/* * Copyright 2006 The Android Open Source Project * * JDWP spy. */ #define _JDWP_MISC_INLINE #include "Common.h" #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <assert.h> #include <ctype.h> static const char gHexDigit[] = "0123456789abcdef"; /* * Print a hex dump. Just hands control off to the fancy version. */ void printHexDump(const void* vaddr, size_t length) { printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, ""); } void printHexDump2(const void* vaddr, size_t length, const char* prefix) { printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, prefix); } /* * Print a hex dump in this format: * 01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0123456789abcdef\n */ void printHexDumpEx(FILE* fp, const void* vaddr, size_t length, HexDumpMode mode, const char* prefix) { const unsigned char* addr = reinterpret_cast<const unsigned char*>(vaddr); char out[77]; /* exact fit */ uintptr_t offset; /* offset to show while printing */ char* hex; char* asc; int gap; if (mode == kHexDumpLocal) offset = 0; else offset = (uintptr_t) addr; memset(out, ' ', sizeof(out)-1); out[8] = ':'; out[sizeof(out)-2] = '\n'; out[sizeof(out)-1] = '\0'; gap = (int) offset & 0x0f; while (length) { unsigned int lineOffset = offset & ~0x0f; char* hex = out; char* asc = out + 59; for (int i = 0; i < 8; i++) { *hex++ = gHexDigit[lineOffset >> 28]; lineOffset <<= 4; } hex++; hex++; int count = ((int)length > 16-gap) ? 16-gap : (int) length; /* cap length */ assert(count != 0); assert(count+gap <= 16); if (gap) { /* only on first line */ hex += gap * 3; asc += gap; } int i; for (i = gap ; i < count+gap; i++) { *hex++ = gHexDigit[*addr >> 4]; *hex++ = gHexDigit[*addr & 0x0f]; hex++; if (isprint(*addr)) *asc++ = *addr; else *asc++ = '.'; addr++; } for ( ; i < 16; i++) { /* erase extra stuff; only happens on last line */ *hex++ = ' '; *hex++ = ' '; hex++; *asc++ = ' '; } fprintf(fp, "%s%s", prefix, out); gap = 0; length -= count; offset += count; } } /* * Explain it. */ static void usage(const char* progName) { fprintf(stderr, "Usage: %s VM-port [debugger-listen-port]\n\n", progName); fprintf(stderr, "When a debugger connects to the debugger-listen-port, jdwpspy will connect\n"); fprintf(stderr, "to the VM on the VM-port.\n"); } /* * Parse args. */ int main(int argc, char* argv[]) { if (argc < 2 || argc > 3) { usage("jdwpspy"); return 2; } setvbuf(stdout, NULL, _IONBF, 0); /* may want this to be host:port */ int connectPort = atoi(argv[1]); int listenPort; if (argc > 2) listenPort = atoi(argv[2]); else listenPort = connectPort + 1; int cc = run("localhost", connectPort, listenPort); return (cc != 0); }