* 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
|
@ -87,9 +87,10 @@ print_insn (memaddr, stream)
|
||||||
CORE_ADDR memaddr;
|
CORE_ADDR memaddr;
|
||||||
FILE *stream;
|
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)
|
for (i = 0; i < NUMOPCODES; ++i)
|
||||||
{
|
{
|
||||||
|
@ -354,14 +355,15 @@ print_insn (memaddr, stream)
|
||||||
if (op == 0x38 /* be */ || op == 0x39 /* ble */)
|
if (op == 0x38 /* be */ || op == 0x39 /* ble */)
|
||||||
{
|
{
|
||||||
CORE_ADDR target_address;
|
CORE_ADDR target_address;
|
||||||
unsigned int prev_insn;
|
long prev_insn;
|
||||||
int basereg, basereg_prev;
|
int basereg, basereg_prev;
|
||||||
|
|
||||||
target_address = extract_17 (insn);
|
target_address = extract_17 (insn);
|
||||||
basereg = GET_FIELD (insn, 6, 10);
|
basereg = GET_FIELD (insn, 6, 10);
|
||||||
if (basereg != 0)
|
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);
|
basereg_prev = GET_FIELD (prev_insn, 6, 10);
|
||||||
|
|
||||||
if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */
|
if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */
|
||||||
|
|
|
@ -56,6 +56,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "gdbcmd.h"
|
#include "gdbcmd.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
#include "symfile.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
|
||||||
|
|
||||||
/* Routines to extract various sized constants out of hppa
|
/* Routines to extract various sized constants out of hppa
|
||||||
|
@ -218,55 +220,58 @@ extract_17 (word)
|
||||||
(word & 0x1) << 16, 17) << 2;
|
(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 *
|
static struct unwind_table_entry *
|
||||||
find_unwind_entry(pc)
|
find_unwind_entry(pc)
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
{
|
{
|
||||||
static struct unwind_table_entry *unwind = NULL;
|
|
||||||
static int unwind_last;
|
|
||||||
static int unwind_cache = -1;
|
|
||||||
int first, middle, last;
|
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$");
|
ui = OBJ_UNWIND_INFO (objfile);
|
||||||
if (unwind_sec)
|
|
||||||
|
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);
|
if (pc < ui->table[middle].region_start)
|
||||||
unwind = malloc (size);
|
last = middle - 1;
|
||||||
unwind_last = size / sizeof (struct unwind_table_entry) - 1;
|
else
|
||||||
|
first = middle + 1;
|
||||||
bfd_get_section_contents (exec_bfd, unwind_sec, unwind, 0, size);
|
|
||||||
}
|
}
|
||||||
}
|
} /* ALL_OBJFILES() */
|
||||||
|
return NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -819,7 +824,7 @@ skip_prologue(pc)
|
||||||
int inst;
|
int inst;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = target_read_memory (pc, &inst, 4);
|
status = target_read_memory (pc, (char *)&inst, 4);
|
||||||
SWAP_TARGET_AND_HOST (&inst, sizeof (inst));
|
SWAP_TARGET_AND_HOST (&inst, sizeof (inst));
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return pc;
|
return pc;
|
||||||
|
|
|
@ -240,6 +240,11 @@ struct objfile
|
||||||
|
|
||||||
PTR sym_private;
|
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. */
|
/* 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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
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 "defs.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
|
@ -56,6 +42,9 @@ pa_symfile_init PARAMS ((struct objfile *));
|
||||||
static void
|
static void
|
||||||
pa_new_init PARAMS ((struct objfile *));
|
pa_new_init PARAMS ((struct objfile *));
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_unwind_info PARAMS ((struct objfile *));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pa_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
|
pa_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
|
||||||
|
|
||||||
|
@ -174,6 +163,44 @@ pa_symtab_read (abfd, addr, objfile)
|
||||||
install_minimal_symbols (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.
|
/* Scan and build partial symbols for a symbol file.
|
||||||
We have been initialized by a call to pa_symfile_init, which
|
We have been initialized by a call to pa_symfile_init, which
|
||||||
currently does nothing.
|
currently does nothing.
|
||||||
|
@ -230,6 +257,8 @@ pa_symfile_read (objfile, section_offsets, mainline)
|
||||||
|
|
||||||
pastab_build_psymtabs (objfile, section_offsets, mainline);
|
pastab_build_psymtabs (objfile, section_offsets, mainline);
|
||||||
|
|
||||||
|
read_unwind_info(objfile);
|
||||||
|
|
||||||
do_cleanups (back_to);
|
do_cleanups (back_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -574,3 +574,16 @@ struct unwind_table_entry {
|
||||||
unsigned int reserved4 : 2;
|
unsigned int reserved4 : 2;
|
||||||
unsigned int Total_frame_size : 27;
|
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 New Issue