Bring across the JDWP implementation.

This compiles and links, but does nothing until we fill out the 100 or so
unimplemented methods in "debugger.cc". Note that I also need to add the
extra command-line handling for the JDWP agent stuff, and add calls from
the runtime to the various "something interesting is going on" hooks.

Change-Id: I477cf3caf9e248c384ce1d739cbfadb60e2008bc
diff --git a/src/logging.cc b/src/logging.cc
index bf6ab91..bb68442 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -63,4 +63,78 @@
   return data_->buffer;
 }
 
+/*
+ * 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
+ *
+ * Does not use printf() or other string-formatting calls.
+ */
+void HexDump(const void* address, size_t byte_count, bool show_actual_address) {
+  static const char gHexDigit[] = "0123456789abcdef";
+  const unsigned char* addr = reinterpret_cast<const unsigned char*>(address);
+  char out[77];           /* exact fit */
+  unsigned int offset;    /* offset to show while printing */
+
+  if (show_actual_address) {
+    offset = (int) addr;
+  } else {
+    offset = 0;
+  }
+  memset(out, ' ', sizeof(out)-1);
+  out[8] = ':';
+  out[sizeof(out)-2] = '\n';
+  out[sizeof(out)-1] = '\0';
+
+  int gap = (int) offset & 0x0f;
+  while (byte_count) {
+    unsigned int lineOffset = offset & ~0x0f;
+    int i, count;
+
+    char* hex = out;
+    char* asc = out + 59;
+
+    for (i = 0; i < 8; i++) {
+      *hex++ = gHexDigit[lineOffset >> 28];
+      lineOffset <<= 4;
+    }
+    hex++;
+    hex++;
+
+    count = ((int)byte_count > 16-gap) ? 16-gap : (int)byte_count; /* cap length */
+    CHECK_NE(count, 0);
+    CHECK_LE(count + gap, 16);
+
+    if (gap) {
+      /* only on first line */
+      hex += gap * 3;
+      asc += gap;
+    }
+
+    for (i = gap ; i < count+gap; i++) {
+      *hex++ = gHexDigit[*addr >> 4];
+      *hex++ = gHexDigit[*addr & 0x0f];
+      hex++;
+      if (*addr >= 0x20 && *addr < 0x7f /*isprint(*addr)*/)
+      *asc++ = *addr;
+      else
+      *asc++ = '.';
+      addr++;
+    }
+    for ( ; i < 16; i++) {
+      /* erase extra stuff; only happens on last line */
+      *hex++ = ' ';
+      *hex++ = ' ';
+      hex++;
+      *asc++ = ' ';
+    }
+
+    LOG(INFO) << out;
+
+    gap = 0;
+    byte_count -= count;
+    offset += count;
+  }
+}
+
 }  // namespace art