2012-05-07 Sergio Durigan Junior <sergiodj@redhat.com>
[binutils-gdb.git] / gdb / amd64obsd-tdep.c
index 1a0cfac22a3d9ae51a6d6ed9c634e62bf07027ed..f2a8ed9de52bd761941620e0d91d27acfea445dc 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for OpenBSD/amd64.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003-2005, 2007-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -87,15 +87,21 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
-  const gdb_byte sigreturn[] =
+  const gdb_byte osigreturn[] =
   {
     0x48, 0xc7, 0xc0,
     0x67, 0x00, 0x00, 0x00,    /* movq $SYS_sigreturn, %rax */
     0xcd, 0x80                 /* int $0x80 */
   };
+  const gdb_byte sigreturn[] =
+  {
+    0x48, 0xc7, 0xc0,
+    0x67, 0x00, 0x00, 0x00,    /* movq $SYS_sigreturn, %rax */
+    0x0f, 0x05                 /* syscall */
+  };
   size_t buflen = (sizeof sigreturn) + 1;
   gdb_byte *buf;
-  char *name;
+  const char *name;
 
   /* If the function has a valid symbol name, it isn't a
      trampoline.  */
@@ -115,9 +121,12 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame)
 
   /* Check for sigreturn(2).  Depending on how the assembler encoded
      the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
-     7.  */
+     7.  OpenBSD 5.0 and later use the `syscall' instruction.  Older
+     versions use `int $0x80'.  Check for both.  */
   if (memcmp (buf, sigreturn, sizeof sigreturn)
-      && memcpy (buf + 1, sigreturn, sizeof sigreturn))
+      && memcmp (buf + 1, sigreturn, sizeof sigreturn)
+      && memcmp (buf, osigreturn, sizeof osigreturn)
+      && memcmp (buf + 1, osigreturn, sizeof osigreturn))
     return 0;
 
   return 1;
@@ -166,7 +175,7 @@ int amd64obsd_r_reg_offset[] =
   0 * 8,                       /* %rdi */
   12 * 8,                      /* %rbp */
   15 * 8,                      /* %rsp */
-  4 * 8,                       /* %r8 .. */
+  4 * 8,                       /* %r8 ..  */
   5 * 8,
   6 * 8,
   7 * 8,
@@ -195,7 +204,7 @@ static int amd64obsd_sc_reg_offset[] =
   0 * 8,                       /* %rdi */
   12 * 8,                      /* %rbp */
   24 * 8,                      /* %rsp */
-  4 * 8,                       /* %r8 ... */
+  4 * 8,                       /* %r8 ...  */
   5 * 8,
   6 * 8,
   7 * 8,
@@ -224,7 +233,7 @@ static int amd64obsd_uthread_reg_offset[] =
   13 * 8,                      /* %rdi */
   15 * 8,                      /* %rbp */
   -1,                          /* %rsp */
-  12 * 8,                      /* %r8 ... */
+  12 * 8,                      /* %r8 ...  */
   11 * 8,
   10 * 8,
   9 * 8,
@@ -250,6 +259,8 @@ static void
 amd64obsd_supply_uthread (struct regcache *regcache,
                          int regnum, CORE_ADDR addr)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
   CORE_ADDR sp = 0;
   gdb_byte buf[8];
@@ -262,12 +273,12 @@ amd64obsd_supply_uthread (struct regcache *regcache,
       int offset;
 
       /* Fetch stack pointer from thread structure.  */
-      sp = read_memory_unsigned_integer (sp_addr, 8);
+      sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
 
       /* Adjust the stack pointer such that it looks as if we just
          returned from _thread_machdep_switch.  */
       offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
-      store_unsigned_integer (buf, 8, sp + offset);
+      store_unsigned_integer (buf, 8, byte_order, sp + offset);
       regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
     }
 
@@ -279,7 +290,7 @@ amd64obsd_supply_uthread (struct regcache *regcache,
          /* Fetch stack pointer from thread structure (if we didn't
              do so already).  */
          if (sp == 0)
-           sp = read_memory_unsigned_integer (sp_addr, 8);
+           sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
 
          /* Read the saved register from the stack frame.  */
          read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
@@ -292,6 +303,8 @@ static void
 amd64obsd_collect_uthread (const struct regcache *regcache,
                           int regnum, CORE_ADDR addr)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
   CORE_ADDR sp = 0;
   gdb_byte buf[8];
@@ -307,10 +320,10 @@ amd64obsd_collect_uthread (const struct regcache *regcache,
          stored into the thread structure.  */
       offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
       regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
-      sp = extract_unsigned_integer (buf, 8) - offset;
+      sp = extract_unsigned_integer (buf, 8, byte_order) - offset;
 
       /* Store the stack pointer.  */
-      write_memory_unsigned_integer (sp_addr, 8, sp);
+      write_memory_unsigned_integer (sp_addr, 8, byte_order, sp);
 
       /* The stack pointer was (potentially) modified.  Make sure we
          build a proper stack frame.  */
@@ -325,7 +338,7 @@ amd64obsd_collect_uthread (const struct regcache *regcache,
          /* Fetch stack pointer from thread structure (if we didn't
              calculate it already).  */
          if (sp == 0)
-           sp = read_memory_unsigned_integer (sp_addr, 8);
+           sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
 
          /* Write the register into the stack frame.  */
          regcache_raw_collect (regcache, i, buf);
@@ -342,10 +355,12 @@ amd64obsd_collect_uthread (const struct regcache *regcache,
 static struct trad_frame_cache *
 amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct trad_frame_cache *cache;
   CORE_ADDR func, sp, addr;
   ULONGEST cs;
-  char *name;
+  const char *name;
   int i;
 
   if (*this_cache)
@@ -369,11 +384,11 @@ amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 
   /* Read %cs from trap frame.  */
   addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
-  cs = read_memory_unsigned_integer (addr, 8); 
+  cs = read_memory_unsigned_integer (addr, 8, byte_order);
   if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
     {
       /* Trap from user space; terminate backtrace.  */
-      trad_frame_set_id (cache, null_frame_id);
+      trad_frame_set_id (cache, outer_frame_id);
     }
   else
     {
@@ -410,7 +425,7 @@ amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
                             void **this_prologue_cache)
 {
   ULONGEST cs;
-  char *name;
+  const char *name;
 
   /* Check Current Privilege Level and bail out if we're not executing
      in kernel space.  */
@@ -430,6 +445,7 @@ static const struct frame_unwind amd64obsd_trapframe_unwind = {
      frame, but SIGTRAMP_FRAME would print <signal handler called>,
      which really is not what we want here.  */
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   amd64obsd_trapframe_this_id,
   amd64obsd_trapframe_prev_register,
   NULL,
@@ -449,9 +465,6 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
   tdep->sizeof_gregset = 24 * 8;
 
-  set_gdbarch_regset_from_core_section (gdbarch,
-                                       amd64obsd_regset_from_core_section);
-
   tdep->jb_pc_offset = 7 * 8;
 
   tdep->sigtramp_p = amd64obsd_sigtramp_p;
@@ -470,6 +483,17 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* Unwind kernel trap frames correctly.  */
   frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
 }
+
+/* Traditional (a.out) NetBSD-style core dumps.  */
+
+static void
+amd64obsd_core_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  amd64obsd_init_abi (info, gdbarch);
+
+  set_gdbarch_regset_from_core_section
+    (gdbarch, amd64obsd_regset_from_core_section);
+}
 \f
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
@@ -486,5 +510,5 @@ _initialize_amd64obsd_tdep (void)
 
   /* OpenBSD uses traditional (a.out) NetBSD-style core dumps.  */
   gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
-                         GDB_OSABI_NETBSD_AOUT, amd64obsd_init_abi);
+                         GDB_OSABI_NETBSD_AOUT, amd64obsd_core_init_abi);
 }