vfs: check userland buffers before reading them.
[haiku.git] / src / apps / debugger / user_interface / cli / commands / CliDumpMemoryCommand.cpp
blob9a627c62003e5d6dde92c4a3d75e043955e05a17
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.
7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
12 #include "CliDumpMemoryCommand.h"
14 #include <ctype.h>
15 #include <stdio.h>
17 #include <AutoLocker.h>
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"
29 CliDumpMemoryCommand::CliDumpMemoryCommand()
31 CliCommand("dump contents of debugged team's memory",
32 "%s [\"]address|expression[\"] [num]\n"
33 "Reads and displays the contents of memory at the target address.")
35 // TODO: this should be retrieved via some indirect helper rather
36 // than instantiating the specific language directly.
37 fLanguage = new(std::nothrow) CppLanguage();
41 CliDumpMemoryCommand::~CliDumpMemoryCommand()
43 if (fLanguage != NULL)
44 fLanguage->ReleaseReference();
48 void
49 CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
50 CliContext& context)
52 if (argc < 2) {
53 PrintUsage(argv[0]);
54 return;
57 if (fLanguage == NULL) {
58 printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY));
59 return;
62 ExpressionInfo* info = context.GetExpressionInfo();
64 target_addr_t address = 0;
65 info->SetTo(argv[1]);
67 context.GetUserInterfaceListener()->ExpressionEvaluationRequested(
68 fLanguage, info);
69 context.WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED);
70 if (context.IsTerminating())
71 return;
73 BString errorMessage;
74 ExpressionResult* result = context.GetExpressionValue();
75 if (result != NULL) {
76 if (result->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
77 Value* value = result->PrimitiveValue();
78 BVariant variantValue;
79 value->ToVariant(variantValue);
80 if (variantValue.Type() == B_STRING_TYPE)
81 errorMessage.SetTo(variantValue.ToString());
82 else
83 address = variantValue.ToUInt64();
85 } else
86 errorMessage = strerror(context.GetExpressionResult());
88 if (!errorMessage.IsEmpty()) {
89 printf("Unable to evaluate expression: %s\n",
90 errorMessage.String());
91 return;
94 int32 itemSize = 0;
95 int32 displayWidth = 0;
97 // build the format string
98 if (strcmp(argv[0], "db") == 0) {
99 itemSize = 1;
100 displayWidth = 16;
101 } else if (strcmp(argv[0], "ds") == 0) {
102 itemSize = 2;
103 displayWidth = 8;
104 } else if (strcmp(argv[0], "dw") == 0) {
105 itemSize = 4;
106 displayWidth = 4;
107 } else if (strcmp(argv[0], "dl") == 0) {
108 itemSize = 8;
109 displayWidth = 2;
110 } else if (strcmp(argv[0], "string") == 0) {
111 itemSize = 1;
112 displayWidth = -1;
113 } else {
114 printf("dump called in an invalid way!\n");
115 return;
118 int32 num = 0;
119 if (argc == 3) {
120 char *remainder;
121 num = strtol(argv[2], &remainder, 0);
122 if (*remainder != '\0') {
123 printf("Error: invalid parameter \"%s\"\n", argv[2]);
127 if (num <= 0)
128 num = displayWidth;
130 TeamMemoryBlock* block = context.CurrentBlock();
131 if (block == NULL || !block->Contains(address)) {
132 context.GetUserInterfaceListener()->InspectRequested(address,
133 &context);
134 context.WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
135 if (context.IsTerminating())
136 return;
137 block = context.CurrentBlock();
140 if (!strcmp(argv[0], "string")) {
141 printf("%p \"", (char*)address);
143 target_addr_t offset = address;
144 char c;
145 while (block->Contains(offset)) {
146 c = *(block->Data() + offset - block->BaseAddress());
148 if (c == '\0')
149 break;
150 if (c == '\n')
151 printf("\\n");
152 else if (c == '\t')
153 printf("\\t");
154 else {
155 if (!isprint(c))
156 c = '.';
158 printf("%c", c);
160 ++offset;
163 printf("\"\n");
164 } else {
165 BString output;
166 UiUtils::DumpMemory(output, 0, block, address, itemSize, displayWidth,
167 num);
168 printf("%s\n", output.String());