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:
Doug Evans 2015-10-26 16:05:21 -07:00
parent 1a70ae976b
commit 0fde2c536b
31 changed files with 412 additions and 192 deletions

View file

@ -1,3 +1,69 @@
2015-10-26 Doug Evans <dje@google.com>
PR symtab/17391
* 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.
2015-10-26 Doug Evans <dje@google.com> 2015-10-26 Doug Evans <dje@google.com>
PR python/18938 PR python/18938

View file

@ -252,9 +252,7 @@ amd64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
if (reg >= 0 && reg < amd64_dwarf_regmap_len) if (reg >= 0 && reg < amd64_dwarf_regmap_len)
regnum = amd64_dwarf_regmap[reg]; regnum = amd64_dwarf_regmap[reg];
if (regnum == -1) if (ymm0_regnum >= 0
warning (_("Unmapped DWARF Register #%d encountered."), reg);
else if (ymm0_regnum >= 0
&& i386_xmm_regnum_p (gdbarch, regnum)) && i386_xmm_regnum_p (gdbarch, regnum))
regnum += ymm0_regnum - I387_XMM0_REGNUM (tdep); regnum += ymm0_regnum - I387_XMM0_REGNUM (tdep);

View file

@ -1364,9 +1364,6 @@ avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
return reg; return reg;
if (reg == 32) if (reg == 32)
return AVR_SP_REGNUM; return AVR_SP_REGNUM;
warning (_("Unmapped DWARF Register #%d encountered."), reg);
return -1; return -1;
} }

View file

@ -566,8 +566,8 @@ bfin_push_dummy_call (struct gdbarch *gdbarch,
static int static int
bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg) bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
if (reg > ARRAY_SIZE (map_gcc_gdb)) if (reg < 0 || reg >= ARRAY_SIZE (map_gcc_gdb))
return 0; return -1;
return map_gcc_gdb[reg]; return map_gcc_gdb[reg];
} }

View file

@ -817,15 +817,15 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
case DW_OP_reg31: case DW_OP_reg31:
dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
pushf_register_address (indent, stream, registers_used, arch, pushf_register_address (indent, stream, registers_used, arch,
dwarf2_reg_to_regnum_or_error (arch, dwarf_reg_to_regnum_or_error
op - DW_OP_reg0)); (arch, op - DW_OP_reg0));
break; break;
case DW_OP_regx: case DW_OP_regx:
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg); op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
pushf_register_address (indent, stream, registers_used, arch, pushf_register_address (indent, stream, registers_used, arch,
dwarf2_reg_to_regnum_or_error (arch, reg)); dwarf_reg_to_regnum_or_error (arch, reg));
break; break;
case DW_OP_breg0: case DW_OP_breg0:
@ -862,8 +862,8 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
case DW_OP_breg31: case DW_OP_breg31:
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
pushf_register (indent, stream, registers_used, arch, pushf_register (indent, stream, registers_used, arch,
dwarf2_reg_to_regnum_or_error (arch, dwarf_reg_to_regnum_or_error (arch,
op - DW_OP_breg0), op - DW_OP_breg0),
offset); offset);
break; break;
case DW_OP_bregx: case DW_OP_bregx:
@ -871,7 +871,7 @@ do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg); op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
pushf_register (indent, stream, registers_used, arch, pushf_register (indent, stream, registers_used, arch,
dwarf2_reg_to_regnum_or_error (arch, reg), offset); dwarf_reg_to_regnum_or_error (arch, reg), offset);
} }
break; break;
case DW_OP_fbreg: case DW_OP_fbreg:

View file

@ -1790,9 +1790,6 @@ cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
if (reg >= 0 && reg < ARRAY_SIZE (cris_dwarf_regmap)) if (reg >= 0 && reg < ARRAY_SIZE (cris_dwarf_regmap))
regnum = cris_dwarf_regmap[reg]; regnum = cris_dwarf_regmap[reg];
if (regnum == -1)
warning (_("Unmapped DWARF Register #%d encountered."), reg);
return regnum; return regnum;
} }

View file

@ -292,7 +292,7 @@ read_addr_from_reg (void *baton, int reg)
{ {
struct frame_info *this_frame = (struct frame_info *) baton; struct frame_info *this_frame = (struct frame_info *) baton;
struct gdbarch *gdbarch = get_frame_arch (this_frame); 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); 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 frame_info *this_frame = (struct frame_info *) baton;
struct gdbarch *gdbarch = get_frame_arch (this_frame); 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); 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; fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNSPECIFIED;
if (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\ incomplete CFI data; DW_CFA_restore unspecified\n\
register %s (#%d) at %s"), register %s (#%d) at %s"),
gdbarch_register_name gdbarch_register_name (gdbarch, regnum), regnum,
(gdbarch, gdbarch_dwarf2_reg_to_regnum (gdbarch, reg)), paddress (gdbarch, fs->pc));
gdbarch_dwarf2_reg_to_regnum (gdbarch, reg), }
paddress (gdbarch, fs->pc));
} }
/* Virtual method table for execute_stack_op below. */ /* 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: case CFA_REG_OFFSET:
{ {
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, fs.regs.cfa_reg); int regnum = dwarf_reg_to_regnum_or_error (gdbarch, fs.regs.cfa_reg);
if (regnum == -1)
error (_("Unable to access DWARF register number %d"),
(int) fs.regs.cfa_reg); /* FIXME */
*regnum_out = regnum; *regnum_out = regnum;
if (fs.armcc_cfa_offsets_reversed) if (fs.armcc_cfa_offsets_reversed)
@ -1093,7 +1091,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
entry_pc, fs); entry_pc, fs);
if (fs->regs.cfa_how == CFA_REG_OFFSET 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))) == gdbarch_sp_regnum (gdbarch)))
{ {
cache->entry_cfa_sp_offset = fs->regs.cfa_offset; 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 /* Go through the DWARF2 CFI generated table and save its register
location information in the cache. Note that we don't skip the location information in the cache. Note that we don't skip the
return address column; it's perfectly all right for it to return address column; it's perfectly all right for it to
correspond to a real register. If it doesn't correspond to a correspond to a real register. */
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). */
{ {
int column; /* CFI speak for "register number". */ int column; /* CFI speak for "register number". */
for (column = 0; column < fs->regs.num_regs; column++) for (column = 0; column < fs->regs.num_regs; column++)
{ {
/* Use the GDB register number as the destination index. */ /* 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) if (regnum < 0 || regnum >= num_regs)
continue; 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); return frame_unwind_got_memory (this_frame, regnum, addr);
case DWARF2_FRAME_REG_SAVED_REG: case DWARF2_FRAME_REG_SAVED_REG:
realnum realnum = dwarf_reg_to_regnum_or_error
= gdbarch_dwarf2_reg_to_regnum (gdbarch, cache->reg[regnum].loc.reg); (gdbarch, cache->reg[regnum].loc.reg);
return frame_unwind_got_register (this_frame, regnum, realnum); return frame_unwind_got_register (this_frame, regnum, realnum);
case DWARF2_FRAME_REG_SAVED_EXP: 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: case DWARF2_FRAME_REG_RA_OFFSET:
addr = cache->reg[regnum].loc.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); (gdbarch, cache->retaddr_reg.loc.reg);
addr += get_frame_register_unsigned (this_frame, regnum); addr += get_frame_register_unsigned (this_frame, regnum);
return frame_unwind_got_address (this_frame, regnum, addr); return frame_unwind_got_address (this_frame, regnum, addr);

View file

@ -26,6 +26,7 @@
#include "gdbcore.h" #include "gdbcore.h"
#include "dwarf2.h" #include "dwarf2.h"
#include "dwarf2expr.h" #include "dwarf2expr.h"
#include "dwarf2loc.h"
/* Local prototypes. */ /* Local prototypes. */
@ -611,7 +612,7 @@ dwarf_block_to_sp_offset (struct gdbarch *gdbarch, const gdb_byte *buf,
return 0; return 0;
} }
if (gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_reg) if (dwarf_reg_to_regnum (gdbarch, dwarf_reg)
!= gdbarch_sp_regnum (gdbarch)) != gdbarch_sp_regnum (gdbarch))
return 0; return 0;

View file

@ -32,7 +32,7 @@
#include "objfiles.h" #include "objfiles.h"
#include "block.h" #include "block.h"
#include "gdbcmd.h" #include "gdbcmd.h"
#include "complaints.h"
#include "dwarf2.h" #include "dwarf2.h"
#include "dwarf2expr.h" #include "dwarf2expr.h"
#include "dwarf2loc.h" #include "dwarf2loc.h"
@ -312,7 +312,7 @@ dwarf_expr_read_addr_from_reg (void *baton, int dwarf_regnum)
{ {
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
struct gdbarch *gdbarch = get_frame_arch (debaton->frame); struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum); int regnum = dwarf_reg_to_regnum_or_error (gdbarch, dwarf_regnum);
return address_from_register (regnum, debaton->frame); return address_from_register (regnum, debaton->frame);
} }
@ -324,7 +324,7 @@ dwarf_expr_get_reg_value (void *baton, struct type *type, int dwarf_regnum)
{ {
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
struct gdbarch *gdbarch = get_frame_arch (debaton->frame); struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum); int regnum = dwarf_reg_to_regnum_or_error (gdbarch, dwarf_regnum);
return value_from_register (type, regnum, debaton->frame); return value_from_register (type, regnum, debaton->frame);
} }
@ -1757,40 +1757,31 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
{ {
struct gdbarch *arch = get_frame_arch (frame); struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno); int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
int optim, unavail;
int reg_offset = source_offset;
if (gdb_regnum != -1) if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
&& this_size < register_size (arch, gdb_regnum))
{ {
int optim, unavail; /* Big-endian, and we want less than full size. */
int reg_offset = source_offset; reg_offset = register_size (arch, gdb_regnum) - this_size;
/* We want the lower-order THIS_SIZE_BITS of the bytes
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG we extract from the register. */
&& this_size < register_size (arch, gdb_regnum)) source_offset_bits += 8 * this_size - this_size_bits;
{
/* Big-endian, and we want less than full size. */
reg_offset = register_size (arch, gdb_regnum) - this_size;
/* We want the lower-order THIS_SIZE_BITS of the bytes
we extract from the register. */
source_offset_bits += 8 * this_size - this_size_bits;
}
if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, buffer,
&optim, &unavail))
{
/* Just so garbage doesn't ever shine through. */
memset (buffer, 0, this_size);
if (optim)
mark_value_bits_optimized_out (v, offset, this_size_bits);
if (unavail)
mark_value_bits_unavailable (v, offset, this_size_bits);
}
} }
else
if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, buffer,
&optim, &unavail))
{ {
error (_("Unable to access DWARF register number %s"), /* Just so garbage doesn't ever shine through. */
paddress (arch, p->v.regno)); memset (buffer, 0, this_size);
if (optim)
mark_value_bits_optimized_out (v, offset, this_size_bits);
if (unavail)
mark_value_bits_unavailable (v, offset, this_size_bits);
} }
} }
break; break;
@ -1949,52 +1940,43 @@ write_pieced_value (struct value *to, struct value *from)
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
{ {
struct gdbarch *arch = get_frame_arch (frame); struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno); int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
int reg_offset = dest_offset;
if (gdb_regnum != -1) if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
&& this_size <= register_size (arch, gdb_regnum))
{ {
int reg_offset = dest_offset; /* Big-endian, and we want less than full size. */
reg_offset = register_size (arch, gdb_regnum) - this_size;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
&& this_size <= register_size (arch, gdb_regnum))
{
/* Big-endian, and we want less than full size. */
reg_offset = register_size (arch, gdb_regnum) - this_size;
}
if (need_bitwise)
{
int optim, unavail;
if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, buffer,
&optim, &unavail))
{
if (optim)
throw_error (OPTIMIZED_OUT_ERROR,
_("Can't do read-modify-write to "
"update bitfield; containing word "
"has been optimized out"));
if (unavail)
throw_error (NOT_AVAILABLE_ERROR,
_("Can't do read-modify-write to update "
"bitfield; containing word "
"is unavailable"));
}
copy_bitwise (buffer, dest_offset_bits,
contents, source_offset_bits,
this_size_bits,
bits_big_endian);
}
put_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, source_buffer);
} }
else
if (need_bitwise)
{ {
error (_("Unable to write to DWARF register number %s"), int optim, unavail;
paddress (arch, p->v.regno));
if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, buffer,
&optim, &unavail))
{
if (optim)
throw_error (OPTIMIZED_OUT_ERROR,
_("Can't do read-modify-write to "
"update bitfield; containing word "
"has been optimized out"));
if (unavail)
throw_error (NOT_AVAILABLE_ERROR,
_("Can't do read-modify-write to update "
"bitfield; containing word "
"is unavailable"));
}
copy_bitwise (buffer, dest_offset_bits,
contents, source_offset_bits,
this_size_bits,
bits_big_endian);
} }
put_frame_register_bytes (frame, gdb_regnum, reg_offset,
this_size, source_buffer);
} }
break; break;
case DWARF_VALUE_MEMORY: case DWARF_VALUE_MEMORY:
@ -2335,30 +2317,27 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
struct gdbarch *arch = get_frame_arch (frame); struct gdbarch *arch = get_frame_arch (frame);
int dwarf_regnum int dwarf_regnum
= longest_to_int (value_as_long (dwarf_expr_fetch (ctx, 0))); = longest_to_int (value_as_long (dwarf_expr_fetch (ctx, 0)));
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum); int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum);
if (byte_offset != 0) if (byte_offset != 0)
error (_("cannot use offset on synthetic pointer to register")); error (_("cannot use offset on synthetic pointer to register"));
do_cleanups (value_chain); do_cleanups (value_chain);
if (gdb_regnum == -1) retval = value_from_register (type, gdb_regnum, frame);
error (_("Unable to access DWARF register number %d"), if (value_optimized_out (retval))
dwarf_regnum); {
retval = value_from_register (type, gdb_regnum, frame); struct value *tmp;
if (value_optimized_out (retval))
{
struct value *tmp;
/* This means the register has undefined value / was /* This means the register has undefined value / was
not saved. As we're computing the location of some not saved. As we're computing the location of some
variable etc. in the program, not a value for variable etc. in the program, not a value for
inspecting a register ($pc, $sp, etc.), return a inspecting a register ($pc, $sp, etc.), return a
generic optimized out value instead, so that we show generic optimized out value instead, so that we show
<optimized out> instead of <not saved>. */ <optimized out> instead of <not saved>. */
do_cleanups (value_chain); do_cleanups (value_chain);
tmp = allocate_value (type); tmp = allocate_value (type);
value_contents_copy (tmp, 0, retval, 0, TYPE_LENGTH (type)); value_contents_copy (tmp, 0, retval, 0, TYPE_LENGTH (type));
retval = tmp; retval = tmp;
} }
} }
break; break;
@ -2858,14 +2837,54 @@ unimplemented (unsigned int op)
op); op);
} }
/* See dwarf2loc.h.
This is basically a wrapper on gdbarch_dwarf2_reg_to_regnum so that we
can issue a complaint, which is better than having every target's
implementation of dwarf2_reg_to_regnum do it. */
int
dwarf_reg_to_regnum (struct gdbarch *arch, int dwarf_reg)
{
int reg = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_reg);
if (reg == -1)
{
complaint (&symfile_complaints,
_("bad DWARF register number %d"), dwarf_reg);
}
return reg;
}
/* Subroutine of dwarf_reg_to_regnum_or_error to simplify it.
Throw an error because DWARF_REG is bad. */
static void
throw_bad_regnum_error (ULONGEST dwarf_reg)
{
/* Still want to print -1 as "-1".
We *could* have int and ULONGEST versions of dwarf2_reg_to_regnum_or_error
but that's overkill for now. */
if ((int) dwarf_reg == dwarf_reg)
error (_("Unable to access DWARF register number %d"), (int) dwarf_reg);
error (_("Unable to access DWARF register number %s"),
pulongest (dwarf_reg));
}
/* See dwarf2loc.h. */ /* See dwarf2loc.h. */
int int
dwarf2_reg_to_regnum_or_error (struct gdbarch *arch, int dwarf_reg) dwarf_reg_to_regnum_or_error (struct gdbarch *arch, ULONGEST dwarf_reg)
{ {
int reg = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_reg); int reg;
if (dwarf_reg > INT_MAX)
throw_bad_regnum_error (dwarf_reg);
/* Yes, we will end up issuing a complaint and an error if DWARF_REG is
bad, but that's ok. */
reg = dwarf_reg_to_regnum (arch, (int) dwarf_reg);
if (reg == -1) if (reg == -1)
error (_("Unable to access DWARF register number %d"), dwarf_reg); throw_bad_regnum_error (dwarf_reg);
return reg; return reg;
} }
@ -3112,14 +3131,14 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
case DW_OP_reg30: case DW_OP_reg30:
case DW_OP_reg31: case DW_OP_reg31:
dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
loc->u.reg = dwarf2_reg_to_regnum_or_error (arch, op - DW_OP_reg0); loc->u.reg = dwarf_reg_to_regnum_or_error (arch, op - DW_OP_reg0);
loc->kind = axs_lvalue_register; loc->kind = axs_lvalue_register;
break; break;
case DW_OP_regx: case DW_OP_regx:
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg); op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx"); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
loc->u.reg = dwarf2_reg_to_regnum_or_error (arch, reg); loc->u.reg = dwarf_reg_to_regnum_or_error (arch, reg);
loc->kind = axs_lvalue_register; loc->kind = axs_lvalue_register;
break; break;
@ -3182,7 +3201,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
case DW_OP_breg30: case DW_OP_breg30:
case DW_OP_breg31: case DW_OP_breg31:
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
i = dwarf2_reg_to_regnum_or_error (arch, op - DW_OP_breg0); i = dwarf_reg_to_regnum_or_error (arch, op - DW_OP_breg0);
ax_reg (expr, i); ax_reg (expr, i);
if (offset != 0) if (offset != 0)
{ {
@ -3194,7 +3213,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
{ {
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg); op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
i = dwarf2_reg_to_regnum_or_error (arch, reg); i = dwarf_reg_to_regnum_or_error (arch, reg);
ax_reg (expr, i); ax_reg (expr, i);
if (offset != 0) if (offset != 0)
{ {
@ -3659,7 +3678,17 @@ locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum)
{ {
int regnum; int regnum;
regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum); /* This doesn't use dwarf_reg_to_regnum_or_error on purpose.
We'd rather print *something* here than throw an error. */
regnum = dwarf_reg_to_regnum (gdbarch, dwarf_regnum);
/* gdbarch_register_name may just return "", return something more
descriptive for bad register numbers. */
if (regnum == -1)
{
/* The text is output as "$bad_register_number".
That is why we use the underscores. */
return _("bad_register_number");
}
return gdbarch_register_name (gdbarch, regnum); return gdbarch_register_name (gdbarch, regnum);
} }

View file

@ -293,9 +293,18 @@ extern struct call_site_chain *call_site_find_chain (struct gdbarch *gdbarch,
/* A helper function to convert a DWARF register to an arch register. /* A helper function to convert a DWARF register to an arch register.
ARCH is the architecture. ARCH is the architecture.
DWARF_REG is the register. DWARF_REG is the register.
This will throw an exception if the DWARF register cannot be If DWARF_REG is bad then a complaint is issued and -1 is returned.
translated to an architecture register. */ Note: Some targets get this wrong. */
extern int dwarf2_reg_to_regnum_or_error (struct gdbarch *arch, int dwarf_reg); extern int dwarf_reg_to_regnum (struct gdbarch *arch, int dwarf_reg);
/* A wrapper on dwarf_reg_to_regnum to throw an exception if the
DWARF register cannot be translated to an architecture register.
This takes a ULONGEST instead of an int because some callers actually have
a ULONGEST. Negative values passed as ints will still be flagged as
invalid. */
extern int dwarf_reg_to_regnum_or_error (struct gdbarch *arch,
ULONGEST dwarf_reg);
#endif /* dwarf2loc.h */ #endif /* dwarf2loc.h */

View file

@ -334,7 +334,8 @@ typedef int (gdbarch_sdb_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int sdb_
extern int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr); extern int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr);
extern void set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum); extern void set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum);
/* Provide a default mapping from a DWARF2 register number to a gdb REGNUM. */ /* Provide a default mapping from a DWARF2 register number to a gdb REGNUM.
Return -1 for bad REGNUM. Note: Several targets get this wrong. */
typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int dwarf2_regnr); typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int dwarf2_regnr);
extern int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr); extern int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr);

View file

@ -461,6 +461,7 @@ m:int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr::no_op_reg_to_regnum::0
# Convert from an sdb register number to an internal gdb register number. # Convert from an sdb register number to an internal gdb register number.
m:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr::no_op_reg_to_regnum::0 m:int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr::no_op_reg_to_regnum::0
# Provide a default mapping from a DWARF2 register number to a gdb REGNUM. # Provide a default mapping from a DWARF2 register number to a gdb REGNUM.
# Return -1 for bad REGNUM. Note: Several targets get this wrong.
m:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr::no_op_reg_to_regnum::0 m:int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr::no_op_reg_to_regnum::0
m:const char *:register_name:int regnr:regnr::0 m:const char *:register_name:int regnr:regnr::0

View file

@ -39,14 +39,13 @@ static int
hppa_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) hppa_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
/* The general registers and the sar are the same in both sets. */ /* The general registers and the sar are the same in both sets. */
if (reg <= 32) if (reg >= 0 && reg <= 32)
return reg; return reg;
/* fr4-fr31 (left and right halves) are mapped from 72. */ /* fr4-fr31 (left and right halves) are mapped from 72. */
if (reg >= 72 && reg <= 72 + 28 * 2) if (reg >= 72 && reg <= 72 + 28 * 2)
return HPPA_FP4_REGNUM + (reg - 72); return HPPA_FP4_REGNUM + (reg - 72);
warning (_("Unmapped DWARF DBX Register #%d encountered."), reg);
return -1; return -1;
} }

View file

@ -696,14 +696,13 @@ static int
hppa64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) hppa64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
/* The general registers and the sar are the same in both sets. */ /* The general registers and the sar are the same in both sets. */
if (reg <= 32) if (reg >= 0 && reg <= 32)
return reg; return reg;
/* fr4-fr31 are mapped from 72 in steps of 2. */ /* fr4-fr31 are mapped from 72 in steps of 2. */
if (reg >= 72 && reg < 72 + 28 * 2 && !(reg & 1)) if (reg >= 72 && reg < 72 + 28 * 2 && !(reg & 1))
return HPPA64_FP4_REGNUM + (reg - 72) / 2; return HPPA64_FP4_REGNUM + (reg - 72) / 2;
warning (_("Unmapped DWARF DBX Register #%d encountered."), reg);
return -1; return -1;
} }

View file

@ -502,11 +502,11 @@ i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
} }
/* Convert SVR4 register number REG to the appropriate register number /* Convert SVR4 DWARF register number REG to the appropriate register number
used by GDB. */ used by GDB. */
static int static int
i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg) i386_svr4_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@ -544,8 +544,20 @@ i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
case 45: return I386_GS_REGNUM; case 45: return I386_GS_REGNUM;
} }
/* This will hopefully provoke a warning. */ return -1;
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); }
/* Wrapper on i386_svr4_dwarf_reg_to_regnum to return
num_regs + num_pseudo_regs for other debug formats. */
static int
i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
int regnum = i386_svr4_dwarf_reg_to_regnum (gdbarch, reg);
if (regnum == -1)
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
return regnum;
} }
@ -8349,7 +8361,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_dbx_reg_to_regnum); set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_dbx_reg_to_regnum);
/* Use the SVR4 register numbering scheme for DWARF 2. */ /* Use the SVR4 register numbering scheme for DWARF 2. */
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_dwarf_reg_to_regnum);
/* We don't set gdbarch_stab_reg_to_regnum, since ECOFF doesn't seem to /* We don't set gdbarch_stab_reg_to_regnum, since ECOFF doesn't seem to
be in use on any of the supported i386 targets. */ be in use on any of the supported i386 targets. */

View file

@ -573,7 +573,7 @@ m68k_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num)
/* pc */ /* pc */
return M68K_PC_REGNUM; return M68K_PC_REGNUM;
else else
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); return -1;
} }

View file

@ -521,6 +521,14 @@ add_pending (FDR *fh, char *sh, struct type *t)
/* Parsing Routines proper. */ /* Parsing Routines proper. */
static void
reg_value_complaint (int regnum, int num_regs, const char *sym)
{
complaint (&symfile_complaints,
_("bad register number %d (max %d) in symbol %s"),
regnum, num_regs - 1, sym);
}
/* Parse a single symbol. Mostly just make up a GDB symbol for it. /* Parse a single symbol. Mostly just make up a GDB symbol for it.
For blocks, procedures and types we open a new lexical context. For blocks, procedures and types we open a new lexical context.
This is basically just a big switch on the symbol's type. Argument This is basically just a big switch on the symbol's type. Argument
@ -533,7 +541,21 @@ add_pending (FDR *fh, char *sh, struct type *t)
static int static int
mdebug_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch) mdebug_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
{ {
return gdbarch_ecoff_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym)); int regno = gdbarch_ecoff_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
if (regno < 0
|| regno >= (gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch)))
{
reg_value_complaint (regno,
gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch),
SYMBOL_PRINT_NAME (sym));
regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless. */
}
return regno;
} }
static const struct symbol_register_ops mdebug_register_funcs = { static const struct symbol_register_ops mdebug_register_funcs = {

View file

@ -784,7 +784,9 @@ static int
mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg) mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg)
{ {
/* The debug info uses the raw register numbers. */ /* The debug info uses the raw register numbers. */
return mep_raw_to_pseudo[debug_reg]; if (debug_reg >= 0 && debug_reg < ARRAY_SIZE (mep_raw_to_pseudo))
return mep_raw_to_pseudo[debug_reg];
return -1;
} }

View file

@ -638,8 +638,9 @@ static int dwarf2_to_reg_map[78] =
static int static int
microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
gdb_assert ((size_t) reg < sizeof (dwarf2_to_reg_map)); if (reg >= 0 && reg < sizeof (dwarf2_to_reg_map))
return dwarf2_to_reg_map[reg]; return dwarf2_to_reg_map[reg];
return -1;
} }
static void static void

View file

@ -8024,9 +8024,7 @@ mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78)
regnum = num + mips_regnum (gdbarch)->dspacc - 72; regnum = num + mips_regnum (gdbarch)->dspacc - 72;
else else
/* This will hopefully (eventually) provoke a warning. Should return -1;
we be calling complaint() here? */
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
return gdbarch_num_regs (gdbarch) + regnum; return gdbarch_num_regs (gdbarch) + regnum;
} }
@ -8049,9 +8047,7 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num)
else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72)
regnum = num + mips_regnum (gdbarch)->dspacc - 66; regnum = num + mips_regnum (gdbarch)->dspacc - 66;
else else
/* This will hopefully (eventually) provoke a warning. Should we return -1;
be calling complaint() here? */
return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
return gdbarch_num_regs (gdbarch) + regnum; return gdbarch_num_regs (gdbarch) + regnum;
} }

View file

@ -1385,10 +1385,7 @@ mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2)
if (dwarf2 < 0 if (dwarf2 < 0
|| dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb)) || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb))
{ return -1;
warning (_("Bogus register number in debug info: %d"), dwarf2);
return -1;
}
return dwarf2_to_gdb[dwarf2]; return dwarf2_to_gdb[dwarf2];
} }

View file

@ -583,13 +583,9 @@ static const struct frame_unwind msp430_unwind = {
static int static int
msp430_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) msp430_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{ {
if (reg < MSP430_NUM_REGS) if (reg >= 0 && reg < MSP430_NUM_REGS)
return reg + MSP430_NUM_REGS; return reg + MSP430_NUM_REGS;
else return -1;
{
warning (_("Unmapped DWARF Register #%d encountered."), reg);
return -1;
}
} }
/* Implement the "return_value" gdbarch method. */ /* Implement the "return_value" gdbarch method. */

View file

@ -138,17 +138,15 @@ static int nios2_dwarf2gdb_regno_map[] =
NIOS2_MPUACC_REGNUM /* 48 */ NIOS2_MPUACC_REGNUM /* 48 */
}; };
gdb_static_assert (ARRAY_SIZE (nios2_dwarf2gdb_regno_map) == NIOS2_NUM_REGS);
/* Implement the dwarf2_reg_to_regnum gdbarch method. */ /* Implement the dwarf2_reg_to_regnum gdbarch method. */
static int static int
nios2_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dw_reg) nios2_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dw_reg)
{ {
if (dw_reg < 0 || dw_reg > NIOS2_NUM_REGS) if (dw_reg < 0 || dw_reg >= NIOS2_NUM_REGS)
{ return -1;
warning (_("Dwarf-2 uses unmapped register #%d"), dw_reg);
return dw_reg;
}
return nios2_dwarf2gdb_regno_map[dw_reg]; return nios2_dwarf2gdb_regno_map[dw_reg];
} }

View file

@ -1217,9 +1217,7 @@ rl78_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
else if (reg == 37) else if (reg == 37)
return RL78_PC_REGNUM; return RL78_PC_REGNUM;
else else
internal_error (__FILE__, __LINE__, return -1;
_("Undefined dwarf2 register mapping of reg %d"),
reg);
} }
/* Implement the `register_sim_regno' gdbarch method. */ /* Implement the `register_sim_regno' gdbarch method. */

View file

@ -1011,9 +1011,7 @@ rx_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
else if (reg == 17) else if (reg == 17)
return RX_PC_REGNUM; return RX_PC_REGNUM;
else else
internal_error (__FILE__, __LINE__, return -1;
_("Undefined dwarf2 register mapping of reg %d"),
reg);
} }
/* Allocate and initialize a gdbarch object. */ /* Allocate and initialize a gdbarch object. */

View file

@ -169,7 +169,7 @@ static void
reg_value_complaint (int regnum, int num_regs, const char *sym) reg_value_complaint (int regnum, int num_regs, const char *sym)
{ {
complaint (&symfile_complaints, complaint (&symfile_complaints,
_("register number %d too large (max %d) in symbol %s"), _("bad register number %d (max %d) in symbol %s"),
regnum, num_regs - 1, sym); regnum, num_regs - 1, sym);
} }
@ -597,8 +597,9 @@ stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
{ {
int regno = gdbarch_stab_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym)); int regno = gdbarch_stab_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym));
if (regno >= gdbarch_num_regs (gdbarch) if (regno < 0
+ gdbarch_num_pseudo_regs (gdbarch)) || regno >= (gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch)))
{ {
reg_value_complaint (regno, reg_value_complaint (regno,
gdbarch_num_regs (gdbarch) gdbarch_num_regs (gdbarch)

View file

@ -1,3 +1,10 @@
2015-10-26 Doug Evans <dje@google.com>
PR symtab/17391
* lib/dwarf.exp (_location): Add support for DW_OP_regx.
* gdb.dwarf2/bad-regnum.c: New file.
* gdb.dwarf2/bad-regnum.exp: New file.
2015-10-26 Doug Evans <dje@google.com> 2015-10-26 Doug Evans <dje@google.com>
PR python/18938 PR python/18938

View file

@ -0,0 +1,22 @@
/* Copyright 2015 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
int
main ()
{
return 0;
}

View file

@ -0,0 +1,76 @@
# Copyright 2015 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
load_lib dwarf.exp
# This test can only be run on targets which support DWARF-2 and use gas.
if {![dwarf2_support]} {
return 0
}
standard_testfile bad-regnum.c bad-regnum-dw.S
# Make some DWARF for the test.
set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
cu {} {
DW_TAG_compile_unit {
{DW_AT_language @DW_LANG_C}
{DW_AT_name bad-regnum-dw.c}
{DW_AT_comp_dir /tmp}
} {
declare_labels integer_label
integer_label: DW_TAG_base_type {
{DW_AT_byte_size 4 DW_FORM_sdata}
{DW_AT_encoding @DW_ATE_signed}
{DW_AT_name integer}
}
DW_TAG_variable {
{DW_AT_name foo1}
{DW_AT_type :$integer_label}
{DW_AT_location {
DW_OP_regx 2147483647
} SPECIAL_expr}
{external 1 flag}
}
DW_TAG_variable {
{DW_AT_name foo2}
{DW_AT_type :$integer_label}
{DW_AT_location {
DW_OP_regx -1
} SPECIAL_expr}
{external 1 flag}
}
}
}
}
if { [prepare_for_testing ${testfile}.exp ${testfile} \
[list $srcfile $asm_file] {nodebug}] } {
return -1
}
if ![runto_main] {
return -1
}
gdb_test "info addr foo1" \
"Symbol \"foo1\" is a variable in \\\$bad_register_number."
gdb_test "info addr foo2" \
"Symbol \"foo2\" is a variable in \\\$bad_register_number."

View file

@ -836,6 +836,10 @@ namespace eval Dwarf {
_op .${_cu_addr_size}byte [lindex $line 1] _op .${_cu_addr_size}byte [lindex $line 1]
} }
DW_OP_regx {
_op .uleb128 [lindex $line 1]
}
DW_OP_pick - DW_OP_pick -
DW_OP_const1u - DW_OP_const1u -
DW_OP_const1s { DW_OP_const1s {

View file

@ -356,9 +356,7 @@ xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number) if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number)
return i; return i;
internal_error (__FILE__, __LINE__, return -1;
_("invalid dwarf/stabs register number %d"), regnum);
return 0;
} }