2004-04-22 Randolph Chung <tausq@debian.org>
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index b3e9f5fecc1e76c8d630a5df19c66d386ea9cb42..26b73dc551c3fd0fe2f606001c5ad59bc772e64a 100644 (file)
@@ -54,6 +54,8 @@
 #include "objfiles.h"
 #include "hppa-tdep.h"
 
+static int hppa_debug = 0;
+
 /* Some local constants.  */
 static const int hppa32_num_regs = 128;
 static const int hppa64_num_regs = 96;
@@ -351,15 +353,18 @@ compare_unwind_entries (const void *arg1, const void *arg2)
     return 0;
 }
 
-static CORE_ADDR low_text_segment_address;
-
 static void
-record_text_segment_lowaddr (bfd *abfd, asection *section, void *ignored)
+record_text_segment_lowaddr (bfd *abfd, asection *section, void *data)
 {
-  if (((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+  if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
        == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
-      && section->vma < low_text_segment_address)
-    low_text_segment_address = section->vma;
+    {
+      bfd_vma value = section->vma - section->filepos;
+      CORE_ADDR *low_text_segment_address = (CORE_ADDR *)data;
+
+      if (value < *low_text_segment_address)
+          *low_text_segment_address = value;
+    }
 }
 
 static void
@@ -369,30 +374,29 @@ internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
 {
   /* We will read the unwind entries into temporary memory, then
      fill in the actual unwind table.  */
+
   if (size > 0)
     {
       unsigned long tmp;
       unsigned i;
       char *buf = alloca (size);
+      CORE_ADDR low_text_segment_address;
 
-      low_text_segment_address = -1;
-
-      /* If addresses are 64 bits wide, then unwinds are supposed to
+      /* For ELF targets, then unwinds are supposed to
         be segment relative offsets instead of absolute addresses. 
 
         Note that when loading a shared library (text_offset != 0) the
         unwinds are already relative to the text_offset that will be
         passed in.  */
-      if (TARGET_PTR_BIT == 64 && text_offset == 0)
+      if (gdbarch_tdep (current_gdbarch)->is_elf && text_offset == 0)
        {
+          low_text_segment_address = -1;
+
          bfd_map_over_sections (objfile->obfd,
-                                record_text_segment_lowaddr, NULL);
+                                record_text_segment_lowaddr, 
+                                &low_text_segment_address);
 
-         /* ?!? Mask off some low bits.  Should this instead subtract
-            out the lowest section's filepos or something like that?
-            This looks very hokey to me.  */
-         low_text_segment_address &= ~0xfff;
-         text_offset += low_text_segment_address;
+         text_offset = low_text_segment_address;
        }
 
       bfd_get_section_contents (objfile->obfd, section, buf, 0, size);
@@ -605,9 +609,17 @@ find_unwind_entry (CORE_ADDR pc)
   struct objfile *objfile;
   struct hppa_objfile_private *priv;
 
+  if (hppa_debug)
+    fprintf_unfiltered (gdb_stdlog, "{ find_unwind_entry 0x%s -> ",
+                       paddr_nz (pc));
+
   /* A function at address 0?  Not in HP-UX! */
   if (pc == (CORE_ADDR) 0)
-    return NULL;
+    {
+      if (hppa_debug)
+       fprintf_unfiltered (gdb_stdlog, "NULL }\n");
+      return NULL;
+    }
 
   ALL_OBJFILES (objfile)
   {
@@ -631,7 +643,12 @@ find_unwind_entry (CORE_ADDR pc)
     if (ui->cache
        && pc >= ui->cache->region_start
        && pc <= ui->cache->region_end)
-      return ui->cache;
+      {
+       if (hppa_debug)
+         fprintf_unfiltered (gdb_stdlog, "0x%s (cached) }\n",
+            paddr_nz ((CORE_ADDR) ui->cache));
+        return ui->cache;
+      }
 
     /* Not in the cache, do a binary search */
 
@@ -645,6 +662,9 @@ find_unwind_entry (CORE_ADDR pc)
            && pc <= ui->table[middle].region_end)
          {
            ui->cache = &ui->table[middle];
+           if (hppa_debug)
+             fprintf_unfiltered (gdb_stdlog, "0x%s }\n",
+                paddr_nz ((CORE_ADDR) ui->cache));
            return &ui->table[middle];
          }
 
@@ -654,6 +674,10 @@ find_unwind_entry (CORE_ADDR pc)
          first = middle + 1;
       }
   }                            /* ALL_OBJFILES() */
+
+  if (hppa_debug)
+    fprintf_unfiltered (gdb_stdlog, "NULL (not found) }\n");
+
   return NULL;
 }
 
@@ -2039,8 +2063,17 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache)
   struct unwind_table_entry *u;
   int i;
 
+  if (hppa_debug)
+    fprintf_unfiltered (gdb_stdlog, "{ hppa_frame_cache (frame=%d) -> ",
+      frame_relative_level(next_frame));
+
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    {
+      if (hppa_debug)
+        fprintf_unfiltered (gdb_stdlog, "base=0x%s (cached) }", 
+          paddr_nz (((struct hppa_frame_cache *)*this_cache)->base));
+      return (*this_cache);
+    }
   cache = FRAME_OBSTACK_ZALLOC (struct hppa_frame_cache);
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
@@ -2048,7 +2081,11 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache)
   /* Yow! */
   u = find_unwind_entry (frame_func_unwind (next_frame));
   if (!u)
-    return (*this_cache);
+    {
+      if (hppa_debug)
+        fprintf_unfiltered (gdb_stdlog, "base=NULL (no unwind entry) }");
+      return (*this_cache);
+    }
 
   /* Turn the Entry_GR field into a bitmask.  */
   saved_gr_mask = 0;
@@ -2243,6 +2280,9 @@ hppa_frame_cache (struct frame_info *next_frame, void **this_cache)
       }
   }
 
+  if (hppa_debug)
+    fprintf_unfiltered (gdb_stdlog, "base=0x%s }", 
+      paddr_nz (((struct hppa_frame_cache *)*this_cache)->base));
   return (*this_cache);
 }
 
@@ -2540,6 +2580,18 @@ hppa_fetch_pointer_argument (struct frame_info *frame, int argi,
   return addr;
 }
 
+static void
+hppa_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                          int regnum, void *buf)
+{
+    ULONGEST tmp;
+
+    regcache_raw_read_unsigned (regcache, regnum, &tmp);
+    if (regnum == PCOQ_HEAD_REGNUM || regnum == PCOQ_TAIL_REGNUM)
+      tmp &= ~0x3;
+    store_unsigned_integer (buf, sizeof(tmp), tmp);
+}
+
 /* Here is a table of C type sizes on hppa with various compiles
    and options.  I measured this on PA 9000/800 with HP-UX 11.11
    and these compilers:
@@ -2595,7 +2647,7 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return (arches->gdbarch);
 
   /* If none found, then allocate and initialize one.  */
-  tdep = XMALLOC (struct gdbarch_tdep);
+  tdep = XZALLOC (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* Determine from the bfd_arch_info structure if we are dealing with
@@ -2699,6 +2751,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   frame_unwind_append_sniffer (gdbarch, hppa_frame_unwind_sniffer);
   frame_base_append_sniffer (gdbarch, hppa_frame_base_sniffer);
 
+  set_gdbarch_pseudo_register_read (gdbarch, hppa_pseudo_register_read);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
@@ -2708,7 +2762,11 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 static void
 hppa_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 {
-   /* Nothing to print for the moment.  */
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  fprintf_unfiltered (file, "bytes_per_address = %d\n", 
+                      tdep->bytes_per_address);
+  fprintf_unfiltered (file, "elf = %s\n", tdep->is_elf ? "yes" : "no");
 }
 
 void
@@ -2756,5 +2814,10 @@ be no argument or the argument must be a depth.\n"), NULL);
                            break_at_finish_at_depth_command,
 "Set breakpoint at procedure exit.  Either there should\n\
 be no argument or the argument must be a depth.\n"), NULL);
+
+  /* Debug this files internals. */
+  add_show_from_set (add_set_cmd ("hppa", class_maintenance, var_zinteger,
+                                 &hppa_debug, "Set hppa debugging.\n\
+When non-zero, hppa specific debugging is enabled.", &setdebuglist), &showdebuglist);
 }
 
This page took 0.029171 seconds and 4 git commands to generate.