xref: /haiku/src/apps/debugger/user_interface/cli/commands/CliDumpMemoryCommand.cpp (revision 4b7e219688450694efc9d1890f83f816758c16d3)
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 
27 CliDumpMemoryCommand::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 
36 void
37 CliDumpMemoryCommand::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