include/elf/ChangeLog:
[deliverable/binutils-gdb.git] / gdb / hppa-hpux-tdep.c
index da43b5253b415e60dd46036db39f5f4450044be3..2448a5afe5af441d69035eb69b5d311dc01235c6 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for HP-UX on PA-RISC.
 
-   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -16,8 +16,8 @@
 
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "arch-utils.h"
 #define IS_32BIT_TARGET(_gdbarch) \
        ((gdbarch_tdep (_gdbarch))->bytes_per_address == 4)
 
+/* Bit in the `ss_flag' member of `struct save_state' that indicates
+   that the 64-bit register values are live.  From
+   <machine/save_state.h>.  */
+#define HPPA_HPUX_SS_WIDEREGS          0x40
+
+/* Offsets of various parts of `struct save_state'.  From
+   <machine/save_state.h>.  */
+#define HPPA_HPUX_SS_FLAGS_OFFSET      0
+#define HPPA_HPUX_SS_NARROW_OFFSET     4
+#define HPPA_HPUX_SS_FPBLOCK_OFFSET    256
+#define HPPA_HPUX_SS_WIDE_OFFSET        640
+
+/* The size of `struct save_state.  */
+#define HPPA_HPUX_SAVE_STATE_SIZE      1152
+
+/* The size of `struct pa89_save_state', which corresponds to PA-RISC
+   1.1, the lowest common denominator that we support.  */
+#define HPPA_HPUX_PA89_SAVE_STATE_SIZE 512
+
+
 /* Forward declarations.  */
 extern void _initialize_hppa_hpux_tdep (void);
 extern initialize_file_ftype _initialize_hppa_hpux_tdep;
@@ -1158,8 +1178,8 @@ hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct hppa_hpux_sigtramp_unwind_cache *info;
   unsigned int flag;
-  CORE_ADDR sp, scptr;
-  int i, incr, off, szoff;
+  CORE_ADDR sp, scptr, off;
+  int i, incr, szoff;
 
   if (*this_cache)
     return *this_cache;
@@ -1170,25 +1190,29 @@ hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
 
   sp = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
 
-  scptr = sp - 1352;
+  if (IS_32BIT_TARGET (gdbarch))
+    scptr = sp - 1352;
+  else
+    scptr = sp - 1520;
+
   off = scptr;
 
   /* See /usr/include/machine/save_state.h for the structure of the save_state_t
      structure. */
   
-  flag = read_memory_unsigned_integer(scptr, 4);
-    
-  if (!(flag & 0x40))
+  flag = read_memory_unsigned_integer(scptr + HPPA_HPUX_SS_FLAGS_OFFSET, 4);
+
+  if (!(flag & HPPA_HPUX_SS_WIDEREGS))
     {
       /* Narrow registers. */
-      off = scptr + offsetof (save_state_t, ss_narrow);
+      off = scptr + HPPA_HPUX_SS_NARROW_OFFSET;
       incr = 4;
       szoff = 0;
     }
   else
     {
       /* Wide registers. */
-      off = scptr + offsetof (save_state_t, ss_wide) + 8;
+      off = scptr + HPPA_HPUX_SS_WIDE_OFFSET + 8;
       incr = 8;
       szoff = (tdep->bytes_per_address == 4 ? 4 : 0);
     }
@@ -1203,6 +1227,7 @@ hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
     {
       if (hppa_hpux_tramp_reg[i] > 0)
         info->saved_regs[hppa_hpux_tramp_reg[i]].addr = off + szoff;
+
       off += incr;
     }
 
@@ -1225,11 +1250,11 @@ hppa_hpux_sigtramp_frame_this_id (struct frame_info *next_frame,
 
 static void
 hppa_hpux_sigtramp_frame_prev_register (struct frame_info *next_frame,
-                                        void **this_prologue_cache,
-                                        int regnum, int *optimizedp,
-                                        enum lval_type *lvalp, 
-                                        CORE_ADDR *addrp,
-                                        int *realnump, void *valuep)
+                                       void **this_prologue_cache,
+                                       int regnum, int *optimizedp,
+                                       enum lval_type *lvalp, 
+                                       CORE_ADDR *addrp,
+                                       int *realnump, gdb_byte *valuep)
 {
   struct hppa_hpux_sigtramp_unwind_cache *info
     = hppa_hpux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
@@ -1246,12 +1271,28 @@ static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind = {
 static const struct frame_unwind *
 hppa_hpux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
 {
+  struct unwind_table_entry *u;
   CORE_ADDR pc = frame_pc_unwind (next_frame);
-  char *name;
 
-  find_pc_partial_function (pc, &name, NULL, NULL);
+  u = find_unwind_entry (pc);
+
+  /* If this is an export stub, try to get the unwind descriptor for
+     the actual function itself.  */
+  if (u && u->stub_unwind.stub_type == EXPORT)
+    {
+      gdb_byte buf[HPPA_INSN_SIZE];
+      unsigned long insn;
+
+      if (!safe_frame_unwind_memory (next_frame, u->region_start,
+                                    buf, sizeof buf))
+       return NULL;
+
+      insn = extract_unsigned_integer (buf, sizeof buf);
+      if ((insn & 0xffe0e000) == 0xe8400000)
+       u = find_unwind_entry(u->region_start + hppa_extract_17 (insn) + 8);
+    }
 
-  if (name && strcmp(name, "_sigreturn") == 0)
+  if (u && u->HP_UX_interrupt_marker)
     return &hppa_hpux_sigtramp_frame_unwind;
 
   return NULL;
@@ -1309,32 +1350,31 @@ static CORE_ADDR
 hppa_hpux_search_pattern (CORE_ADDR start, CORE_ADDR end, 
                          unsigned int *patterns, int count)
 {
-  unsigned int *buf;
+  int num_insns = (end - start + HPPA_INSN_SIZE) / HPPA_INSN_SIZE;
+  unsigned int *insns;
+  gdb_byte *buf;
   int offset, i;
-  int region, insns;
-
-  region = end - start + 4;
-  insns = region / 4;
-  buf = (unsigned int *) alloca (region);
 
-  read_memory (start, (char *) buf, region);
+  buf = alloca (num_insns * HPPA_INSN_SIZE);
+  insns = alloca (num_insns * sizeof (unsigned int));
 
-  for (i = 0; i < insns; i++)
-    buf[i] = extract_unsigned_integer (&buf[i], 4);
+  read_memory (start, buf, num_insns * HPPA_INSN_SIZE);
+  for (i = 0; i < num_insns; i++, buf += HPPA_INSN_SIZE)
+    insns[i] = extract_unsigned_integer (buf, HPPA_INSN_SIZE);
 
-  for (offset = 0; offset <= insns - count; offset++)
+  for (offset = 0; offset <= num_insns - count; offset++)
     {
       for (i = 0; i < count; i++)
         {
-         if ((buf[offset + i] & patterns[i]) != patterns[i])
+         if ((insns[offset + i] & patterns[i]) != patterns[i])
            break;
        }
       if (i == count)
         break;
     }
-    
-  if (offset <= insns - count)
-    return start + offset * 4;
+
+  if (offset <= num_insns - count)
+    return start + offset * HPPA_INSN_SIZE;
   else
     return 0;
 }
@@ -1472,7 +1512,7 @@ hppa64_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
     {
       CORE_ADDR begin, end;
       char *name;
-      unsigned int insns[2];
+      gdb_byte buf[2 * HPPA_INSN_SIZE];
       int offset;
 
       find_pc_partial_function (SYMBOL_VALUE_ADDRESS (msym), &name,
@@ -1481,16 +1521,16 @@ hppa64_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
       if (name == NULL || begin == 0 || end == 0)
         continue;
 
-      if (target_read_memory (end - sizeof (insns), (char *)insns, sizeof (insns)) == 0)
+      if (target_read_memory (end - sizeof (buf), buf, sizeof (buf)) == 0)
         {
-         for (offset = 0; offset < ARRAY_SIZE (insns); offset++)
+         for (offset = 0; offset < sizeof (buf); offset++)
            {
              unsigned int insn;
 
-             insn = extract_unsigned_integer (&insns[offset], 4);
+             insn = extract_unsigned_integer (buf + offset, HPPA_INSN_SIZE);
              if (insn == 0xe840d002) /* bve,n (rp) */
                {
-                 addr = (end - sizeof (insns)) + (offset * 4);
+                 addr = (end - sizeof (buf)) + offset;
                  goto found_pattern;
                }
            }
@@ -1761,25 +1801,6 @@ hppa_hpux_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
 
 \f
 
-/* Bit in the `ss_flag' member of `struct save_state' that indicates
-   that the 64-bit register values are live.  From
-   <machine/save_state.h>.  */
-#define HPPA_HPUX_SS_WIDEREGS          0x40
-
-/* Offsets of various parts of `struct save_state'.  From
-   <machine/save_state.h>.  */
-#define HPPA_HPUX_SS_FLAGS_OFFSET      0
-#define HPPA_HPUX_SS_NARROW_OFFSET     4
-#define HPPA_HPUX_SS_FPBLOCK_OFFSET    256
-#define HPPA_HPUX_SS_WIDE_OFFSET        640
-
-/* The size of `struct save_state.  */
-#define HPPA_HPUX_SAVE_STATE_SIZE      1152
-
-/* The size of `struct pa89_save_state', which corresponds to PA-RISC
-   1.1, the lowest common denominator that we support.  */
-#define HPPA_HPUX_PA89_SAVE_STATE_SIZE 512
-
 static void
 hppa_hpux_supply_ss_narrow (struct regcache *regcache,
                            int regnum, const char *save_state)
@@ -2056,6 +2077,24 @@ hppa_hpux_core_osabi_sniffer (bfd *abfd)
 {
   if (strcmp (bfd_get_target (abfd), "hpux-core") == 0)
     return GDB_OSABI_HPUX_SOM;
+  else if (strcmp (bfd_get_target (abfd), "elf64-hppa") == 0)
+    {
+      asection *section;
+      
+      section = bfd_get_section_by_name (abfd, ".kernel");
+      if (section)
+        {
+         bfd_size_type size;
+         char *contents;
+
+         size = bfd_section_size (abfd, section);
+         contents = alloca (size);
+         if (bfd_get_section_contents (abfd, section, contents, 
+                                       (file_ptr) 0, size)
+             && strcmp (contents, "HP-UX") == 0)
+           return GDB_OSABI_HPUX_ELF;
+       }
+    }
 
   return GDB_OSABI_UNKNOWN;
 }
@@ -2068,6 +2107,9 @@ _initialize_hppa_hpux_tdep (void)
   gdbarch_register_osabi_sniffer (bfd_arch_unknown,
                                  bfd_target_unknown_flavour,
                                  hppa_hpux_core_osabi_sniffer);
+  gdbarch_register_osabi_sniffer (bfd_arch_hppa,
+                                  bfd_target_elf_flavour,
+                                 hppa_hpux_core_osabi_sniffer);
 
   gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_HPUX_SOM,
                           hppa_hpux_som_init_abi);
This page took 0.02794 seconds and 4 git commands to generate.