aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r--gdb/mips-tdep.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 7c95a4f..427e0f6 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -44,6 +44,15 @@ extern struct obstack frame_cache_obstack;
static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
#endif
+static void mips_print_register PARAMS ((int, int));
+
+static mips_extra_func_info_t
+heuristic_proc_desc PARAMS ((CORE_ADDR, CORE_ADDR, struct frame_info *));
+
+static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));
+
+static int read_next_frame_reg PARAMS ((struct frame_info *, int));
+
static void mips_set_fpu_command PARAMS ((char *, int,
struct cmd_list_element *));
@@ -59,6 +68,12 @@ static void mips_show_processor_type_command PARAMS ((char *, int));
static void reinit_frame_cache_sfunc PARAMS ((char *, int,
struct cmd_list_element *));
+static mips_extra_func_info_t
+ find_proc_desc PARAMS ((CORE_ADDR pc, struct frame_info *next_frame));
+
+static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
+ mips_extra_func_info_t proc_desc));
+
/* This value is the model of MIPS in use. It is derived from the value
of the PrID register. */
@@ -186,6 +201,44 @@ struct linked_proc_info
} *linked_proc_desc_table = NULL;
+
+/* This returns the PC of the first inst after the prologue. If we can't
+ find the prologue, then return 0. */
+
+static CORE_ADDR
+after_prologue (pc, proc_desc)
+ CORE_ADDR pc;
+ mips_extra_func_info_t proc_desc;
+{
+ struct symtab_and_line sal;
+ CORE_ADDR func_addr, func_end;
+
+ if (!proc_desc)
+ proc_desc = find_proc_desc (pc, NULL);
+
+ if (proc_desc)
+ {
+ /* If function is frameless, then we need to do it the hard way. I
+ strongly suspect that frameless always means prologueless... */
+ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
+ && PROC_FRAME_OFFSET (proc_desc) == 0)
+ return 0;
+ }
+
+ if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+ return 0; /* Unknown */
+
+ sal = find_pc_line (func_addr, 0);
+
+ if (sal.end < func_end)
+ return sal.end;
+
+ /* The line after the prologue is after the end of the function. In this
+ case, tell the caller to find the prologue the hard way. */
+
+ return 0;
+}
+
/* Guaranteed to set fci->saved_regs to some values (it never leaves it
NULL). */
@@ -258,6 +311,11 @@ mips_find_saved_regs (fci)
/* In a dummy frame we know exactly where things are saved. */
&& !PROC_DESC_IS_DUMMY (proc_desc)
+ /* Don't bother unless we are inside a function prologue. Outside the
+ prologue, we know where everything is. */
+
+ && in_prologue (fci->pc, PROC_LOW_ADDR (proc_desc))
+
/* Not sure exactly what kernel_trap means, but if it means
the kernel saves the registers without a prologue doing it,
we better not examine the prologue to see whether registers
@@ -1129,6 +1187,19 @@ mips_skip_prologue (pc, lenient)
int offset;
int seen_sp_adjust = 0;
int load_immediate_bytes = 0;
+ CORE_ADDR post_prologue_pc;
+
+ /* See if we can determine the end of the prologue via the symbol table.
+ If so, then return either PC, or the PC after the prologue, whichever
+ is greater. */
+
+ post_prologue_pc = after_prologue (pc, NULL);
+
+ if (post_prologue_pc != 0)
+ return max (pc, post_prologue_pc);
+
+ /* Can't determine prologue from the symbol table, need to examine
+ instructions. */
/* Skip the typical prologue instructions. These are the stack adjustment
instruction and the instructions that save registers on the stack
@@ -1284,10 +1355,6 @@ mips_store_return_value (valtype, valbuf)
write_register_bytes(REGISTER_BYTE (regnum), raw_buffer, TYPE_LENGTH (valtype));
}
-/* These exist in mdebugread.c. */
-extern CORE_ADDR sigtramp_address, sigtramp_end;
-extern void fixup_sigtramp PARAMS ((void));
-
/* Exported procedure: Is PC in the signal trampoline code */
int