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