Message ID | 001a113308e8dafbc3051d8af62f@google.com |
---|---|
State | New |
Headers | show |
On 08/18/2015 01:26 AM, Doug Evans wrote: > > More like for those I left it wasn't clear to me how to fix them. > > e.g., rs6000-tdep.c:rs6000_dwarf2_reg_to_regnum. > > I'm certainly not making things worse by leaving them alone. > > OK. Neither rs6000 spu look like cases that returns num_regs + num_pseudo_regs for bad registers, as suggested here, though: + /* If there's no corresponding GDB register, ignore it. + Some targets return num_regs (+ num_pseudo_regs) for bad registers. + Handle them until they are fixed. */ if (regnum < 0 || regnum >= num_regs) continue; IMO, as written, this is the sort of comment that ends up staying stale forever even after all such targets stop returning num_regs+num_pseudo_regs specifically (they may still return bogus register numbers higher than that). After your supplemental patch, I think we can just drop it or say "Protect against a target returning a bad register" or some such? > I missed a few obvious cases. > The main remaining cases that I can think of are rs6000 and spu. > Plus this supplemental patch makes stabs and ecoff more robust. > Stabs was using num_arch + num_pseudo to denote "bad reg", > but some targets use the same reg_to_regnum function for both > stabs and dwarf, so that's asking for trouble (since dwarf uses -1). > This patch makes stabs handle negative regnos too. > > If it's too hard to review this apart from the original patch > I can resubmit the entire thing. Looks good to me. Thanks, Pedro Alves
On Tue, Aug 18, 2015 at 4:48 AM, Pedro Alves <palves@redhat.com> wrote: > On 08/18/2015 01:26 AM, Doug Evans wrote: > >> > More like for those I left it wasn't clear to me how to fix them. >> > e.g., rs6000-tdep.c:rs6000_dwarf2_reg_to_regnum. >> > I'm certainly not making things worse by leaving them alone. >> > > > OK. Neither rs6000 spu look like cases that > returns num_regs + num_pseudo_regs for bad registers, as suggested > here, though: > > + /* If there's no corresponding GDB register, ignore it. > + Some targets return num_regs (+ num_pseudo_regs) for bad registers. > + Handle them until they are fixed. */ > if (regnum < 0 || regnum >= num_regs) > continue; > > IMO, as written, this is the sort of comment that ends up staying > stale forever even after all such targets stop returning num_regs+num_pseudo_regs > specifically (they may still return bogus register numbers higher > than that). After your supplemental patch, I think we can just drop it > or say "Protect against a target returning a bad register" or some such? > >> I missed a few obvious cases. >> The main remaining cases that I can think of are rs6000 and spu. >> Plus this supplemental patch makes stabs and ecoff more robust. >> Stabs was using num_arch + num_pseudo to denote "bad reg", >> but some targets use the same reg_to_regnum function for both >> stabs and dwarf, so that's asking for trouble (since dwarf uses -1). >> This patch makes stabs handle negative regnos too. >> >> If it's too hard to review this apart from the original patch >> I can resubmit the entire thing. > > Looks good to me. Committed with the suggested change. Thanks.
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index d7347b6..5a3ed95 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -573,7 +573,7 @@ m68k_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num) /* pc */ return M68K_PC_REGNUM; else - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; } diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 3a81615..90f1f51 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -521,6 +521,14 @@ add_pending (FDR *fh, char *sh, struct type *t) /* 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. For blocks, procedures and types we open a new lexical context. 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 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 = { diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c index d2831db..7ab4928 100644 --- a/gdb/mep-tdep.c +++ b/gdb/mep-tdep.c @@ -784,7 +784,9 @@ static int mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg) { /* 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; } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index e0706db..4bf0d99 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8020,9 +8020,7 @@ mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78) regnum = num + mips_regnum (gdbarch)->dspacc - 72; else - /* This will hopefully (eventually) provoke a warning. Should - we be calling complaint() here? */ - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; return gdbarch_num_regs (gdbarch) + regnum; } @@ -8045,9 +8043,7 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72) regnum = num + mips_regnum (gdbarch)->dspacc - 66; else - /* This will hopefully (eventually) provoke a warning. Should we - be calling complaint() here? */ - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; return gdbarch_num_regs (gdbarch) + regnum; } diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 985821c..83a3e48 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1383,10 +1383,7 @@ mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2) if (dwarf2 < 0 || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb)) - { - warning (_("Bogus register number in debug info: %d"), dwarf2); - return -1; - } + return -1; return dwarf2_to_gdb[dwarf2]; } diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 03c9eb1..f6d8343 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -169,7 +169,7 @@ static void reg_value_complaint (int regnum, int num_regs, const char *sym) { 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); } @@ -598,8 +598,9 @@ stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch) { int regno = gdbarch_stab_reg_to_regnum (gdbarch, SYMBOL_VALUE (sym)); - if (regno >= gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch)) + if (regno < 0 + || regno >= (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch))) { reg_value_complaint (regno, gdbarch_num_regs (gdbarch) diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index 55e7d98..6c60070 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -354,9 +354,7 @@ xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum) if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number) return i; - internal_error (__FILE__, __LINE__, - _("invalid dwarf/stabs register number %d"), regnum); - return 0; + return -1; }