daily update
[deliverable/binutils-gdb.git] / gdb / hppa-linux-tdep.c
index 2cc591c0f8951006b150cf07bf8ed75b43e99e52..70f53a6752b71e45cba2e7214ee4b35c26822782 100644 (file)
@@ -1,6 +1,7 @@
 /* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
 
-   Copyright (C) 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "regset.h"
 #include "regcache.h"
 #include "hppa-tdep.h"
-
+#include "linux-tdep.h"
 #include "elf/common.h"
 
-#if 0
-/* Convert DWARF register number REG to the appropriate register
-   number used by GDB.  */
+/* Map DWARF DBX register numbers to GDB register numbers.  */
 static int
-hppa_dwarf_reg_to_regnum (int reg)
+hppa_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 {
-  /* registers 0 - 31 are the same in both sets */
-  if (reg < 32)
+  /* The general registers and the sar are the same in both sets.  */
+  if (reg <= 32)
     return reg;
 
-  /* dwarf regs 32 to 85 are fpregs 4 - 31 */
-  if (reg >= 32 && reg <= 85)
-    return HPPA_FP4_REGNUM + (reg - 32);
+  /* fr4-fr31 (left and right halves) are mapped from 72.  */
+  if (reg >= 72 && reg <= 72 + 28 * 2)
+    return HPPA_FP4_REGNUM + (reg - 72);
 
-  warning (_("Unmapped DWARF Register #%d encountered."), reg);
+  warning (_("Unmapped DWARF DBX Register #%d encountered."), reg);
   return -1;
 }
-#endif
 
 static void
 hppa_linux_target_write_pc (struct regcache *regcache, CORE_ADDR v)
@@ -90,10 +88,11 @@ static struct insn_pattern hppa_sigtramp[] = {
    When the match is successful, fill INSN[i] with what PATTERN[i]
    matched.  */
 static int
-insns_match_pattern (CORE_ADDR pc,
+insns_match_pattern (struct gdbarch *gdbarch, CORE_ADDR pc,
                      struct insn_pattern *pattern,
                      unsigned int *insn)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int i;
   CORE_ADDR npc = pc;
 
@@ -102,7 +101,7 @@ insns_match_pattern (CORE_ADDR pc,
       char buf[4];
 
       target_read_memory (npc, buf, 4);
-      insn[i] = extract_unsigned_integer (buf, 4);
+      insn[i] = extract_unsigned_integer (buf, 4, byte_order);
       if ((insn[i] & pattern[i].mask) == pattern[i].data)
         npc += 4;
       else
@@ -133,7 +132,7 @@ insns_match_pattern (CORE_ADDR pc,
    Note that with a 2.4 64-bit kernel, the signal context is not properly
    passed back to userspace so the unwind will not work correctly.  */
 static CORE_ADDR
-hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
+hppa_linux_sigtramp_find_sigcontext (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   unsigned int dummy[HPPA_MAX_INSN_PATTERN_LEN];
   int offs = 0;
@@ -157,7 +156,8 @@ hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
 
   for (try = 0; try < ARRAY_SIZE (pcoffs); try++)
     {
-      if (insns_match_pattern (sp + pcoffs[try], hppa_sigtramp, dummy))
+      if (insns_match_pattern (gdbarch, sp + pcoffs[try],
+                              hppa_sigtramp, dummy))
        {
           offs = sfoffs[try];
          break;
@@ -166,7 +166,7 @@ hppa_linux_sigtramp_find_sigcontext (CORE_ADDR pc)
 
   if (offs == 0)
     {
-      if (insns_match_pattern (pc, hppa_sigtramp, dummy))
+      if (insns_match_pattern (gdbarch, pc, hppa_sigtramp, dummy))
        {
          /* sigaltstack case: we have no way of knowing which offset to 
             use in this case; default to new kernel handling. If this is
@@ -212,7 +212,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
   info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
   pc = get_frame_pc (this_frame);
-  scptr = hppa_linux_sigtramp_find_sigcontext (pc);
+  scptr = hppa_linux_sigtramp_find_sigcontext (gdbarch, pc);
 
   /* structure of struct sigcontext:
    
@@ -227,7 +227,8 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
   /* Skip sc_flags.  */
   scptr += 4;
 
-  /* GR[0] is the psw, we don't restore that.  */
+  /* GR[0] is the psw.  */
+  info->saved_regs[HPPA_IPSW_REGNUM].addr = scptr;
   scptr += 4;
 
   /* General registers.  */
@@ -237,7 +238,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
       scptr += 4;
     }
 
-  /* Pad.  */
+  /* Pad to long long boundary.  */
   scptr += 4;
 
   /* FP regs; FP0-3 are not restored.  */
@@ -262,6 +263,8 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
   info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
   scptr += 4;
 
+  info->saved_regs[HPPA_SAR_REGNUM].addr = scptr;
+
   info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
 
   return info;
@@ -299,9 +302,10 @@ hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
                                   struct frame_info *this_frame,
                                   void **this_prologue_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
 
-  if (hppa_linux_sigtramp_find_sigcontext (pc))
+  if (hppa_linux_sigtramp_find_sigcontext (gdbarch, pc))
     return 1;
 
   return 0;
@@ -328,6 +332,7 @@ static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
 static CORE_ADDR
 hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   struct obj_section *faddr_sect;
   CORE_ADDR faddr;
   
@@ -343,7 +348,7 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 
       status = target_read_memory (faddr + 4, buf, sizeof (buf));
       if (status == 0)
-       return extract_unsigned_integer (buf, sizeof (buf));
+       return extract_unsigned_integer (buf, sizeof (buf), byte_order);
     }
 
   /* If the address is in the plt section, then the real function hasn't 
@@ -379,7 +384,7 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
              status = target_read_memory (addr, buf, sizeof (buf));
              if (status != 0)
                break;
-             tag = extract_signed_integer (buf, sizeof (buf));
+             tag = extract_signed_integer (buf, sizeof (buf), byte_order);
 
              if (tag == DT_PLTGOT)
                {
@@ -388,8 +393,8 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
                  status = target_read_memory (addr + 4, buf, sizeof (buf));
                  if (status != 0)
                    break;
-                 global_pointer = extract_unsigned_integer (buf, sizeof (buf));
-
+                 global_pointer = extract_unsigned_integer (buf, sizeof (buf),
+                                                            byte_order);
                  /* The payoff... */
                  return global_pointer;
                }
@@ -518,6 +523,8 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
+  linux_init_abi (info, gdbarch);
+
   /* GNU/Linux is always ELF.  */
   tdep->is_elf = 1;
 
@@ -545,12 +552,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_regset_from_core_section
     (gdbarch, hppa_linux_regset_from_core_section);
 
-#if 0
-  /* Dwarf-2 unwinding support.  Not yet working.  */
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
-  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
-  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
-#endif
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
This page took 0.027547 seconds and 4 git commands to generate.