1/*
2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2010, Axel D��rfler, axeld@pinc-software.de.
4 * Copyright 2012-2016, Rene Gollent, rene@gollent.com.
5 * Distributed under the terms of the MIT License.
6 *
7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
10
11
12#include "CliDumpMemoryCommand.h"
13
14#include <ctype.h>
15#include <stdio.h>
16
17#include <AutoLocker.h>
18
19#include "CliContext.h"
20#include "CppLanguage.h"
21#include "Team.h"
22#include "TeamMemoryBlock.h"
23#include "UiUtils.h"
24#include "UserInterface.h"
25#include "Value.h"
26#include "Variable.h"
27
28
29CliDumpMemoryCommand::CliDumpMemoryCommand(int itemSize,
30	const char* itemSizeNoun, int displayWidth)
31	:
32	CliCommand(NULL, NULL),
33	itemSize(itemSize),
34	displayWidth(displayWidth)
35{
36	// BString manages the lifetime of the const char* put in fSummary and fUsage
37	fSummaryString.SetToFormat("dump contents of debugged team's memory in %s-sized increments",
38		itemSizeNoun);
39	fUsageString.SetToFormat("%%s [\"]address|expression[\"] [num]\n"
40		"Reads and displays the contents of memory at the target address in %d-byte increments",
41		itemSize);
42
43	fSummary = fSummaryString.String();
44	fUsage = fUsageString.String();
45
46	// TODO: this should be retrieved via some indirect helper rather
47	// than instantiating the specific language directly.
48	fLanguage = new(std::nothrow) CppLanguage();
49}
50
51
52CliDumpMemoryCommand::~CliDumpMemoryCommand()
53{
54	if (fLanguage != NULL)
55		fLanguage->ReleaseReference();
56}
57
58
59void
60CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
61	CliContext& context)
62{
63	if (argc < 2) {
64		PrintUsage(argv[0]);
65		return;
66	}
67
68	if (fLanguage == NULL) {
69		printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY));
70		return;
71	}
72
73	target_addr_t address;
74	if (context.EvaluateExpression(argv[1], fLanguage, address) != B_OK)
75		return;
76
77	TeamMemoryBlock* block = NULL;
78	if (context.GetMemoryBlock(address, block) != B_OK)
79		return;
80
81	int32 num = 0;
82	if (argc == 3) {
83		char *remainder;
84		num = strtol(argv[2], &remainder, 0);
85		if (*remainder != '\0') {
86			printf("Error: invalid parameter \"%s\"\n", argv[2]);
87		}
88	}
89
90	if (num <= 0)
91		num = displayWidth;
92
93	BString output;
94	UiUtils::DumpMemory(output, 0, block, address, itemSize, displayWidth,
95		num);
96	printf("%s\n", output.String());
97}
98