diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 43 | ||||
-rw-r--r-- | gdb/mipsread.c | 31 |
3 files changed, 64 insertions, 17 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9c4f124..1f00f54 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +Fri Apr 16 12:27:11 1993 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + * mips-tdep.c (mips_skip_prologue): Always skip the typical prologue + instructions and nothing more. + * mipsread.c (add_line): Add comment why we have to combine line number + entries for the same line number. + Fri Apr 16 09:42:03 1993 Jim Kingdon (kingdon@cygnus.com) * symtab.{c,h}: Doc fixes (remove symseg references, last relevant diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index d68fbc29..14267fa 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -87,17 +87,18 @@ read_next_frame_reg(fi, regno) FRAME fi; int regno; { -#define SIGFRAME_BASE sizeof(struct sigcontext) -#define SIGFRAME_PC_OFF (-SIGFRAME_BASE+ 2*sizeof(int)) -#define SIGFRAME_SP_OFF (-SIGFRAME_BASE+32*sizeof(int)) -#define SIGFRAME_RA_OFF (-SIGFRAME_BASE+34*sizeof(int)) + /* If it is the frame for sigtramp we have a complete sigcontext + immediately below the frame and we get the saved registers from there. + If the stack layout for sigtramp changes we might have to change these + constants and the companion fixup_sigtramp in mipsread.c */ +#define SIGFRAME_BASE 0x12c /* sizeof(sigcontext) */ +#define SIGFRAME_PC_OFF (-SIGFRAME_BASE + 2 * 4) +#define SIGFRAME_REGSAVE_OFF (-SIGFRAME_BASE + 3 * 4) for (; fi; fi = fi->next) if (in_sigtramp(fi->pc, 0)) { - /* No idea if this code works. --PB. */ int offset; if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF; - else if (regno == RA_REGNUM) offset = SIGFRAME_RA_OFF; - else if (regno == SP_REGNUM) offset = SIGFRAME_SP_OFF; + else if (regno < 32) offset = SIGFRAME_REGSAVE_OFF + regno * 4; else return 0; return read_memory_integer(fi->frame + offset, 4); } @@ -728,19 +729,32 @@ mips_skip_prologue(pc) int offset; int seen_sp_adjust = 0; - /* For -g modules and most functions anyways the - first instruction adjusts the stack. - But we allow some number of stores before the stack adjustment. - (These are emitted by varags functions compiled by gcc-2.0. */ + /* Skip the typical prologue instructions. These are the stack adjustment + instruction and the instructions that save registers on the stack + or in the gcc frame. */ for (offset = 0; offset < 100; offset += 4) { inst = read_memory_integer(pc + offset, 4); - if ((inst & 0xffff0000) == 0x27bd0000) /* addiu $sp,$sp,offset */ + if ((inst & 0xffff0000) == 0x27bd0000) /* addiu $sp,$sp,offset */ seen_sp_adjust = 1; - else if ((inst & 0xFFE00000) == 0xAFA00000) /* sw reg,n($sp) */ + else if ((inst & 0xFFE00000) == 0xAFA00000 && (inst & 0x001F0000)) + continue; /* sw reg,n($sp) */ + /* reg != $zero */ + else if ((inst & 0xFFE00000) == 0xE7A00000) /* swc1 freg,n($sp) */ + continue; + else if ((inst & 0xF3E00000) == 0xA3C00000 && (inst & 0x001F0000)) + /* sx reg,n($s8) */ + continue; /* reg != $zero */ + else if (inst == 0x03A0F021) /* move $s8,$sp */ continue; else - break; + break; } + return pc + offset; + +/* FIXME schauer. The following code seems no longer necessary if we + always skip the typical prologue instructions. */ + +#if 0 if (seen_sp_adjust) return pc + offset; @@ -764,6 +778,7 @@ mips_skip_prologue(pc) return pc + 4; return pc; +#endif } /* Let the user turn off floating point. */ diff --git a/gdb/mipsread.c b/gdb/mipsread.c index b6523e1..4f0558b 100644 --- a/gdb/mipsread.c +++ b/gdb/mipsread.c @@ -180,6 +180,9 @@ struct complaint pdr_for_nonsymbol_complaint = struct complaint pdr_static_symbol_complaint = {"can't handle PDR for static proc at 0x%x", 0, 0}; +struct complaint bad_setjmp_pdr_complaint = +{"fixing bad setjmp PDR from libc", 0, 0}; + /* Macros and extra defs */ /* Already-parsed symbols are marked specially */ @@ -1583,6 +1586,16 @@ parse_procedure (pr, have_stabs, first_off) e->pdr = *pr; e->pdr.isym = (long) s; e->pdr.adr += cur_fdr->adr - first_off; + + /* Correct incorrect setjmp procedure descriptor from the library + to make backtrace through setjmp work. */ + if (e->pdr.pcreg == 0 && strcmp (sh_name, "setjmp") == 0) + { + complain (&bad_setjmp_pdr_complaint, 0); + e->pdr.pcreg = RA_REGNUM; + e->pdr.regmask = 0x80000000; + e->pdr.regoffset = -4; + } } } @@ -2824,7 +2837,18 @@ add_block (b, s) /* Add a new linenumber entry (LINENO,ADR) to a linevector LT. MIPS' linenumber encoding might need more than one byte - to describe it, LAST is used to detect these continuation lines */ + to describe it, LAST is used to detect these continuation lines. + + Combining lines with the same line number seems like a bad idea. + E.g: There could be a line number entry with the same line number after the + prologue and GDB should not ignore it (this is a better way to find + a prologue than mips_skip_prologue). + But due to the compressed line table format there are line number entries + for the same line which are needed to bridge the gap to the next + line number entry. These entries have a bogus address info with them + and we are unable to tell them from intended duplicate line number + entries. + This is another reason why -ggdb debugging format is preferable. */ static int add_line (lt, lineno, adr, last) @@ -3170,11 +3194,12 @@ fixup_sigtramp () /* align_longword(sigcontext + SIGFRAME) */ e->pdr.frameoffset = 0x150; e->pdr.framereg = SP_REGNUM; - e->pdr.pcreg = 31; + /* read_next_frame_reg provides the true pc at the time of signal */ + e->pdr.pcreg = PC_REGNUM; e->pdr.regmask = -2; e->pdr.regoffset = -(41 * sizeof (int)); e->pdr.fregmask = -1; - e->pdr.fregoffset = -(37 * sizeof (int)); + e->pdr.fregoffset = -(7 * sizeof (int)); e->pdr.isym = (long) s; current_objfile = st->objfile; /* Keep new_symbol happy */ |