* testsuite/Makefile.am: Add -ffunction-sections to compile
[deliverable/binutils-gdb.git] / gdb / hppa-linux-tdep.c
index c5d23f9e02ad809e0e50bf8f1ec4dc5d7f736ea8..295635addd38064e9ec19603f0554515eb759d15 100644 (file)
@@ -1,12 +1,12 @@
 /* Target-dependent code for GNU/Linux running on PA-RISC, for GDB.
 
-   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdbcore.h"
 #include "dwarf2-frame.h"
 #include "value.h"
 #include "regset.h"
+#include "regcache.h"
 #include "hppa-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 (CORE_ADDR v, ptid_t ptid)
+hppa_linux_target_write_pc (struct regcache *regcache, CORE_ADDR v)
 {
   /* Probably this should be done by the kernel, but it isn't.  */
-  write_register_pid (HPPA_PCOQ_HEAD_REGNUM, v | 0x3, ptid);
-  write_register_pid (HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3, ptid);
+  regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, v | 0x3);
+  regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_TAIL_REGNUM, (v + 4) | 0x3);
 }
 
 /* An instruction to match.  */
@@ -102,7 +98,7 @@ insns_match_pattern (CORE_ADDR pc,
     {
       char buf[4];
 
-      deprecated_read_memory_nobpt (npc, buf, 4);
+      target_read_memory (npc, buf, 4);
       insn[i] = extract_unsigned_integer (buf, 4);
       if ((insn[i] & pattern[i].mask) == pattern[i].data)
         npc += 4;
@@ -197,10 +193,10 @@ struct hppa_linux_sigtramp_unwind_cache
 };
 
 static struct hppa_linux_sigtramp_unwind_cache *
-hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
+hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
                                        void **this_cache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct hppa_linux_sigtramp_unwind_cache *info;
   CORE_ADDR pc, scptr;
   int i;
@@ -210,9 +206,9 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
 
   info = FRAME_OBSTACK_ZALLOC (struct hppa_linux_sigtramp_unwind_cache);
   *this_cache = info;
-  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
+  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
 
-  pc = frame_pc_unwind (next_frame);
+  pc = get_frame_pc (this_frame);
   scptr = hppa_linux_sigtramp_find_sigcontext (pc);
 
   /* structure of struct sigcontext:
@@ -228,7 +224,8 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_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.  */
@@ -238,7 +235,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
       scptr += 4;
     }
 
-  /* Pad.  */
+  /* Pad to long long boundary.  */
   scptr += 4;
 
   /* FP regs; FP0-3 are not restored.  */
@@ -263,58 +260,61 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
   info->saved_regs[HPPA_PCOQ_TAIL_REGNUM].addr = scptr;
   scptr += 4;
 
-  info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
+  info->saved_regs[HPPA_SAR_REGNUM].addr = scptr;
+
+  info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM);
 
   return info;
 }
 
 static void
-hppa_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+hppa_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
                                   void **this_prologue_cache,
                                   struct frame_id *this_id)
 {
   struct hppa_linux_sigtramp_unwind_cache *info
-    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
-  *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
+    = hppa_linux_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
+  *this_id = frame_id_build (info->base, get_frame_pc (this_frame));
 }
 
-static void
-hppa_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
+static struct value *
+hppa_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
                                         void **this_prologue_cache,
-                                        int regnum, int *optimizedp,
-                                        enum lval_type *lvalp, 
-                                        CORE_ADDR *addrp,
-                                        int *realnump, gdb_byte *valuep)
+                                        int regnum)
 {
   struct hppa_linux_sigtramp_unwind_cache *info
-    = hppa_linux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
-  hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
-                                  optimizedp, lvalp, addrp, realnump, valuep);
+    = hppa_linux_sigtramp_frame_unwind_cache (this_frame, this_prologue_cache);
+  return hppa_frame_prev_register_helper (this_frame,
+                                         info->saved_regs, regnum);
 }
 
-static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
-  SIGTRAMP_FRAME,
-  hppa_linux_sigtramp_frame_this_id,
-  hppa_linux_sigtramp_frame_prev_register
-};
-
 /* hppa-linux always uses "new-style" rt-signals.  The signal handler's return
    address should point to a signal trampoline on the stack.  The signal
    trampoline is embedded in a rt_sigframe structure that is aligned on
    the stack.  We take advantage of the fact that sp must be 64-byte aligned,
    and the trampoline is small, so by rounding down the trampoline address
    we can find the beginning of the struct rt_sigframe.  */
-static const struct frame_unwind *
-hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
+static int
+hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
+                                  struct frame_info *this_frame,
+                                  void **this_prologue_cache)
 {
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
 
   if (hppa_linux_sigtramp_find_sigcontext (pc))
-    return &hppa_linux_sigtramp_frame_unwind;
+    return 1;
 
-  return NULL;
+  return 0;
 }
 
+static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
+  SIGTRAMP_FRAME,
+  hppa_linux_sigtramp_frame_this_id,
+  hppa_linux_sigtramp_frame_prev_register,
+  NULL,
+  hppa_linux_sigtramp_frame_sniffer
+};
+
 /* Attempt to find (and return) the global pointer for the given
    function.
 
@@ -326,7 +326,7 @@ hppa_linux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
    d_un.d_ptr value is the global pointer.  */
 
 static CORE_ADDR
-hppa_linux_find_global_pointer (struct value *function)
+hppa_linux_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 {
   struct obj_section *faddr_sect;
   CORE_ADDR faddr;
@@ -365,10 +365,12 @@ hppa_linux_find_global_pointer (struct value *function)
 
       if (osect < faddr_sect->objfile->sections_end)
        {
-         CORE_ADDR addr;
+         CORE_ADDR addr, endaddr;
+
+         addr = obj_section_addr (osect);
+         endaddr = obj_section_endaddr (osect);
 
-         addr = osect->addr;
-         while (addr < osect->endaddr)
+         while (addr < endaddr)
            {
              int status;
              LONGEST tag;
@@ -472,16 +474,16 @@ 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;
     }
 }
 
-/* Linux register set.  */
+/* HPPA Linux kernel register set.  */
 static struct regset hppa_linux_regset =
 {
   NULL,
@@ -523,7 +525,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_write_pc (gdbarch, hppa_linux_target_write_pc);
 
-  frame_unwind_append_sniffer (gdbarch, hppa_linux_sigtramp_unwind_sniffer);
+  frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind);
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
@@ -543,13 +545,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_dwarf_reg_to_regnum (gdbarch, hppa_dwarf_reg_to_regnum);
   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.033696 seconds and 4 git commands to generate.