diff options
-rw-r--r-- | gdb/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 69 |
2 files changed, 71 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 21a7720..368d960 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,9 @@ 2003-11-22 Andrew Cagney <cagney@redhat.com> + * mips-tdep.c (skip_prologue_using_sal): New function. + (mips32_skip_prologue, mips16_skip_prologue): Use + skip_prologue_using_sal to get an upper bound on the search. + * config/powerpc/tm-linux.h (PROLOGUE_FIRSTLINE_OVERLAP): Delete #if 0'ed macro. * infrun.c (step_into_function): Delete #ifdef diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 720c0ce..3ba9e28 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -4307,6 +4307,61 @@ mips_step_skips_delay (CORE_ADDR pc) } +/* Given PC at the function's start address, attempt to find the + prologue end using SAL information. Return zero if the skip fails. + + A non-optimized prologue traditionally has one SAL for the function + and a second for the function body. A single line function has + them both pointing at the same line. + + An optimized prologue is similar but the prologue may contain + instructions (SALs) from the instruction body. Need to skip those + while not getting into the function body. + + The functions end point and an increasing SAL line are used as + indicators of the prologue's endpoint. + + This code is based on the function refine_prologue_limit (versions + found in both ia64 and ppc). */ + +static CORE_ADDR +skip_prologue_using_sal (CORE_ADDR func_addr) +{ + struct symtab_and_line prologue_sal; + CORE_ADDR start_pc; + CORE_ADDR end_pc; + + /* Get an initial range for the function. */ + find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc); + start_pc += FUNCTION_START_OFFSET; + + prologue_sal = find_pc_line (start_pc, 0); + if (prologue_sal.line != 0) + { + while (prologue_sal.end < end_pc) + { + struct symtab_and_line sal; + + sal = find_pc_line (prologue_sal.end, 0); + if (sal.line == 0) + break; + /* Assume that a consecutive SAL for the same (or larger) + line mark the prologue -> body transition. */ + if (sal.line >= prologue_sal.line) + break; + /* The case in which compiler's optimizer/scheduler has + moved instructions into the prologue. We look ahead in + the function looking for address ranges whose + corresponding line number is less the first one that we + found for the function. This is more conservative then + refine_prologue_limit which scans a large number of SALs + looking for any in the prologue */ + prologue_sal = sal; + } + } + return prologue_sal.end; +} + /* Skip the PC past function prologue instructions (32-bit version). This is a helper function for mips_skip_prologue. */ @@ -4318,10 +4373,15 @@ mips32_skip_prologue (CORE_ADDR pc) int seen_sp_adjust = 0; int load_immediate_bytes = 0; + /* Find an upper bound on the prologue. */ + end_pc = skip_prologue_using_sal (pc); + if (end_pc == 0) + end_pc = pc + 100; /* Magic. */ + /* 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 (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN) + for (; pc < end_pc; pc += MIPS_INSTLEN) { unsigned long high_word; @@ -4463,10 +4523,15 @@ mips16_skip_prologue (CORE_ADDR pc) } /* end of table marker */ }; + /* Find an upper bound on the prologue. */ + end_pc = skip_prologue_using_sal (pc); + if (end_pc == 0) + end_pc = pc + 100; /* Magic. */ + /* 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 (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN) + for (; pc < end_pc; pc += MIPS16_INSTLEN) { unsigned short inst; int i; |