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