summaryrefslogtreecommitdiff
path: root/jdwpspy/Main.cpp
blob: 0f68d52c38ddc7f6e4de4491b350c8b0603a7bfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright 2006 The Android Open Source Project
 *
 * JDWP spy.
 */
#define _JDWP_MISC_INLINE
#include "Common.h"
#include <stdlib.h>
#include <stdio.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 */
    unsigned int offset;    /* offset to show while printing */
    char* hex;
    char* asc;
    int gap;

    if (mode == kHexDumpLocal)
        offset = 0;
    else
        offset = (int) 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);
}