am fe0d5d42: am 5434bf66: Merge "LP64: Enable debuggerd/libbacktrace/libunwind."

* commit 'fe0d5d42e4ca8b77d6a0657be1b8b6343c21d689':
  LP64: Enable debuggerd/libbacktrace/libunwind.
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 422a86a..8c1c3d8 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -1,6 +1,6 @@
 # Copyright 2005 The Android Open Source Project
 
-ifneq ($(filter arm mips x86,$(TARGET_ARCH)),)
+ifneq ($(filter arm mips x86 x86_64,$(TARGET_ARCH)),)
 
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
@@ -19,6 +19,7 @@
 	-Wall \
 	-Wno-array-bounds \
 	-Werror \
+	-Wno-unused-parameter \
 
 LOCAL_MODULE := debuggerd
 
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
old mode 100644
new mode 100755
index e5d50e7..cf780d1
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -179,9 +179,9 @@
   if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)){
     _LOG(log, SCOPE_AT_FAULT, "cannot get siginfo: %s\n", strerror(errno));
   } else if (signal_has_address(sig)) {
-    _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %0*" PRIxPTR "\n",
+    _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %" PRIPTR "\n",
          sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code),
-         sizeof(uintptr_t)*2, reinterpret_cast<uintptr_t>(si.si_addr));
+         reinterpret_cast<uintptr_t>(si.si_addr));
   } else {
     _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr --------\n",
          sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code));
@@ -226,7 +226,7 @@
 static void dump_stack_segment(
     Backtrace* backtrace, log_t* log, int scope_flags, uintptr_t* sp, size_t words, int label) {
   for (size_t i = 0; i < words; i++) {
-    uint32_t stack_content;
+    word_t stack_content;
     if (!backtrace->ReadWord(*sp, &stack_content)) {
       break;
     }
@@ -243,32 +243,32 @@
     if (!func_name.empty()) {
       if (!i && label >= 0) {
         if (offset) {
-          _LOG(log, scope_flags, "    #%02d  %08x  %08x  %s (%s+%u)\n",
+          _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIxPTR "u)\n",
                label, *sp, stack_content, map_name, func_name.c_str(), offset);
         } else {
-          _LOG(log, scope_flags, "    #%02d  %08x  %08x  %s (%s)\n",
+          _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
                label, *sp, stack_content, map_name, func_name.c_str());
         }
       } else {
         if (offset) {
-          _LOG(log, scope_flags, "         %08x  %08x  %s (%s+%u)\n",
+          _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIxPTR "u)\n",
                *sp, stack_content, map_name, func_name.c_str(), offset);
         } else {
-          _LOG(log, scope_flags, "         %08x  %08x  %s (%s)\n",
+          _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
                *sp, stack_content, map_name, func_name.c_str());
         }
       }
     } else {
       if (!i && label >= 0) {
-        _LOG(log, scope_flags, "    #%02d  %08x  %08x  %s\n",
+        _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s\n",
              label, *sp, stack_content, map_name);
       } else {
-        _LOG(log, scope_flags, "         %08x  %08x  %s\n",
+        _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s\n",
              *sp, stack_content, map_name);
       }
     }
 
-    *sp += sizeof(uint32_t);
+    *sp += sizeof(word_t);
   }
 }
 
@@ -291,7 +291,7 @@
   scope_flags |= SCOPE_SENSITIVE;
 
   // Dump a few words before the first frame.
-  uintptr_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(uint32_t);
+  word_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(word_t);
   dump_stack_segment(backtrace, log, scope_flags, &sp, STACK_WORDS, -1);
 
   // Dump a few words from all successive frames.
@@ -311,7 +311,7 @@
         _LOG(log, scope_flags, "         ........  ........\n");
       }
     } else {
-      size_t words = frame->stack_size / sizeof(uint32_t);
+      size_t words = frame->stack_size / sizeof(word_t);
       if (words == 0) {
         words = 1;
       } else if (words > STACK_WORDS) {
@@ -334,7 +334,7 @@
 
 static void dump_map(log_t* log, const backtrace_map_t* map, const char* what, int scope_flags) {
   if (map != NULL) {
-    _LOG(log, scope_flags, "    %08x-%08x %c%c%c %s\n", map->start, map->end,
+    _LOG(log, scope_flags, "    %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end,
          (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-',
          (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str());
   } else {
@@ -567,24 +567,15 @@
   memset(msg, 0, sizeof(msg));
   char* p = &msg[0];
   while (p < &msg[sizeof(msg)]) {
-    uint32_t data;
+    word_t data;
+    size_t len = sizeof(word_t);
     if (!backtrace->ReadWord(address, &data)) {
       break;
     }
-    address += sizeof(uint32_t);
+    address += sizeof(word_t);
 
-    if ((*p++ = (data >>  0) & 0xff) == 0) {
-      break;
-    }
-    if ((*p++ = (data >>  8) & 0xff) == 0) {
-      break;
-    }
-    if ((*p++ = (data >> 16) & 0xff) == 0) {
-      break;
-    }
-    if ((*p++ = (data >> 24) & 0xff) == 0) {
-      break;
-    }
+    while (len > 0 && (*p++ = (data >> (sizeof(word_t) - len) * 8) & 0xff) != 0)
+       len--;
   }
   msg[sizeof(msg) - 1] = '\0';
 
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index 100324a..9b20914 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -14,19 +14,17 @@
  * limitations under the License.
  */
 
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
+#include "utility.h"
+
 #include <errno.h>
-#include <unistd.h>
 #include <signal.h>
-#include <log/logd.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/ptrace.h>
 #include <sys/wait.h>
-#include <arpa/inet.h>
-#include <assert.h>
 
-#include "utility.h"
+#include <backtrace/Backtrace.h>
+#include <log/logd.h>
 
 const int sleep_time_usec = 50000;         // 0.05 seconds
 const int max_total_sleep_usec = 10000000; // 10 seconds
@@ -34,7 +32,7 @@
 static int write_to_am(int fd, const char* buf, int len) {
   int to_write = len;
   while (to_write > 0) {
-    int written = TEMP_FAILURE_RETRY( write(fd, buf + len - to_write, to_write) );
+    int written = TEMP_FAILURE_RETRY(write(fd, buf + len - to_write, to_write));
     if (written < 0) {
       // hard failure
       LOG("AM write failure (%d / %s)\n", errno, strerror(errno));
@@ -46,34 +44,28 @@
 }
 
 void _LOG(log_t* log, int scopeFlags, const char* fmt, ...) {
-  char buf[512];
-  bool want_tfd_write;
-  bool want_log_write;
-  bool want_amfd_write;
-  int len = 0;
+  bool want_tfd_write = log && log->tfd >= 0;
+  bool want_log_write = IS_AT_FAULT(scopeFlags) && (!log || !log->quiet);
+  bool want_amfd_write = IS_AT_FAULT(scopeFlags) && !IS_SENSITIVE(scopeFlags) && log && log->amfd >= 0;
 
+  char buf[512];
   va_list ap;
   va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
 
-  // where is the information going to go?
-  want_tfd_write = log && log->tfd >= 0;
-  want_log_write = IS_AT_FAULT(scopeFlags) && (!log || !log->quiet);
-  want_amfd_write = IS_AT_FAULT(scopeFlags) && !IS_SENSITIVE(scopeFlags) && log && log->amfd >= 0;
-
-  // if we're going to need the literal string, generate it once here
-  if (want_tfd_write || want_amfd_write) {
-    vsnprintf(buf, sizeof(buf), fmt, ap);
-    len = strlen(buf);
+  size_t len = strlen(buf);
+  if (len <= 0) {
+    return;
   }
 
   if (want_tfd_write) {
-    write(log->tfd, buf, len);
+    TEMP_FAILURE_RETRY(write(log->tfd, buf, len));
   }
 
   if (want_log_write) {
-    // whatever goes to logcat also goes to the Activity Manager
-    __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap);
-    if (want_amfd_write && len > 0) {
+    __android_log_write(ANDROID_LOG_INFO, "DEBUG", buf);
+    if (want_amfd_write) {
       int written = write_to_am(log->amfd, buf, len);
       if (written <= 0) {
         // timeout or other failure on write; stop informing the activity manager
@@ -81,7 +73,6 @@
       }
     }
   }
-  va_end(ap);
 }
 
 int wait_for_signal(pid_t tid, int* total_sleep_time_usec) {
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 232b7bc..0f88605 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -18,9 +18,8 @@
 #ifndef _DEBUGGERD_UTILITY_H
 #define _DEBUGGERD_UTILITY_H
 
-#include <inttypes.h>
 #include <stdbool.h>
-#include <stddef.h>
+#include <sys/types.h>
 
 typedef struct {
     /* tombstone file descriptor */
@@ -61,14 +60,6 @@
 #define XLOG2(fmt...) do {} while(0)
 #endif
 
-#if __LP64__
-#define PRIPTR "016" PRIxPTR
-typedef uint64_t word_t;
-#else
-#define PRIPTR "08" PRIxPTR
-typedef uint32_t word_t;
-#endif
-
 int wait_for_signal(pid_t tid, int* total_sleep_time_usec);
 void wait_for_stop(pid_t tid, int* total_sleep_time_usec);
 
diff --git a/debuggerd/x86_64/crashglue.S b/debuggerd/x86_64/crashglue.S
new file mode 100644
index 0000000..4d2a5c0
--- /dev/null
+++ b/debuggerd/x86_64/crashglue.S
@@ -0,0 +1,15 @@
+.globl crash1
+.globl crashnostack
+
+crash1:
+	movl $0xa5a50000, %eax
+	movl $0xa5a50001, %ebx
+	movl $0xa5a50002, %ecx
+
+	movl $0, %edx
+	jmp *%rdx
+
+
+crashnostack:
+	movl $0, %ebp
+	jmp *%rbp
diff --git a/debuggerd/x86_64/machine.cpp b/debuggerd/x86_64/machine.cpp
new file mode 100755
index 0000000..406851a
--- /dev/null
+++ b/debuggerd/x86_64/machine.cpp
@@ -0,0 +1,51 @@
+/*
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+
+#include "../utility.h"
+#include "../machine.h"
+
+void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+}
+
+void dump_registers(log_t* log, pid_t tid, int scope_flags) {
+    struct user_regs_struct r;
+    if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
+        _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+        return;
+    }
+    _LOG(log, scope_flags, "    rax %016lx  rbx %016lx  rcx %016lx  rdx %016lx\n",
+         r.rax, r.rbx, r.rcx, r.rdx);
+    _LOG(log, scope_flags, "    rsi %016lx  rdi %016lx\n",
+         r.rsi, r.rdi);
+    _LOG(log, scope_flags, "    r8  %016lx  r9  %016lx  r10 %016lx  r11 %016lx\n",
+         r.r8, r.r9, r.r10, r.r11);
+    _LOG(log, scope_flags, "    r12 %016lx  r13 %016lx  r14 %016lx  r15 %016lx\n",
+         r.r12, r.r13, r.r14, r.r15);
+    _LOG(log, scope_flags, "    cs  %016lx  ss  %016lx\n",
+         r.cs, r.ss);
+    _LOG(log, scope_flags, "    rip %016lx  rbp %016lx  rsp %016lx  eflags %016lx\n",
+         r.rip, r.rbp, r.rsp, r.eflags);
+}
diff --git a/include/backtrace/Backtrace.h b/include/backtrace/Backtrace.h
index bd4134c..3c3a482 100644
--- a/include/backtrace/Backtrace.h
+++ b/include/backtrace/Backtrace.h
@@ -17,6 +17,7 @@
 #ifndef _BACKTRACE_BACKTRACE_H
 #define _BACKTRACE_BACKTRACE_H
 
+#include <inttypes.h>
 #include <stdint.h>
 
 #include <string>
@@ -25,6 +26,14 @@
 #include <backtrace/backtrace_constants.h>
 #include <backtrace/BacktraceMap.h>
 
+#if __LP64__
+#define PRIPTR "016" PRIxPTR
+typedef uint64_t word_t;
+#else
+#define PRIPTR "08" PRIxPTR
+typedef uint32_t word_t;
+#endif
+
 struct backtrace_frame_data_t {
   size_t num;             // The current fame number.
   uintptr_t pc;           // The absolute pc.
@@ -65,7 +74,7 @@
   virtual const backtrace_map_t* FindMap(uintptr_t pc);
 
   // Read the data at a specific address.
-  virtual bool ReadWord(uintptr_t ptr, uint32_t* out_value) = 0;
+  virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0;
 
   // Create a string representing the formatted line of backtrace information
   // for a single frame.
@@ -96,7 +105,7 @@
 protected:
   Backtrace(BacktraceImpl* impl, pid_t pid, BacktraceMap* map);
 
-  virtual bool VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value);
+  virtual bool VerifyReadWordArgs(uintptr_t ptr, word_t* out_value);
 
   bool BuildMap();
 
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
old mode 100644
new mode 100755
index 17a807d..ee90f28
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -23,7 +23,7 @@
 	liblog \
 
 # To enable using libunwind on each arch, add it to this list.
-libunwind_architectures := arm arm64 x86
+libunwind_architectures := arm arm64 x86 x86_64
 
 ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),$(libunwind_architectures)))
 
diff --git a/libbacktrace/BacktraceImpl.cpp b/libbacktrace/BacktraceImpl.cpp
index 8027d86..855810e 100644
--- a/libbacktrace/BacktraceImpl.cpp
+++ b/libbacktrace/BacktraceImpl.cpp
@@ -21,8 +21,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <inttypes.h>
-
 #include <string>
 
 #include <backtrace/Backtrace.h>
@@ -81,10 +79,10 @@
   return func_name;
 }
 
-bool Backtrace::VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value) {
-  if (ptr & 3) {
+bool Backtrace::VerifyReadWordArgs(uintptr_t ptr, word_t* out_value) {
+  if (ptr & (sizeof(word_t)-1)) {
     BACK_LOGW("invalid pointer %p", (void*)ptr);
-    *out_value = (uint32_t)-1;
+    *out_value = (word_t)-1;
     return false;
   }
   return true;
@@ -142,18 +140,18 @@
 BacktraceCurrent::~BacktraceCurrent() {
 }
 
-bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) {
+bool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) {
   if (!VerifyReadWordArgs(ptr, out_value)) {
     return false;
   }
 
   const backtrace_map_t* map = FindMap(ptr);
   if (map && map->flags & PROT_READ) {
-    *out_value = *reinterpret_cast<uint32_t*>(ptr);
+    *out_value = *reinterpret_cast<word_t*>(ptr);
     return true;
   } else {
     BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr));
-    *out_value = static_cast<uint32_t>(-1);
+    *out_value = static_cast<word_t>(-1);
     return false;
   }
 }
@@ -170,7 +168,7 @@
 BacktracePtrace::~BacktracePtrace() {
 }
 
-bool BacktracePtrace::ReadWord(uintptr_t ptr, uint32_t* out_value) {
+bool BacktracePtrace::ReadWord(uintptr_t ptr, word_t* out_value) {
   if (!VerifyReadWordArgs(ptr, out_value)) {
     return false;
   }
@@ -183,7 +181,7 @@
   // To disambiguate -1 from a valid result, we clear errno beforehand.
   errno = 0;
   *out_value = ptrace(PTRACE_PEEKTEXT, Tid(), reinterpret_cast<void*>(ptr), NULL);
-  if (*out_value == static_cast<uint32_t>(-1) && errno) {
+  if (*out_value == static_cast<word_t>(-1) && errno) {
     BACK_LOGW("invalid pointer %p reading from tid %d, ptrace() strerror(errno)=%s",
               reinterpret_cast<void*>(ptr), Tid(), strerror(errno));
     return false;
diff --git a/libbacktrace/BacktraceImpl.h b/libbacktrace/BacktraceImpl.h
old mode 100644
new mode 100755
index af014d5..48dd11c
--- a/libbacktrace/BacktraceImpl.h
+++ b/libbacktrace/BacktraceImpl.h
@@ -61,7 +61,7 @@
   BacktraceCurrent(BacktraceImpl* impl, BacktraceMap* map);
   virtual ~BacktraceCurrent();
 
-  bool ReadWord(uintptr_t ptr, uint32_t* out_value);
+  bool ReadWord(uintptr_t ptr, word_t* out_value);
 };
 
 class BacktracePtrace : public Backtrace {
@@ -69,7 +69,7 @@
   BacktracePtrace(BacktraceImpl* impl, pid_t pid, pid_t tid, BacktraceMap* map);
   virtual ~BacktracePtrace();
 
-  bool ReadWord(uintptr_t ptr, uint32_t* out_value);
+  bool ReadWord(uintptr_t ptr, word_t* out_value);
 };
 
 Backtrace* CreateCurrentObj(BacktraceMap* map);
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
old mode 100644
new mode 100755
index 461ed02..81e69bb
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "libbacktrace"
 
+#include <sys/ucontext.h>
 #include <sys/types.h>
 
 #include <backtrace/Backtrace.h>
@@ -27,8 +28,6 @@
 #include "UnwindCurrent.h"
 #include "UnwindMap.h"
 
-#include <ucontext.h>
-
 //-------------------------------------------------------------------------
 // UnwindCurrent functions.
 //-------------------------------------------------------------------------