* hppa-pinsn.c (print_insn): Use read_memory_integer, instead of
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.
This commit is contained in:
parent
30ea4a2d91
commit
fa9265e55d
5 changed files with 110 additions and 56 deletions
|
@ -87,9 +87,10 @@ print_insn (memaddr, stream)
|
|||
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)
|
||||
{
|
||||
|
@ -354,14 +355,15 @@ print_insn (memaddr, stream)
|
|||
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 */
|
||||
|
|
|
@ -56,6 +56,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "gdbcore.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "target.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
|
||||
/* Routines to extract various sized constants out of hppa
|
||||
|
@ -218,55 +220,58 @@ extract_17 (word)
|
|||
(word & 0x1) << 16, 17) << 2;
|
||||
}
|
||||
|
||||
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)
|
||||
ui = OBJ_UNWIND_INFO (objfile);
|
||||
|
||||
if (!ui)
|
||||
continue;
|
||||
|
||||
/* First, check the cache */
|
||||
|
||||
if (ui->cache
|
||||
&& pc >= ui->cache->region_start
|
||||
&& pc <= ui->cache->region_end)
|
||||
return ui->cache;
|
||||
|
||||
/* Not in the cache, do a binary search */
|
||||
|
||||
first = 0;
|
||||
last = ui->last;
|
||||
|
||||
while (first <= last)
|
||||
{
|
||||
int size;
|
||||
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];
|
||||
}
|
||||
|
||||
size = bfd_section_size (exec_bfd, unwind_sec);
|
||||
unwind = malloc (size);
|
||||
unwind_last = size / sizeof (struct unwind_table_entry) - 1;
|
||||
|
||||
bfd_get_section_contents (exec_bfd, unwind_sec, unwind, 0, size);
|
||||
if (pc < ui->table[middle].region_start)
|
||||
last = middle - 1;
|
||||
else
|
||||
first = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (unwind_cache > 0
|
||||
&& pc >= unwind[unwind_cache].region_start
|
||||
&& pc <= unwind[unwind_cache].region_end)
|
||||
return &unwind[unwind_cache];
|
||||
|
||||
first = 0;
|
||||
last = unwind_last;
|
||||
|
||||
while (first <= last)
|
||||
{
|
||||
middle = (first + last) / 2;
|
||||
if (pc >= unwind[middle].region_start
|
||||
&& pc <= unwind[middle].region_end)
|
||||
return &unwind[middle];
|
||||
|
||||
if (pc < unwind[middle].region_start)
|
||||
last = middle - 1;
|
||||
else
|
||||
first = middle + 1;
|
||||
}
|
||||
return NULL;
|
||||
} /* ALL_OBJFILES() */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -819,7 +824,7 @@ skip_prologue(pc)
|
|||
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;
|
||||
|
|
|
@ -240,6 +240,11 @@ struct objfile
|
|||
|
||||
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. */
|
||||
|
|
57
gdb/paread.c
57
gdb/paread.c
|
@ -18,20 +18,6 @@ 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., 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"
|
||||
|
@ -56,6 +42,9 @@ pa_symfile_init PARAMS ((struct objfile *));
|
|||
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));
|
||||
|
||||
|
@ -174,6 +163,44 @@ pa_symtab_read (abfd, addr, objfile)
|
|||
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.
|
||||
|
@ -230,6 +257,8 @@ pa_symfile_read (objfile, section_offsets, mainline)
|
|||
|
||||
pastab_build_psymtabs (objfile, section_offsets, mainline);
|
||||
|
||||
read_unwind_info(objfile);
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
|
|
|
@ -574,3 +574,16 @@ struct unwind_table_entry {
|
|||
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)
|
||||
|
|
Loading…
Reference in a new issue