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-2014, 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 fLanguage = new(std::nothrow) CppLanguage(); 36 } 37 38 39 CliDumpMemoryCommand::~CliDumpMemoryCommand() 40 { 41 if (fLanguage != NULL) 42 fLanguage->ReleaseReference(); 43 } 44 45 46 void 47 CliDumpMemoryCommand::Execute(int argc, const char* const* argv, 48 CliContext& context) 49 { 50 if (argc < 2) { 51 PrintUsage(argv[0]); 52 return; 53 } 54 55 if (fLanguage == NULL) { 56 printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY)); 57 return; 58 } 59 60 ExpressionInfo* info = context.GetExpressionInfo(); 61 62 target_addr_t address = 0; 63 info->SetTo(argv[1]); 64 65 context.GetUserInterfaceListener()->ExpressionEvaluationRequested( 66 fLanguage, info); 67 context.WaitForEvents(CliContext::EVENT_EXPRESSION_EVALUATED); 68 if (context.IsTerminating()) 69 return; 70 71 BString errorMessage; 72 ExpressionResult* result = context.GetExpressionValue(); 73 if (result != NULL) { 74 if (result->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { 75 Value* value = result->PrimitiveValue(); 76 BVariant variantValue; 77 value->ToVariant(variantValue); 78 if (variantValue.Type() == B_STRING_TYPE) 79 errorMessage.SetTo(variantValue.ToString()); 80 else 81 address = variantValue.ToUInt64(); 82 } 83 } else 84 errorMessage = strerror(context.GetExpressionResult()); 85 86 if (!errorMessage.IsEmpty()) { 87 printf("Unable to evaluate expression: %s\n", 88 errorMessage.String()); 89 return; 90 } 91 92 int32 itemSize = 0; 93 int32 displayWidth = 0; 94 95 // build the format string 96 if (strcmp(argv[0], "db") == 0) { 97 itemSize = 1; 98 displayWidth = 16; 99 } else if (strcmp(argv[0], "ds") == 0) { 100 itemSize = 2; 101 displayWidth = 8; 102 } else if (strcmp(argv[0], "dw") == 0) { 103 itemSize = 4; 104 displayWidth = 4; 105 } else if (strcmp(argv[0], "dl") == 0) { 106 itemSize = 8; 107 displayWidth = 2; 108 } else if (strcmp(argv[0], "string") == 0) { 109 itemSize = 1; 110 displayWidth = -1; 111 } else { 112 printf("dump called in an invalid way!\n"); 113 return; 114 } 115 116 int32 num = 0; 117 if (argc == 3) { 118 char *remainder; 119 num = strtol(argv[2], &remainder, 0); 120 if (*remainder != '\0') { 121 printf("Error: invalid parameter \"%s\"\n", argv[2]); 122 } 123 } 124 125 if (num <= 0) 126 num = displayWidth; 127 128 TeamMemoryBlock* block = context.CurrentBlock(); 129 if (block == NULL || !block->Contains(address)) { 130 context.GetUserInterfaceListener()->InspectRequested(address, 131 &context); 132 context.WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED); 133 if (context.IsTerminating()) 134 return; 135 block = context.CurrentBlock(); 136 } 137 138 if (!strcmp(argv[0], "string")) { 139 printf("%p \"", (char*)address); 140 141 target_addr_t offset = address; 142 char c; 143 while (block->Contains(offset)) { 144 c = *(block->Data() + offset - block->BaseAddress()); 145 146 if (c == '\0') 147 break; 148 if (c == '\n') 149 printf("\\n"); 150 else if (c == '\t') 151 printf("\\t"); 152 else { 153 if (!isprint(c)) 154 c = '.'; 155 156 printf("%c", c); 157 } 158 ++offset; 159 } 160 161 printf("\"\n"); 162 } else { 163 BString output; 164 UiUtils::DumpMemory(output, 0, block, address, itemSize, displayWidth, 165 num); 166 printf("%s\n", output.String()); 167 } 168 } 169