Home | History | Annotate | Download | only in jdwpspy
      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