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 29 CliDumpMemoryCommand::CliDumpMemoryCommand() 30 : 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.") 34 { 35 // TODO: this should be retrieved via some indirect helper rather 36 // than instantiating the specific language directly. 37 fLanguage = new(std::nothrow) CppLanguage(); 38 } 39 40 41 CliDumpMemoryCommand::~CliDumpMemoryCommand() 42 { 43 if (fLanguage != NULL) 44 fLanguage->ReleaseReference(); 45 } 46 47 48 void 49 CliDumpMemoryCommand::Execute(int argc, const char* const* argv, 50 CliContext& context) 51 { 52 if (argc < 2) { 53 PrintUsage(argv[0]); 54 return; 55 } 56 57 if (fLanguage == NULL) { 58 printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY)); 59 return; 60 } 61 62 ExpressionInfo* info = context.GetExpressionInfo(); 63 64 target_addr_t address = 0; 65 info->SetTo(argv[1]); 66 67 context.GetUserInterfaceListener()->ExpressionEvaluationRequested( 68 fLanguage, info); 69 context.WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED); 70 if (context.IsTerminating()) 71 return; 72 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(); 84 } 85 } else 86 errorMessage = strerror(context.GetExpressionResult()); 87 88 if (!errorMessage.IsEmpty()) { 89 printf("Unable to evaluate expression: %s\n", 90 errorMessage.String()); 91 return; 92 } 93 94 int32 itemSize = 0; 95 int32 displayWidth = 0; 96 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; 116 } 117 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]); 124 } 125 } 126 127 if (num <= 0) 128 num = displayWidth; 129 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(); 138 } 139 140 if (!strcmp(argv[0], "string")) { 141 printf("%p \"", (char*)address); 142 143 target_addr_t offset = address; 144 char c; 145 while (block->Contains(offset)) { 146 c = *(block->Data() + offset - block->BaseAddress()); 147 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 = '.'; 157 158 printf("%c", c); 159 } 160 ++offset; 161 } 162 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()); 169 } 170 } 171