diff --git a/gdb/hppa-pinsn.c b/gdb/hppa-pinsn.c index 0f0fec1472..87d5e7a6fe 100644 --- a/gdb/hppa-pinsn.c +++ b/gdb/hppa-pinsn.c @@ -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 */ diff --git a/gdb/hppah-tdep.c b/gdb/hppah-tdep.c index 7c0c6f328d..5a1227a249 100644 --- a/gdb/hppah-tdep.c +++ b/gdb/hppah-tdep.c @@ -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; diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 78a60614e8..f8b887ff90 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -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. */ diff --git a/gdb/paread.c b/gdb/paread.c index afab674473..46a6e3d253 100644 --- a/gdb/paread.c +++ b/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); } diff --git a/gdb/tm-hppa.h b/gdb/tm-hppa.h index 15be003645..957fc150a6 100644 --- a/gdb/tm-hppa.h +++ b/gdb/tm-hppa.h @@ -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)