* [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
@ 2010-08-24 6:39 Yao Qi
2010-08-24 11:28 ` Mark Kettenis
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2010-08-24 6:39 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1032 bytes --]
Hi,
This patch is to calculate correct address of 'next pc' of syscall
sigreturn and rt_sigreturn.
Tested on armv7l-unknown-linux-gnueabi, and a diff of test summary is
shown below:
-FAIL: gdb.base/sigstep.exp: step from handler; leave handler(timeout)
+PASS: gdb.base/sigstep.exp: step from handler; leave handler
-FAIL: gdb.base/sigstep.exp: stepi from handleri; leave signal trampoline
+PASS: gdb.base/sigstep.exp: stepi from handleri; leave signal trampoline (in main)
-FAIL: gdb.base/sigstep.exp: next from handler; leave handler (timeout)
+PASS: gdb.base/sigstep.exp: next from handler; leave handler
-FAIL: gdb.base/sigstep.exp: nexti from handleri; leave signal trampoline
+PASS: gdb.base/sigstep.exp: nexti from handleri; leave signal trampoline (in main)
=== gdb Summary ===
-# of expected passes 14664
-# of unexpected failures 314
+# of expected passes 14669
+# of unexpected failures 310
Is that OK?
--
Yao Qi
CodeSourcery
yao@codesourcery.com
(650) 331-3385 x739
[-- Attachment #2: nextpc_of_svc.patch --]
[-- Type: text/x-diff, Size: 733 bytes --]
2010-08-24 Yao Qi <yao@codesourcery.com>
*arm-tdep.c (arm_get_next_pc_raw): Calculate next pc of sigreturn or
rt_sigreturn syscall.
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 1ac8817..978bb72 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3257,7 +3257,18 @@ 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 */
+ {
+ unsigned long svc_number = get_frame_register_unsigned (frame, 7);
+
+ if (svc_number == 119 || svc_number == 173)
+ {
+ if (get_frame_type (frame) == SIGTRAMP_FRAME)
+ {
+ nextpc = frame_unwind_caller_pc (frame);
+ }
+ }
break;
default:
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-24 6:39 [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall Yao Qi
@ 2010-08-24 11:28 ` Mark Kettenis
2010-08-24 14:13 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Mark Kettenis @ 2010-08-24 11:28 UTC (permalink / raw)
To: yao; +Cc: gdb-patches
> 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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-24 11:28 ` Mark Kettenis
@ 2010-08-24 14:13 ` Daniel Jacobowitz
2010-08-25 3:06 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2010-08-24 14:13 UTC (permalink / raw)
To: Mark Kettenis, Yao Qi; +Cc: gdb-patches
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.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-24 14:13 ` Daniel Jacobowitz
@ 2010-08-25 3:06 ` Yao Qi
2010-08-25 14:31 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2010-08-25 3:06 UTC (permalink / raw)
To: Mark Kettenis, Daniel Jacobowitz; +Cc: gdb-patches
[-- 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,
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-25 3:06 ` Yao Qi
@ 2010-08-25 14:31 ` Daniel Jacobowitz
2010-08-26 8:51 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2010-08-25 14:31 UTC (permalink / raw)
To: Yao Qi; +Cc: Mark Kettenis, gdb-patches
Generally looks OK.
On Tue, Aug 24, 2010 at 08:05:55PM -0700, Yao Qi wrote:
> 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.
A valid return address won't be zero, but it's still confusing.
Please do this the way that e.g. mips_linux_get_longjmp_target does;
return 0 or 1, and have a CORE_ADDR * parameter.
> +static int
> +arm_linux_sigreturn_return_addr(struct frame_info *frame,
> + unsigned long svc_number)
Space before "(". Same problem in other places, too.
> +/* 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));
Line too long; move the read of r7 to another temporary.
What about non-EABI? We shouldn't wire this up for non-EABI binaries,
because the syscall number won't be in r7.
> @@ -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 */
Why did you remove the condition_true check?
> + {
> + struct gdbarch_tdep *tdep;
> + tdep = gdbarch_tdep (get_frame_arch (frame));
You can just use gdbarch_tdep (gdbarch).
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-25 14:31 ` Daniel Jacobowitz
@ 2010-08-26 8:51 ` Yao Qi
2010-08-30 13:00 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2010-08-26 8:51 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2175 bytes --]
Daniel Jacobowitz wrote:
> Generally looks OK.
>
> On Tue, Aug 24, 2010 at 08:05:55PM -0700, Yao Qi wrote:
>> 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.
>
> A valid return address won't be zero, but it's still confusing.
> Please do this the way that e.g. mips_linux_get_longjmp_target does;
> return 0 or 1, and have a CORE_ADDR * parameter.
>
OK, done as you suggested.
>> +static int
>> +arm_linux_sigreturn_return_addr(struct frame_info *frame,
>> + unsigned long svc_number)
>
> Space before "(". Same problem in other places, too.
>
Done.
>> +/* 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));
>
> Line too long; move the read of r7 to another temporary.
>
Done.
> What about non-EABI? We shouldn't wire this up for non-EABI binaries,
> because the syscall number won't be in r7.
I've added code for non-EABI to decode SWI instruction for syscall
number. See details in my patch.
>
>> @@ -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 */
>
> Why did you remove the condition_true check?
Because I noticed that condition_true always returns true if cond is 0xf
(INST_NV).
>> + {
>> + struct gdbarch_tdep *tdep;
>> + tdep = gdbarch_tdep (get_frame_arch (frame));
>
> You can just use gdbarch_tdep (gdbarch).
OK, done in my patch.
--
Yao Qi
CodeSourcery
yao@codesourcery.com
(650) 331-3385 x739
[-- Attachment #2: return_addr_sigreturn.patch --]
[-- Type: text/x-patch, Size: 7073 bytes --]
2010-08-26 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..f0e1dfa 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -630,6 +630,82 @@ arm_linux_regset_from_core_section (struct gdbarch *gdbarch,
return NULL;
}
+/* Copy the value of next pc of sigreturn and rt_sigrturn into PC,
+ and return 1. 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,
+ CORE_ADDR *pc)
+{
+ /* Is this a sigreturn or rt_sigreturn syscall? */
+ if (svc_number == 119 || svc_number == 173)
+ {
+ if (get_frame_type (frame) == SIGTRAMP_FRAME)
+ {
+ *pc = frame_unwind_caller_pc (frame);
+ return 1;
+ }
+ }
+ 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;
+ int is_thumb = arm_frame_is_thumb (frame);
+ ULONGEST svc_number = 0;
+ int is_sigreturn = 0;
+
+ if (is_thumb)
+ {
+ svc_number = get_frame_register_unsigned (frame, 7);
+ }
+ else
+ {
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order_for_code =
+ gdbarch_byte_order_for_code (gdbarch);
+ unsigned long this_instr =
+ read_memory_unsigned_integer (pc, 4, byte_order_for_code);
+
+ unsigned long svc_operand = (0x00ffffff & this_instr);
+ if (svc_operand) /* OABI. */
+ {
+ svc_number = svc_operand - 0x900000;
+ }
+ else /* EABI. */
+ {
+ svc_number = get_frame_register_unsigned (frame, 7);
+ }
+ }
+
+ is_sigreturn = arm_linux_sigreturn_return_addr (frame, svc_number,
+ &return_addr);
+
+ if (is_sigreturn)
+ return return_addr;
+
+ if (is_thumb)
+ {
+ 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,8 +764,11 @@ 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);
+ int is_sigreturn = 0;
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: copying Linux svc insn %.8lx\n",
@@ -697,13 +776,10 @@ 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)
+ is_sigreturn = arm_linux_sigreturn_return_addr(frame, svc_number,
+ &return_to);
+ if (is_sigreturn)
{
- if (get_frame_type (frame) == SIGTRAMP_FRAME)
- {
- CORE_ADDR return_to;
struct symtab_and_line sal;
if (debug_displaced)
@@ -711,7 +787,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 +818,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 +1021,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..36b46b5 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 (gdbarch);
+
+ 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 (gdbarch);
+
+ 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,
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-26 8:51 ` Yao Qi
@ 2010-08-30 13:00 ` Daniel Jacobowitz
2010-08-30 13:08 ` Mark Kettenis
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2010-08-30 13:00 UTC (permalink / raw)
To: Yao Qi; +Cc: Mark Kettenis, gdb-patches
On Thu, Aug 26, 2010 at 04:50:48PM +0800, Yao Qi wrote:
> > Why did you remove the condition_true check?
>
> Because I noticed that condition_true always returns true if cond is 0xf
> (INST_NV).
Sorry, you're right - I completely misread this.
> 2010-08-26 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.
This is OK. Thanks!
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-30 13:00 ` Daniel Jacobowitz
@ 2010-08-30 13:08 ` Mark Kettenis
2010-08-30 15:35 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Mark Kettenis @ 2010-08-30 13:08 UTC (permalink / raw)
To: dan; +Cc: yao, mark.kettenis, gdb-patches
> Date: Mon, 30 Aug 2010 08:59:58 -0400
> From: Daniel Jacobowitz <dan@codesourcery.com>
>
> On Thu, Aug 26, 2010 at 04:50:48PM +0800, Yao Qi wrote:
> > > Why did you remove the condition_true check?
> >
> > Because I noticed that condition_true always returns true if cond is 0xf
> > (INST_NV).
>
> Sorry, you're right - I completely misread this.
>
> > 2010-08-26 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.
>
> This is OK. Thanks!
If Daniel is happy with this, I'm as well.
Thanks,
Mark
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall
2010-08-30 13:08 ` Mark Kettenis
@ 2010-08-30 15:35 ` Yao Qi
0 siblings, 0 replies; 9+ messages in thread
From: Yao Qi @ 2010-08-30 15:35 UTC (permalink / raw)
To: Mark Kettenis; +Cc: dan, gdb-patches
On Mon, Aug 30, 2010 at 03:07:16PM +0200, Mark Kettenis wrote:
> > Date: Mon, 30 Aug 2010 08:59:58 -0400
> > From: Daniel Jacobowitz <dan@codesourcery.com>
> >
> > On Thu, Aug 26, 2010 at 04:50:48PM +0800, Yao Qi wrote:
> > > > Why did you remove the condition_true check?
> > >
> > > Because I noticed that condition_true always returns true if cond is 0xf
> > > (INST_NV).
> >
> > Sorry, you're right - I completely misread this.
> >
> > > 2010-08-26 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.
> >
> > This is OK. Thanks!
>
> If Daniel is happy with this, I'm as well.
Committed in both GDB mainline and GDB 7.2 branch.
http://www.cygwin.org/ml/gdb-cvs/2010-08/msg00190.html
http://www.cygwin.org/ml/gdb-cvs/2010-08/msg00191.html
--
Yao Qi
CodeSourcery
yao@codesourcery.com
(650) 331-3385 x739
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-08-30 15:35 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-24 6:39 [Patch,ARM] Next pc of sigreturn/rt_sigreturn syscall Yao Qi
2010-08-24 11:28 ` Mark Kettenis
2010-08-24 14:13 ` Daniel Jacobowitz
2010-08-25 3:06 ` Yao Qi
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
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).