* [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).