Add signal number conversions for OpenBSD.
[deliverable/binutils-gdb.git] / gdb / amd64obsd-tdep.c
index be5641db620ec92764839ab002997569f4964f02..94463180b488e8543054fd863a136cdebdbca490 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for OpenBSD/amd64.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -31,8 +30,9 @@
 #include "trad-frame.h"
 
 #include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
 
+#include "obsd-tdep.h"
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
 #include "solib-svr4.h"
@@ -88,15 +88,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.  */
@@ -116,9 +122,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;
@@ -167,7 +176,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,
@@ -196,7 +205,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,
@@ -225,7 +234,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,
@@ -251,6 +260,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];
@@ -263,12 +274,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);
     }
 
@@ -280,7 +291,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);
@@ -293,6 +304,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];
@@ -308,10 +321,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.  */
@@ -326,7 +339,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);
@@ -343,10 +356,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)
@@ -370,11 +385,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
     {
@@ -411,7 +426,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.  */
@@ -431,6 +446,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,
@@ -444,15 +460,13 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   amd64_init_abi (info, gdbarch);
+  obsd_init_abi (info, gdbarch);
 
   /* Initialize general-purpose register set details.  */
   tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
   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;
@@ -471,6 +485,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.  */
@@ -487,5 +512,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);
 }
This page took 0.030365 seconds and 4 git commands to generate.