CliDumpMemoryCommand.cpp revision 44646df4
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, 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#include <ExpressionParser.h>
19
20#include "CliContext.h"
21#include "Team.h"
22#include "TeamMemoryBlock.h"
23#include "UiUtils.h"
24#include "UserInterface.h"
25
26
27CliDumpMemoryCommand::CliDumpMemoryCommand()
28	:
29	CliCommand("dump contents of debugged team's memory",
30		"%s [\"]address|expression[\"] [num]\n"
31		"Reads and displays the contents of memory at the target address.")
32{
33}
34
35
36void
37CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
38	CliContext& context)
39{
40	if (argc < 2) {
41		PrintUsage(argv[0]);
42		return;
43	}
44
45	target_addr_t address;
46	ExpressionParser parser;
47	parser.SetSupportHexInput(true);
48
49	try {
50		address = parser.EvaluateToInt64(argv[1]);
51	} catch(...) {
52		printf("Error parsing address/expression.\n");
53		return;
54	}
55
56	int32 itemSize = 0;
57	int32 displayWidth = 0;
58
59	// build the format string
60	if (strcmp(argv[0], "db") == 0) {
61		itemSize = 1;
62		displayWidth = 16;
63	} else if (strcmp(argv[0], "ds") == 0) {
64		itemSize = 2;
65		displayWidth = 8;
66	} else if (strcmp(argv[0], "dw") == 0) {
67		itemSize = 4;
68		displayWidth = 4;
69	} else if (strcmp(argv[0], "dl") == 0) {
70		itemSize = 8;
71		displayWidth = 2;
72	} else if (strcmp(argv[0], "string") == 0) {
73		itemSize = 1;
74		displayWidth = -1;
75	} else {
76		printf("dump called in an invalid way!\n");
77		return;
78	}
79
80	int32 num = 0;
81	if (argc == 3) {
82		char *remainder;
83		num = strtol(argv[2], &remainder, 0);
84		if (*remainder != '\0') {
85			printf("Error: invalid parameter \"%s\"\n", argv[2]);
86		}
87	}
88
89	if (num <= 0)
90		num = displayWidth;
91
92	TeamMemoryBlock* block = context.CurrentBlock();
93	if (block == NULL || !block->Contains(address)) {
94		context.GetUserInterfaceListener()->InspectRequested(address,
95			&context);
96		context.WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
97		if (context.IsTerminating())
98			return;
99		block = context.CurrentBlock();
100	}
101
102	if (!strcmp(argv[0], "string")) {
103		printf("%p \"", (char*)address);
104
105		target_addr_t offset = address;
106		char c;
107		while (block->Contains(offset)) {
108			c = *(block->Data() + offset - block->BaseAddress());
109
110			if (c == '\0')
111				break;
112			if (c == '\n')
113				printf("\\n");
114			else if (c == '\t')
115				printf("\\t");
116			else {
117				if (!isprint(c))
118					c = '.';
119
120				printf("%c", c);
121			}
122			++offset;
123		}
124
125		printf("\"\n");
126	} else {
127		BString output;
128		UiUtils::DumpMemory(output, 0, block, address, itemSize, displayWidth,
129			num);
130		printf("%s\n", output.String());
131	}
132}
133