From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [PATCH] [SH] Prologue skipping if there is none
Date: Thu, 16 Feb 2012 00:13:00 -0000 [thread overview]
Message-ID: <20120215165907.33f2e9a6@mesquite.lan> (raw)
In-Reply-To: <20120215075413.1313f7fa@mesquite.lan>
On Wed, 15 Feb 2012 07:54:13 -0700
Kevin Buettner <kevinb@redhat.com> wrote:
> 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?
Below is an updated patch which builds cleanly against current
sources. I've verified that it produces better test results than not
having the patch. I have not compared the test results to Thomas'
patch.
I ran my tests against the simulator. I found that a sim patch is
necessary to do so. I'll post that in a moment.
Kevin
* 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: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.236
diff -u -p -r1.236 sh-tdep.c
--- sh-tdep.c 28 Jan 2012 18:08:20 -0000 1.236
+++ sh-tdep.c 15 Feb 2012 23:55:14 -0000
@@ -518,39 +518,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))
{
@@ -563,11 +567,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))
{
@@ -626,6 +633,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))
{
@@ -637,17 +645,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))
@@ -681,7 +692,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
@@ -693,61 +707,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;
+ const 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 23:59 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 ` [PATCH] [SH] Prologue skipping if there is none Kevin Buettner
2012-02-16 0:13 ` Kevin Buettner [this message]
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=20120215165907.33f2e9a6@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