aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/mips-tdep.c43
-rw-r--r--gdb/mipsread.c31
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 */