From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [PATCH] [SH] Prologue skipping if there is none
Date: Wed, 15 Feb 2012 16:09:00 -0000 [thread overview]
Message-ID: <20120215075413.1313f7fa@mesquite.lan> (raw)
In-Reply-To: <87pqdgciho.fsf@schwinge.name>
On Wed, 15 Feb 2012 14:51:31 +0100
Thomas Schwinge <thomas@codesourcery.com> wrote:
> The prologue skipping issue is that GDB fails to place breakpoints
> correctly at the beginning of a function -- such as for ``break main'' --
> for the case that there is no prologue in that function.
Hi Thomas,
I've been sitting on a patch which is similar to what you just posted,
though I think it might provide more accurate results in some instances.
Would you mind checking to see if it solves your problem?
* sh-tdep.c (sh_analyze_prologue): Change loop to run to
the limit PC. Keep track of the PC value after frame
related instructions; return this value.
(after_prologue): Delete.
(sh_skip_prologue): Find the function limit and pass that
as the limit address to sh_analyze_prologue(). Also use
skip_prologue_using_sal() and return the lower result.
Index: gdb/sh-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/gnupro/gdb/sh-tdep.c,v
retrieving revision 1.21
diff -u -p -r1.21 sh-tdep.c
--- gdb/sh-tdep.c 2 Jul 2011 02:04:18 -0000 1.21
+++ gdb/sh-tdep.c 28 Oct 2011 00:27:21 -0000
@@ -520,39 +520,43 @@ sh_breakpoint_from_pc (struct gdbarch *g
static CORE_ADDR
sh_analyze_prologue (struct gdbarch *gdbarch,
- CORE_ADDR pc, CORE_ADDR current_pc,
+ CORE_ADDR pc, CORE_ADDR limit_pc,
struct sh_frame_cache *cache, ULONGEST fpscr)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST inst;
- CORE_ADDR opc;
+ CORE_ADDR after_last_frame_setup_insn = pc;
+ CORE_ADDR next_pc;
int offset;
int sav_offset = 0;
int r3_val = 0;
int reg, sav_reg = -1;
- if (pc >= current_pc)
- return current_pc;
-
cache->uses_fp = 0;
- for (opc = pc + (2 * 28); pc < opc; pc += 2)
+
+ for (;pc < limit_pc; pc = next_pc)
{
inst = read_memory_unsigned_integer (pc, 2, byte_order);
+ next_pc = pc + 2;
+
/* See where the registers will be saved to. */
if (IS_PUSH (inst))
{
cache->saved_regs[GET_SOURCE_REG (inst)] = cache->sp_offset;
cache->sp_offset += 4;
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_STS (inst))
{
cache->saved_regs[PR_REGNUM] = cache->sp_offset;
cache->sp_offset += 4;
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_MACL_STS (inst))
{
cache->saved_regs[MACL_REGNUM] = cache->sp_offset;
cache->sp_offset += 4;
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_MOV_R3 (inst))
{
@@ -565,11 +569,14 @@ sh_analyze_prologue (struct gdbarch *gdb
else if (IS_ADD_R3SP (inst))
{
cache->sp_offset += -r3_val;
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_ADD_IMM_SP (inst))
{
offset = ((inst & 0xff) ^ 0x80) - 0x80;
cache->sp_offset -= offset;
+ if (offset < 0)
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_MOVW_PCREL_TO_REG (inst))
{
@@ -628,6 +635,7 @@ sh_analyze_prologue (struct gdbarch *gdb
sav_reg = -1;
}
cache->sp_offset += sav_offset;
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_FPUSH (inst))
{
@@ -639,17 +647,20 @@ sh_analyze_prologue (struct gdbarch *gdb
{
cache->sp_offset += 4;
}
+ after_last_frame_setup_insn = next_pc;
}
else if (IS_MOV_SP_FP (inst))
{
+ CORE_ADDR opc;
cache->uses_fp = 1;
+ after_last_frame_setup_insn = next_pc;
/* At this point, only allow argument register moves to other
registers or argument register moves to @(X,fp) which are
moving the register arguments onto the stack area allocated
by a former add somenumber to SP call. Don't allow moving
to an fp indirect address above fp + cache->sp_offset. */
pc += 2;
- for (opc = pc + 12; pc < opc; pc += 2)
+ for (opc = pc + 12; pc < opc && pc < limit_pc; pc += 2)
{
inst = read_memory_integer (pc, 2, byte_order);
if (IS_MOV_ARG_TO_IND_R14 (inst))
@@ -683,7 +694,10 @@ sh_analyze_prologue (struct gdbarch *gdb
so, note that before returning the current pc. */
inst = read_memory_integer (pc + 2, 2, byte_order);
if (IS_MOV_SP_FP (inst))
- cache->uses_fp = 1;
+ {
+ cache->uses_fp = 1;
+ after_last_frame_setup_insn = pc;
+ }
break;
}
#if 0 /* This used to just stop when it found an instruction
@@ -695,61 +709,30 @@ sh_analyze_prologue (struct gdbarch *gdb
#endif
}
- return pc;
+ return after_last_frame_setup_insn;
}
/* Skip any prologue before the guts of a function. */
-/* Skip the prologue using the debug information. If this fails we'll
- fall back on the 'guess' method below. */
-static CORE_ADDR
-after_prologue (CORE_ADDR pc)
-{
- struct symtab_and_line sal;
- CORE_ADDR func_addr, func_end;
-
- /* If we can not find the symbol in the partial symbol table, then
- there is no hope we can determine the function's start address
- with this code. */
- if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- return 0;
-
- /* Get the line associated with FUNC_ADDR. */
- sal = find_pc_line (func_addr, 0);
-
- /* There are only two cases to consider. First, the end of the source line
- is within the function bounds. In that case we return the end of the
- source line. Second is the end of the source line extends beyond the
- bounds of the current function. We need to use the slow code to
- examine instructions in that case. */
- if (sal.end < func_end)
- return sal.end;
- else
- return 0;
-}
-
static CORE_ADDR
sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
- CORE_ADDR pc;
+ CORE_ADDR pc, sal_end, func_addr, func_end;
struct sh_frame_cache cache;
+ char *name;
- /* 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. */
- pc = after_prologue (start_pc);
-
- /* If after_prologue returned a useful address, then use it. Else
- fall back on the instruction skipping code. */
- if (pc)
- return max (pc, start_pc);
+ /* Try to find the extent of the function that contains PC. */
+ if (!find_pc_partial_function (start_pc, &name, &func_addr, &func_end))
+ return start_pc;
cache.sp_offset = -4;
- pc = sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0);
- if (!cache.uses_fp)
- return start_pc;
+ pc = sh_analyze_prologue (gdbarch, func_addr, func_end, &cache, 0);
- return pc;
+ sal_end = skip_prologue_using_sal (gdbarch, start_pc);
+ if (sal_end != 0 && sal_end != start_pc && sal_end < pc)
+ return sal_end;
+ else
+ return pc;
}
/* The ABI says:
next prev parent reply other threads:[~2012-02-15 14:54 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-15 14:00 Thomas Schwinge
2012-02-15 14:54 ` Pedro Alves
2012-02-16 15:27 ` [PATCH] [SH] GDB crash in sh_is_renesas_calling_convention, TYPE_CALLING_CONVENTION (was: Prologue skipping if there is none) Thomas Schwinge
2012-02-16 19:38 ` [PATCH] [SH] GDB crash in sh_is_renesas_calling_convention, TYPE_CALLING_CONVENTION Tom Tromey
2012-02-15 16:09 ` Kevin Buettner [this message]
2012-02-16 0:13 ` [PATCH] [SH] Prologue skipping if there is none Kevin Buettner
2012-02-16 16:59 ` Thomas Schwinge
2012-02-17 2:30 ` Kevin Buettner
2012-02-20 16:19 ` Thomas Schwinge
2012-02-21 5:25 ` Kevin Buettner
2012-02-24 11:09 ` Thomas Schwinge
2012-02-24 22:21 ` Kevin Buettner
2012-02-29 13:51 ` Thomas Schwinge
2012-03-01 0:13 ` Kevin Buettner
2012-03-01 9:03 ` Thomas Schwinge
2012-03-01 9:00 ` Thomas Schwinge
2012-03-02 0:19 ` Kevin Buettner
2012-03-02 11:18 ` Thomas Schwinge
2012-03-02 12:01 ` Pedro Alves
2012-03-02 14:15 ` Thomas Schwinge
2012-03-06 19:08 ` Pedro Alves
2012-03-03 1:18 ` Kevin Buettner
2012-03-05 15:16 ` Thomas Schwinge
2012-03-05 19:40 ` Kevin Buettner
2012-02-21 15:23 ` Thomas Schwinge
2012-02-22 14:54 ` Simulator testing for sh and sh64 (was: [PATCH] [SH] Prologue skipping if there is none) Thomas Schwinge
2012-02-22 16:56 ` Kevin Buettner
2012-02-22 19:33 ` Simulator testing for sh and sh64 Thomas Schwinge
2012-02-23 0:35 ` Kaz Kojima
2012-02-24 21:38 ` Thomas Schwinge
2012-02-23 19:55 ` Thomas Schwinge
2012-02-23 22:53 ` Kevin Buettner
2012-02-24 11:12 ` Thomas Schwinge
2012-02-23 23:57 ` Kevin Buettner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120215075413.1313f7fa@mesquite.lan \
--to=kevinb@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox