debuggerd: IA version

Change-Id: I0c0d9c2d7e476b8d117aaf505a9480a47c0b5c05
Signed-off-by: Lei Li <lei.l.li@intel.com>
Signed-off-by: Bruce Beare <bruce.j.beare@intel.com>
diff --git a/debuggerd/x86/crashglue.S b/debuggerd/x86/crashglue.S
new file mode 100644
index 0000000..59df432
--- /dev/null
+++ b/debuggerd/x86/crashglue.S
@@ -0,0 +1,15 @@
+.globl crash1
+.globl crashnostack
+
+crash1:
+	movl $0xa5a50000, %eax
+	movl $0xa5a50001, %ebx
+	movl $0xa5a50002, %ecx
+
+	movl $0, %edx
+	jmp *%edx
+
+
+crashnostack:
+	movl $0, %ebp
+	jmp *%ebp
diff --git a/debuggerd/x86/machine.c b/debuggerd/x86/machine.c
new file mode 100644
index 0000000..9d418cf
--- /dev/null
+++ b/debuggerd/x86/machine.c
@@ -0,0 +1,61 @@
+/* system/debuggerd/debuggerd.c
+**
+** Copyright 2006, 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 <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <sys/exec_elf.h>
+#include <sys/stat.h>
+
+#include <cutils/sockets.h>
+#include <cutils/properties.h>
+
+#include <linux/input.h>
+
+#include "../utility.h"
+#include "x86_utility.h"
+
+void dump_registers(int tfd, int pid, bool at_fault)
+{
+    struct pt_regs_x86 r;
+    bool only_in_tombstone = !at_fault;
+
+    if(ptrace(PTRACE_GETREGS, pid, 0, &r)) {
+        _LOG(tfd, only_in_tombstone,
+             "cannot get registers: %s\n", strerror(errno));
+        return;
+    }
+//if there is no stack, no print just like arm
+    if(!r.ebp)
+        return;
+    _LOG(tfd, only_in_tombstone, " eax %08x  ebx %08x  ecx %08x  edx %08x\n",
+         r.eax, r.ebx, r.ecx, r.edx);
+    _LOG(tfd, only_in_tombstone, " esi %08x  edi %08x\n",
+         r.esi, r.edi);
+    _LOG(tfd, only_in_tombstone, " xcs %08x  xds %08x  xes %08x  xfs %08x xss %08x\n",
+         r.xcs, r.xds, r.xes, r.xfs, r.xss);
+    _LOG(tfd, only_in_tombstone,
+         " eip %08x  ebp %08x  esp %08x  flags %08x\n",
+         r.eip, r.ebp, r.esp, r.eflags);
+}
diff --git a/debuggerd/x86/unwind.c b/debuggerd/x86/unwind.c
new file mode 100644
index 0000000..8f84e01
--- /dev/null
+++ b/debuggerd/x86/unwind.c
@@ -0,0 +1,85 @@
+#include <cutils/logd.h>
+#include <sys/ptrace.h>
+#include "../utility.h"
+#include "x86_utility.h"
+
+
+int unwind_backtrace_with_ptrace_x86(int tfd, pid_t pid, mapinfo *map,
+                                 bool at_fault)
+{
+    struct pt_regs_x86 r;
+    unsigned int stack_level = 0;
+    unsigned int stack_depth = 0;
+    unsigned int rel_pc;
+    unsigned int stack_ptr;
+    unsigned int stack_content;
+
+    if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0;
+    unsigned int eip = (unsigned int)r.eip;
+    unsigned int ebp = (unsigned int)r.ebp;
+    unsigned int cur_sp = (unsigned int)r.esp;
+    const mapinfo *mi;
+    const struct symbol* sym = 0;
+
+
+//ebp==0, it indicates that the stack is poped to the bottom or there is no stack at all.
+    while (ebp) {
+        _LOG(tfd, !at_fault, "#0%d ",stack_level);
+        mi = pc_to_mapinfo(map, eip, &rel_pc);
+
+        /* See if we can determine what symbol this stack frame resides in */
+        if (mi != 0 && mi->symbols != 0) {
+            sym = symbol_table_lookup(mi->symbols, rel_pc);
+        }
+        if (sym) {
+            _LOG(tfd, !at_fault, "    eip: %08x  %s (%s)\n", eip, mi ? mi->name : "", sym->name);
+        } else {
+            _LOG(tfd, !at_fault, "    eip: %08x  %s\n", eip, mi ? mi->name : "");
+        }
+
+        stack_level++;
+        if (stack_level >= STACK_DEPTH || eip == 0)
+            break;
+        eip = ptrace(PTRACE_PEEKTEXT, pid, (void*)(ebp + 4), NULL);
+        ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL);
+    }
+    ebp = (unsigned int)r.ebp;
+    stack_depth = stack_level;
+    stack_level = 0;
+    if (ebp)
+        _LOG(tfd, !at_fault, "stack: \n");
+    while (ebp) {
+        _LOG(tfd, !at_fault, "#0%d \n",stack_level);
+        stack_ptr = cur_sp;
+        while((int)(ebp - stack_ptr) >= 0) {
+            stack_content = ptrace(PTRACE_PEEKTEXT, pid, (void*)stack_ptr, NULL);
+            mi = pc_to_mapinfo(map, stack_content, &rel_pc);
+
+            /* See if we can determine what symbol this stack frame resides in */
+            if (mi != 0 && mi->symbols != 0) {
+                sym = symbol_table_lookup(mi->symbols, rel_pc);
+            }
+            if (sym) {
+                _LOG(tfd, !at_fault, "    %08x  %08x  %s (%s)\n",
+                    stack_ptr, stack_content, mi ? mi->name : "", sym->name);
+            } else {
+                _LOG(tfd, !at_fault, "    %08x  %08x  %s\n", stack_ptr, stack_content, mi ? mi->name : "");
+            }
+
+            stack_ptr = stack_ptr + 4;
+            //the stack frame may be very deep.
+            if((int)(stack_ptr - cur_sp) >= STACK_FRAME_DEPTH) {
+                _LOG(tfd, !at_fault, "    ......  ......  \n");
+                break;
+            }
+        }
+        cur_sp = ebp + 4;
+        stack_level++;
+        if (stack_level >= STACK_DEPTH || stack_level >= stack_depth)
+            break;
+        ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL);
+    }
+
+    return stack_depth;
+}
+
diff --git a/debuggerd/x86/x86_utility.h b/debuggerd/x86/x86_utility.h
new file mode 100644
index 0000000..ac6a885
--- /dev/null
+++ b/debuggerd/x86/x86_utility.h
@@ -0,0 +1,40 @@
+/*
+**
+** Copyright 2006, 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.
+*/
+
+#define STACK_DEPTH 8
+#define STACK_FRAME_DEPTH 64
+
+typedef struct pt_regs_x86 {
+    long ebx;
+    long ecx;
+    long edx;
+    long esi;
+    long edi;
+    long ebp;
+    long eax;
+    int  xds;
+    int  xes;
+    int  xfs;
+    int  xgs;
+    long orig_eax;
+    long eip;
+    int  xcs;
+    long eflags;
+    long esp;
+    int  xss;
+}pt_regs_x86;
+