read_memory to get byte order right.
* hppah-tdep.c (find_unwind_info): Don't read in unwind info
anymore. This is done in paread.c now. We expect unwind info
to hang off of objfiles, and search all of the objfiles when until
we find a match.
* (skip_trampoline_code): Cast arg to target_read_memory.
* objfiles.h (struct objfile): Add new field obj_private to hold
per object file private data (unwind info in this case).
* paread.c (read_unwind_info): New routine to read unwind info
for the objfile. This data is hung off of obj_private.
* tm-hppa.h: Define struct obj_unwind_info, to hold pointers to
the unwind info for this objfile. Also define OBJ_UNWIND_INFO to
make this easier to access.
CORE_ADDR memaddr;
FILE *stream;
{
- unsigned int insn, i, op;
+ long insn;
+ unsigned int i, op;
- read_memory (memaddr, &insn, sizeof (insn));
+ insn = read_memory_integer (memaddr, sizeof (insn));
for (i = 0; i < NUMOPCODES; ++i)
{
if (op == 0x38 /* be */ || op == 0x39 /* ble */)
{
CORE_ADDR target_address;
- unsigned int prev_insn;
+ long prev_insn;
int basereg, basereg_prev;
target_address = extract_17 (insn);
basereg = GET_FIELD (insn, 6, 10);
if (basereg != 0)
{
- read_memory (memaddr - 4, &prev_insn, sizeof(prev_insn));
+ prev_insn = read_memory_integer (memaddr - 4,
+ sizeof(prev_insn));
basereg_prev = GET_FIELD (prev_insn, 6, 10);
if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
+#include "symfile.h"
+#include "objfiles.h"
\f
/* Routines to extract various sized constants out of hppa
(word & 0x1) << 16, 17) << 2;
}
\f
-int use_unwind = 0;
+static int use_unwind = 0;
+
+/* Lookup the unwind (stack backtrace) info for the given PC. We search all
+ of the objfiles seeking the unwind table entry for this PC. Each objfile
+ contains a sorted list of struct unwind_table_entry. Since we do a binary
+ search of the unwind tables, we depend upon them to be sorted. */
static struct unwind_table_entry *
find_unwind_entry(pc)
CORE_ADDR pc;
{
- static struct unwind_table_entry *unwind = NULL;
- static int unwind_last;
- static int unwind_cache = -1;
int first, middle, last;
+ struct objfile *objfile;
- if (!unwind)
+ ALL_OBJFILES (objfile)
{
- asection *unwind_sec;
+ struct obj_unwind_info *ui;
- unwind_sec = bfd_get_section_by_name (exec_bfd, "$UNWIND_START$");
- if (unwind_sec)
- {
- int size;
+ ui = OBJ_UNWIND_INFO (objfile);
- size = bfd_section_size (exec_bfd, unwind_sec);
- unwind = malloc (size);
- unwind_last = size / sizeof (struct unwind_table_entry) - 1;
+ if (!ui)
+ continue;
- bfd_get_section_contents (exec_bfd, unwind_sec, unwind, 0, size);
- }
- }
+ /* First, check the cache */
- if (unwind_cache > 0
- && pc >= unwind[unwind_cache].region_start
- && pc <= unwind[unwind_cache].region_end)
- return &unwind[unwind_cache];
+ if (ui->cache
+ && pc >= ui->cache->region_start
+ && pc <= ui->cache->region_end)
+ return ui->cache;
- first = 0;
- last = unwind_last;
+ /* Not in the cache, do a binary search */
- while (first <= last)
- {
- middle = (first + last) / 2;
- if (pc >= unwind[middle].region_start
- && pc <= unwind[middle].region_end)
- return &unwind[middle];
+ first = 0;
+ last = ui->last;
- if (pc < unwind[middle].region_start)
- last = middle - 1;
- else
- first = middle + 1;
- }
- return NULL;
+ while (first <= last)
+ {
+ middle = (first + last) / 2;
+ if (pc >= ui->table[middle].region_start
+ && pc <= ui->table[middle].region_end)
+ {
+ ui->cache = &ui->table[middle];
+ return &ui->table[middle];
+ }
+
+ if (pc < ui->table[middle].region_start)
+ last = middle - 1;
+ else
+ first = middle + 1;
+ }
+ } /* ALL_OBJFILES() */
+ return NULL;
}
static int
int inst;
int status;
- status = target_read_memory (pc, &inst, 4);
+ status = target_read_memory (pc, (char *)&inst, 4);
SWAP_TARGET_AND_HOST (&inst, sizeof (inst));
if (status != 0)
return pc;
PTR sym_private;
+ /* Hook for other info specific to this objfile. This must point to
+ memory allocated on one of the obstacks in this objfile, so that it
+ gets freed automatically when reading a new object file. */
+
+ PTR obj_private;
};
/* Defines for the objfile flag word. */
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/************************************************************************
- * *
- * NOTICE *
- * *
- * This file is still under construction. When it is complete, this *
- * notice will be removed. Until then, direct any questions or changes *
- * to Fred Fish at Cygnus Support (fnf@cygnus.com) *
- * *
- * FIXME Still needs support for shared libraries. *
- * FIXME Still needs support for core files. *
- * FIXME The ".debug" and ".line" section names are hardwired. *
- * *
- ************************************************************************/
-
#include "defs.h"
#include "bfd.h"
#include "libbfd.h"
static void
pa_new_init PARAMS ((struct objfile *));
+static void
+read_unwind_info PARAMS ((struct objfile *));
+
static void
pa_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
install_minimal_symbols (objfile);
}
+/* Read in the backtrace information stored in the `$UNWIND_START$' section of
+ the object file. This info is used mainly by find_unwind_entry() to find
+ out the stack frame size and frame pointer used by procedures. We put
+ everything on the psymbol obstack in the objfile so that it automatically
+ gets freed when the objfile is destroyed. */
+
+static void
+read_unwind_info (objfile)
+ struct objfile *objfile;
+{
+ asection *unwind_sec;
+ struct obj_unwind_info *ui;
+
+ ui = obstack_alloc (&objfile->psymbol_obstack,
+ sizeof (struct obj_unwind_info));
+
+ ui->table = NULL;
+ ui->cache = NULL;
+ ui->last = -1;
+
+ unwind_sec = bfd_get_section_by_name (objfile->obfd,
+ "$UNWIND_START$");
+ if (unwind_sec)
+ {
+ int size;
+ int i, *ip;
+
+ size = bfd_section_size (objfile->obfd, unwind_sec);
+ ui->table = obstack_alloc (&objfile->psymbol_obstack, size);
+ ui->last = size / sizeof (struct unwind_table_entry) - 1;
+
+ bfd_get_section_contents (objfile->obfd, unwind_sec, ui->table,
+ 0, size);
+
+ OBJ_UNWIND_INFO (objfile) = ui;
+ }
+}
+
/* Scan and build partial symbols for a symbol file.
We have been initialized by a call to pa_symfile_init, which
currently does nothing.
pastab_build_psymtabs (objfile, section_offsets, mainline);
+ read_unwind_info(objfile);
+
do_cleanups (back_to);
}
unsigned int reserved4 : 2;
unsigned int Total_frame_size : 27;
};
+
+/* Info about the unwind table associated with an object file. This is hung
+ off of the objfile->obj_private pointer, and is allocated in the objfile's
+ psymbol obstack. This allows us to have unique unwind info for each
+ executable and shared library that we are debugging. */
+
+struct obj_unwind_info {
+ struct unwind_table_entry *table; /* Pointer to unwind info */
+ struct unwind_table_entry *cache; /* Pointer to last entry we found */
+ int last; /* Index of last entry */
+};
+
+#define OBJ_UNWIND_INFO(obj) ((struct obj_unwind_info *)obj->obj_private)