2009-10-13 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gdb / hppa-linux-tdep.c
index ef6b65fa1746d15042bc6a2d03f4529431c00616..50b8bd3836def7cca310bffc9451040c96bd1534 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #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 +87,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 +100,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 +131,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 +155,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 +165,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 +211,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 +226,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 +237,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 +262,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 +301,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 +331,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 +347,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 
@@ -365,10 +369,12 @@ hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 
       if (osect < faddr_sect->objfile->sections_end)
        {
-         CORE_ADDR addr;
+         CORE_ADDR addr, endaddr;
 
-         addr = osect->addr;
-         while (addr < osect->endaddr)
+         addr = obj_section_addr (osect);
+         endaddr = obj_section_endaddr (osect);
+
+         while (addr < endaddr)
            {
              int status;
              LONGEST tag;
@@ -377,7 +383,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)
                {
@@ -386,8 +392,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;
                }
@@ -472,12 +478,12 @@ hppa_linux_supply_fpregset (const struct regset *regset,
   int i, offset;
 
   offset = 0;
-  for (i = 0; i < 31; i++)
+  for (i = 0; i < 64; i++)
     {
       if (regnum == HPPA_FP0_REGNUM + i || regnum == -1)
         regcache_raw_supply (regcache, HPPA_FP0_REGNUM + i, 
                             buf + offset);
-      offset += 8;
+      offset += 4;
     }
 }
 
@@ -543,12 +549,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.034119 seconds and 4 git commands to generate.