• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
printHexDump(const void * vaddr,size_t length)19 void printHexDump(const void* vaddr, size_t length)
20 {
21     printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, "");
22 }
printHexDump2(const void * vaddr,size_t length,const char * prefix)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  */
printHexDumpEx(FILE * fp,const void * vaddr,size_t length,HexDumpMode mode,const char * prefix)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  */
usage(const char * progName)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  */
main(int argc,char * argv[])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