mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
PR symtab/17391 gdb internal error: assertion fails in regcache.c:178
gdb/ChangeLog: * dwarf2-frame.c (dwarf2_restore_rule): Call dwarf_reg_to_regnum instead of gdbarch_dwarf2_reg_to_regnum. (dwarf2_frame_cache): Ditto. (read_addr_from_reg): Call dwarf_reg_to_regnum_or_error instead of gdbarch_dwarf2_reg_to_regnum. (get_reg_value): Ditto. (dwarf2_fetch_cfa_info): Ditto. (dwarf2_frame_prev_register): Ditto. * dwarf2loc.c: #include "complaints.h". (dwarf_expr_read_addr_from_reg): Call dwarf_reg_to_regnum_or_error instead of gdbarch_dwarf2_reg_to_regnum. (dwarf_expr_get_reg_value): Ditto. (read_pieced_value): Ditto. (write_pieced_value): Ditto. (dwarf2_evaluate_loc_desc_full): Ditto. (dwarf_reg_to_regnum): New function. (throw_bad_regnum_error): New function. (dwarf_reg_to_regnum_or_error): Renamed from dwarf2_reg_to_regnum_or_errorChange to take a ULONGEST regnum. All callers updated. Call throw_bad_regnum_error. (locexpr_regname): Improve text of bad register number. * dwarf2loc.h (dwarf_reg_to_regnum): Declare. (dwarf_reg_to_regnum_or_error): Update prototype. * dwarf2expr.c: #include "dwarf2loc.h". (dwarf_block_to_sp_offset): Call dwarf_reg_to_regnum instead of gdbarch_dwarf2_reg_to_regnum. * gdbarch.sh (dwarf2_reg_to_regnum): Add comment. * gdbarch.h: Regenerate. * amd64-tdep.c (amd64_dwarf_reg_to_regnum): Remove warning for bad register. * avr-tdep.c (avr_dwarf_reg_to_regnum): Ditto. * cris-tdep.c (cris_dwarf2_reg_to_regnum): Ditto. * bfin-tdep.c (bfin_reg_to_regnum): Fix error checking. * hppa-linux-tdep.c (hppa_dwarf_reg_to_regnum): Improve error checking. Remove warning for bad register. * hppa-tdep.c (hppa64_dwarf_reg_to_regnum): Ditto. * i386-tdep.c (i386_svr4_dwarf_reg_to_regnum): Renamed from i386_svr4_reg_to_regnum. Return -1 for bad registers. (i386_svr4_reg_to_regnum): New function. (i386_gdbarch_init): Update call to set_gdbarch_dwarf2_reg_to_regnum. * microblaze-tdep.c (microblaze_dwarf2_reg_to_regnum): Don't assert on bad registers, return -1. * msp430-tdep.c (msp430_dwarf2_reg_to_regnum): Improve error checking. Remove warning for bad register. * nios2-tdep.c: Add static assert for NIOS2_NUM_REGS. (nios2_dwarf_reg_to_regnum): Fix off-by-one error. Remove warning for bad register. Return -1 for bad register. * rl78-tdep.c (rl78_dwarf_reg_to_regnum): Don't flag an internal error for bad register, return -1. * rx-tdep.c (rx_dwarf_reg_to_regnum): Ditto. * m68k-tdep.c (m68k_dwarf_reg_to_regnum): Fix error result. * mep-tdep.c (mep_debug_reg_to_regnum): Ditto. * mips-tdep.c (mips_stab_reg_to_regnum): Ditto. (mips_dwarf_dwarf2_ecoff_reg_to_regnum): Ditto. * mn10300-tdep.c (mn10300_dwarf2_reg_to_regnum): Remove warning for bad regs. * xtensa-tdep.c (xtensa_reg_to_regnum): Remove internal error for bad regs. Fix error result. * stabsread.c (stab_reg_to_regnum): Watch for negative regno. (reg_value_complaint): Update complaint text. * mdebugread.c (reg_value_complaint): New function. (mdebug_reg_to_regnum): Rewrite to watch for bad reg numbers. gdb/testsuite/ChangeLog: * lib/dwarf.exp (_location): Add support for DW_OP_regx. * gdb.dwarf2/bad-regnum.c: New file. * gdb.dwarf2/bad-regnum.exp: New file.
This commit is contained in:
@ -292,7 +292,7 @@ read_addr_from_reg (void *baton, int reg)
|
||||
{
|
||||
struct frame_info *this_frame = (struct frame_info *) baton;
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
|
||||
int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg);
|
||||
|
||||
return address_from_register (regnum, this_frame);
|
||||
}
|
||||
@ -304,7 +304,7 @@ get_reg_value (void *baton, struct type *type, int reg)
|
||||
{
|
||||
struct frame_info *this_frame = (struct frame_info *) baton;
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
|
||||
int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg);
|
||||
|
||||
return value_from_register (type, regnum, this_frame);
|
||||
}
|
||||
@ -336,13 +336,15 @@ dwarf2_restore_rule (struct gdbarch *gdbarch, ULONGEST reg_num,
|
||||
fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNSPECIFIED;
|
||||
|
||||
if (fs->regs.reg[reg].how == DWARF2_FRAME_REG_UNSPECIFIED)
|
||||
complaint (&symfile_complaints, _("\
|
||||
{
|
||||
int regnum = dwarf_reg_to_regnum (gdbarch, reg);
|
||||
|
||||
complaint (&symfile_complaints, _("\
|
||||
incomplete CFI data; DW_CFA_restore unspecified\n\
|
||||
register %s (#%d) at %s"),
|
||||
gdbarch_register_name
|
||||
(gdbarch, gdbarch_dwarf2_reg_to_regnum (gdbarch, reg)),
|
||||
gdbarch_dwarf2_reg_to_regnum (gdbarch, reg),
|
||||
paddress (gdbarch, fs->pc));
|
||||
gdbarch_register_name (gdbarch, regnum), regnum,
|
||||
paddress (gdbarch, fs->pc));
|
||||
}
|
||||
}
|
||||
|
||||
/* Virtual method table for execute_stack_op below. */
|
||||
@ -942,11 +944,7 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
|
||||
{
|
||||
case CFA_REG_OFFSET:
|
||||
{
|
||||
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, fs.regs.cfa_reg);
|
||||
|
||||
if (regnum == -1)
|
||||
error (_("Unable to access DWARF register number %d"),
|
||||
(int) fs.regs.cfa_reg); /* FIXME */
|
||||
int regnum = dwarf_reg_to_regnum_or_error (gdbarch, fs.regs.cfa_reg);
|
||||
|
||||
*regnum_out = regnum;
|
||||
if (fs.armcc_cfa_offsets_reversed)
|
||||
@ -1093,7 +1091,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
|
||||
entry_pc, fs);
|
||||
|
||||
if (fs->regs.cfa_how == CFA_REG_OFFSET
|
||||
&& (gdbarch_dwarf2_reg_to_regnum (gdbarch, fs->regs.cfa_reg)
|
||||
&& (dwarf_reg_to_regnum (gdbarch, fs->regs.cfa_reg)
|
||||
== gdbarch_sp_regnum (gdbarch)))
|
||||
{
|
||||
cache->entry_cfa_sp_offset = fs->regs.cfa_offset;
|
||||
@ -1156,19 +1154,16 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
|
||||
/* Go through the DWARF2 CFI generated table and save its register
|
||||
location information in the cache. Note that we don't skip the
|
||||
return address column; it's perfectly all right for it to
|
||||
correspond to a real register. If it doesn't correspond to a
|
||||
real register, or if we shouldn't treat it as such,
|
||||
gdbarch_dwarf2_reg_to_regnum should be defined to return a number outside
|
||||
the range [0, gdbarch_num_regs). */
|
||||
correspond to a real register. */
|
||||
{
|
||||
int column; /* CFI speak for "register number". */
|
||||
|
||||
for (column = 0; column < fs->regs.num_regs; column++)
|
||||
{
|
||||
/* Use the GDB register number as the destination index. */
|
||||
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, column);
|
||||
int regnum = dwarf_reg_to_regnum (gdbarch, column);
|
||||
|
||||
/* If there's no corresponding GDB register, ignore it. */
|
||||
/* Protect against a target returning a bad register. */
|
||||
if (regnum < 0 || regnum >= num_regs)
|
||||
continue;
|
||||
|
||||
@ -1330,8 +1325,8 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
|
||||
return frame_unwind_got_memory (this_frame, regnum, addr);
|
||||
|
||||
case DWARF2_FRAME_REG_SAVED_REG:
|
||||
realnum
|
||||
= gdbarch_dwarf2_reg_to_regnum (gdbarch, cache->reg[regnum].loc.reg);
|
||||
realnum = dwarf_reg_to_regnum_or_error
|
||||
(gdbarch, cache->reg[regnum].loc.reg);
|
||||
return frame_unwind_got_register (this_frame, regnum, realnum);
|
||||
|
||||
case DWARF2_FRAME_REG_SAVED_EXP:
|
||||
@ -1374,7 +1369,7 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
|
||||
|
||||
case DWARF2_FRAME_REG_RA_OFFSET:
|
||||
addr = cache->reg[regnum].loc.offset;
|
||||
regnum = gdbarch_dwarf2_reg_to_regnum
|
||||
regnum = dwarf_reg_to_regnum_or_error
|
||||
(gdbarch, cache->retaddr_reg.loc.reg);
|
||||
addr += get_frame_register_unsigned (this_frame, regnum);
|
||||
return frame_unwind_got_address (this_frame, regnum, addr);
|
||||
|
Reference in New Issue
Block a user