1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * JDWP spy. 5 */ 6 #define _JDWP_MISC_INLINE 7 #include "Common.h" 8 #include <stdlib.h> 9 #include <stdio.h> 10 #include <string.h> 11 #include <assert.h> 12 #include <ctype.h> 13 14 static const char gHexDigit[] = "0123456789abcdef"; 15 16 /* 17 * Print a hex dump. Just hands control off to the fancy version. 18 */ 19 void printHexDump(const void* vaddr, size_t length) 20 { 21 printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, ""); 22 } 23 void printHexDump2(const void* vaddr, size_t length, const char* prefix) 24 { 25 printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, prefix); 26 } 27 28 /* 29 * Print a hex dump in this format: 30 * 31 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef\n 32 */ 33 void printHexDumpEx(FILE* fp, const void* vaddr, size_t length, 34 HexDumpMode mode, const char* prefix) 35 { 36 const unsigned char* addr = reinterpret_cast<const unsigned char*>(vaddr); 37 char out[77]; /* exact fit */ 38 unsigned int offset; /* offset to show while printing */ 39 char* hex; 40 char* asc; 41 int gap; 42 43 if (mode == kHexDumpLocal) 44 offset = 0; 45 else 46 offset = (int) addr; 47 48 memset(out, ' ', sizeof(out)-1); 49 out[8] = ':'; 50 out[sizeof(out)-2] = '\n'; 51 out[sizeof(out)-1] = '\0'; 52 53 gap = (int) offset & 0x0f; 54 while (length) { 55 unsigned int lineOffset = offset & ~0x0f; 56 char* hex = out; 57 char* asc = out + 59; 58 59 for (int i = 0; i < 8; i++) { 60 *hex++ = gHexDigit[lineOffset >> 28]; 61 lineOffset <<= 4; 62 } 63 hex++; 64 hex++; 65 66 int count = ((int)length > 16-gap) ? 16-gap : (int) length; /* cap length */ 67 assert(count != 0); 68 assert(count+gap <= 16); 69 70 if (gap) { 71 /* only on first line */ 72 hex += gap * 3; 73 asc += gap; 74 } 75 76 int i; 77 for (i = gap ; i < count+gap; i++) { 78 *hex++ = gHexDigit[*addr >> 4]; 79 *hex++ = gHexDigit[*addr & 0x0f]; 80 hex++; 81 if (isprint(*addr)) 82 *asc++ = *addr; 83 else 84 *asc++ = '.'; 85 addr++; 86 } 87 for ( ; i < 16; i++) { 88 /* erase extra stuff; only happens on last line */ 89 *hex++ = ' '; 90 *hex++ = ' '; 91 hex++; 92 *asc++ = ' '; 93 } 94 95 fprintf(fp, "%s%s", prefix, out); 96 97 gap = 0; 98 length -= count; 99 offset += count; 100 } 101 } 102 103 104 /* 105 * Explain it. 106 */ 107 static void usage(const char* progName) 108 { 109 fprintf(stderr, "Usage: %s VM-port [debugger-listen-port]\n\n", progName); 110 fprintf(stderr, 111 "When a debugger connects to the debugger-listen-port, jdwpspy will connect\n"); 112 fprintf(stderr, "to the VM on the VM-port.\n"); 113 } 114 115 /* 116 * Parse args. 117 */ 118 int main(int argc, char* argv[]) 119 { 120 if (argc < 2 || argc > 3) { 121 usage("jdwpspy"); 122 return 2; 123 } 124 125 setvbuf(stdout, NULL, _IONBF, 0); 126 127 /* may want this to be host:port */ 128 int connectPort = atoi(argv[1]); 129 130 int listenPort; 131 if (argc > 2) 132 listenPort = atoi(argv[2]); 133 else 134 listenPort = connectPort + 1; 135 136 int cc = run("localhost", connectPort, listenPort); 137 138 return (cc != 0); 139 } 140