From: Yao Qi <yao@codesourcery.com>
To: Mark Kettenis <mark.kettenis@xs4all.nl>,
Daniel Jacobowitz <dan@codesourcery.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
Date: Wed, 25 Aug 2010 03:06:00 -0000 [thread overview]
Message-ID: <20100825030554.GC29794@codesourcery.com> (raw)
In-Reply-To: <20100824141253.GA13547@caradoc.them.org>
[-- Attachment #1: Type: text/plain, Size: 1007 bytes --]
On Tue, Aug 24, 2010 at 10:12:57AM -0400, Daniel Jacobowitz wrote:
> On Tue, Aug 24, 2010 at 01:27:03PM +0200, Mark Kettenis wrote:
> > > Date: Mon, 23 Aug 2010 23:38:54 -0700
> > > From: Yao Qi <yao@codesourcery.com>
> > >
> > > Hi,
> > > This patch is to calculate correct address of 'next pc' of syscall
> > > sigreturn and rt_sigreturn.
> >
> > You're polluting the genric arm code with Linux-specific stuff.
> > Please don't do that. If something like this is needed, it should be
> > added to code in arm-linux-tdep.c.
>
> There's a couple of ways to do that; one example is
> mips_linux_syscall_next_pc.
Here is the updated patch, in which:
1. Add arm_linux_syscall_next_pc, similar to
mips_linux_syscall_next_pc. Compute the return address of SWI in both
ARM mode and Thumb mode.
2. Extract some common code from arm_linux_copy_svc.
Tested on armv7l-unknown-linux-gnueabi again. Result is the same as
my previous post.
--
Yao Qi
CodeSourcery
yao@codesourcery.com
(650) 331-3385 x739
[-- Attachment #2: return_addr_sigreturn.patch --]
[-- Type: text/x-diff, Size: 6256 bytes --]
2010-08-25 Yao Qi <yao@codesourcery.com>
* arm-linux-tdep.c (arm_linux_sigreturn_return_addr): New.
(arm_linux_syscall_next_pc): New.
(arm_linux_copy_svc): Use arm_linux_sigreturn_return_addr instead.
(arm_linux_init_abi): Initialize syscall_next_pc.
* arm-tdep.c (thumb_get_next_pc_raw): Get next pc of SWI in Thumb mode.
(arm_get_next_pc_raw): Get next pc of SWI in ARM mode.
* arm-tdep.h (struct gdbarch_tdep): Add a function pointer syscall_next_pc.
Declare arm_frame_is_thumb.
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 682054c..106cd85 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -630,6 +630,53 @@ arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
return NULL;
}
+/* Get the value of next pc of sigreturn and rt_sigrturn. Return 0 if it is
+ not a rt_sigreturn/sigreturn syscall. */
+static int
+arm_linux_sigreturn_return_addr(struct frame_info *frame,
+ unsigned long svc_number)
+{
+ /* Is this a sigreturn or rt_sigreturn syscall? Note: these are only useful
+ for EABI. */
+ if (svc_number == 119 || svc_number == 173)
+ {
+ if (get_frame_type (frame) == SIGTRAMP_FRAME)
+ {
+ return frame_unwind_caller_pc (frame);
+ }
+ }
+ return 0;
+}
+
+/* When FRAME is at a syscall instruction, return the PC of the next
+ instruction to be executed. */
+
+static CORE_ADDR
+arm_linux_syscall_next_pc (struct frame_info *frame)
+{
+ CORE_ADDR pc = get_frame_pc (frame);
+ CORE_ADDR return_addr = 0;
+ return_addr = arm_linux_sigreturn_return_addr(frame,
+ get_frame_register_unsigned (frame, 7));
+
+ if (return_addr)
+ return return_addr;
+
+ if (arm_frame_is_thumb (frame))
+ {
+ return_addr = pc + 2;
+ /* Addresses for calling Thumb functions have the bit 0 set. */
+ return_addr |= 1;
+ }
+ else
+ {
+ return_addr = pc + 4;
+ }
+
+ return return_addr;
+}
+
+
/* Insert a single step breakpoint at the next executed instruction. */
static int
@@ -688,6 +735,8 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
struct regcache *regs, struct displaced_step_closure *dsc)
{
CORE_ADDR from = dsc->insn_addr;
+ CORE_ADDR return_to = 0;
+
struct frame_info *frame;
unsigned int svc_number = displaced_read_reg (regs, from, 7);
@@ -697,13 +746,9 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
frame = get_current_frame ();
- /* Is this a sigreturn or rt_sigreturn syscall? Note: these are only useful
- for EABI. */
- if (svc_number == 119 || svc_number == 173)
- {
- if (get_frame_type (frame) == SIGTRAMP_FRAME)
+ return_to = arm_linux_sigreturn_return_addr(frame, svc_number);
+ if (return_to)
{
- CORE_ADDR return_to;
struct symtab_and_line sal;
if (debug_displaced)
@@ -711,7 +756,6 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
"sigreturn/rt_sigreturn SVC call. PC in frame = %lx\n",
(unsigned long) get_frame_pc (frame));
- return_to = frame_unwind_caller_pc (frame);
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: unwind pc = %lx. "
"Setting momentary breakpoint.\n", (unsigned long) return_to);
@@ -743,7 +787,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, uint32_t insn, CORE_ADDR to,
else if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: sigreturn/rt_sigreturn "
"SVC call not in signal trampoline frame\n");
- }
+
/* Preparation: If we detect sigreturn, set momentary breakpoint at resume
location, else nothing.
@@ -946,6 +990,9 @@ arm_linux_init_abi (struct gdbarch_info info,
set_gdbarch_displaced_step_free_closure (gdbarch,
simple_displaced_step_free_closure);
set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point);
+
+
+ tdep->syscall_next_pc = arm_linux_syscall_next_pc;
}
/* Provide a prototype to silence -Wmissing-prototypes. */
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 1ac8817..518e4e8 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -257,7 +257,7 @@ int arm_apcs_32 = 1;
/* Determine if FRAME is executing in Thumb mode. */
-static int
+int
arm_frame_is_thumb (struct frame_info *frame)
{
CORE_ADDR cpsr;
@@ -2808,7 +2808,16 @@ thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc, int insert_bkpt)
else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
{
unsigned long cond = bits (inst1, 8, 11);
- if (cond != 0x0f && condition_true (cond, status)) /* 0x0f = SWI */
+ if (cond == 0x0f) /* 0x0f = SWI */
+ {
+ struct gdbarch_tdep *tdep;
+ tdep = gdbarch_tdep (get_frame_arch (frame));
+
+ if (tdep->syscall_next_pc != NULL)
+ nextpc = tdep->syscall_next_pc (frame);
+
+ }
+ else if (cond != 0x0f && condition_true (cond, status))
nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
}
else if ((inst1 & 0xf800) == 0xe000) /* unconditional branch */
@@ -3257,7 +3266,16 @@ arm_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc, int insert_bkpt)
case 0xc:
case 0xd:
case 0xe: /* coproc ops */
+ break;
case 0xf: /* SWI */
+ {
+ struct gdbarch_tdep *tdep;
+ tdep = gdbarch_tdep (get_frame_arch (frame));
+
+ if (tdep->syscall_next_pc != NULL)
+ nextpc = tdep->syscall_next_pc (frame);
+
+ }
break;
default:
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index b6283ef..2f4e99b 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -193,6 +193,10 @@ struct gdbarch_tdep
struct type *arm_ext_type;
struct type *neon_double_type;
struct type *neon_quad_type;
+
+ /* Return the expected next PC if FRAME is stopped at a syscall
+ instruction. */
+ CORE_ADDR (*syscall_next_pc) (struct frame_info *frame);
};
/* Structures used for displaced stepping. */
@@ -294,6 +298,7 @@ extern void
CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);
CORE_ADDR arm_get_next_pc (struct frame_info *, CORE_ADDR);
int arm_software_single_step (struct frame_info *);
+int arm_frame_is_thumb (struct frame_info *frame);
extern struct displaced_step_closure *
arm_displaced_step_copy_insn (struct gdbarch *, CORE_ADDR, CORE_ADDR,
next prev parent reply other threads:[~2010-08-25 3:06 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-24 6:39 Yao Qi
2010-08-24 11:28 ` Mark Kettenis
2010-08-24 14:13 ` Daniel Jacobowitz
2010-08-25 3:06 ` Yao Qi [this message]
2010-08-25 14:31 ` Daniel Jacobowitz
2010-08-26 8:51 ` Yao Qi
2010-08-30 13:00 ` Daniel Jacobowitz
2010-08-30 13:08 ` Mark Kettenis
2010-08-30 15:35 ` Yao Qi
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=20100825030554.GC29794@codesourcery.com \
--to=yao@codesourcery.com \
--cc=dan@codesourcery.com \
--cc=gdb-patches@sourceware.org \
--cc=mark.kettenis@xs4all.nl \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).