* [patch] gdbarch_syscall_pc_increment
@ 2012-12-12 14:24 Aleksandar Ristovski
2012-12-12 15:30 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Aleksandar Ristovski @ 2012-12-12 14:24 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 602 bytes --]
Hello all,
This patch fixes stepping over system call instruction on architectures
that use software single stepping and also may increment PC upon return
from the system call to communicate error. (e.g. this is what we do on
Neutrino).
Note: I could only test this on Neutrino.
Thanks,
Aleksandar
ChangeLog:
* gdbarch.sh (syscall_pc_increment): New function.
* gdbarch.h, gdbarch.c: Regenerated.
* arm-tdep.c (arm_software_single_step): Use
gdbarch_syscall_pc_increment and if provided, insert second
single step breakpoint at the incremented address.
[-- Attachment #2: gdbarch_syscall_pc_increment-201212111513.patch --]
[-- Type: text/x-patch, Size: 6822 bytes --]
Index: gdb/gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.550
diff -u -p -r1.550 gdbarch.sh
--- gdb/gdbarch.sh 21 Nov 2012 00:29:54 -0000 1.550
+++ gdb/gdbarch.sh 11 Dec 2012 20:13:20 -0000
@@ -798,6 +798,10 @@ M:void:record_special_symbol:struct objf
# Get architecture-specific system calls information from registers.
M:LONGEST:get_syscall_number:ptid_t ptid:ptid
+# Return number of bytes the architecture may increment PC after
+# syscall.
+M:int:syscall_pc_increment:const struct frame_info *frame:frame
+
# SystemTap related fields and functions.
# Prefix used to mark an integer constant on the architecture's assembly
Index: gdb/gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.449
diff -u -p -r1.449 gdbarch.h
--- gdb/gdbarch.h 21 Nov 2012 00:29:54 -0000 1.449
+++ gdb/gdbarch.h 11 Dec 2012 20:13:20 -0000
@@ -611,7 +611,7 @@ extern void set_gdbarch_addr_bits_remove
FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
target can single step. If not, then implement single step using breakpoints.
- A return value of 1 means that the software_single_step breakpoints
+ A return value of 1 means that the software_single_step breakpoints
were inserted; 0 means they were not. */
extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch);
@@ -998,6 +998,15 @@ typedef LONGEST (gdbarch_get_syscall_num
extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid);
extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
+/* Return number of bytes the architecture may increment PC after
+ syscall. */
+
+extern int gdbarch_syscall_pc_increment_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_syscall_pc_increment_ftype) (struct gdbarch *gdbarch, const struct frame_info *frame);
+extern int gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, const struct frame_info *frame);
+extern void set_gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, gdbarch_syscall_pc_increment_ftype *syscall_pc_increment);
+
/* SystemTap related fields and functions.
Prefix used to mark an integer constant on the architecture's assembly
For example, on x86 integer constants are written as:
Index: gdb/gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.501
diff -u -p -r1.501 gdbarch.c
--- gdb/gdbarch.c 21 Nov 2012 00:29:54 -0000 1.501
+++ gdb/gdbarch.c 11 Dec 2012 20:13:20 -0000
@@ -263,6 +263,7 @@ struct gdbarch
gdbarch_get_siginfo_type_ftype *get_siginfo_type;
gdbarch_record_special_symbol_ftype *record_special_symbol;
gdbarch_get_syscall_number_ftype *get_syscall_number;
+ gdbarch_syscall_pc_increment_ftype *syscall_pc_increment;
const char * stap_integer_prefix;
const char * stap_integer_suffix;
const char * stap_register_prefix;
@@ -431,6 +432,7 @@ struct gdbarch startup_gdbarch =
0, /* get_siginfo_type */
0, /* record_special_symbol */
0, /* get_syscall_number */
+ 0, /* syscall_pc_increment */
0, /* stap_integer_prefix */
0, /* stap_integer_suffix */
0, /* stap_register_prefix */
@@ -731,6 +733,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of get_siginfo_type, has predicate. */
/* Skip verify of record_special_symbol, has predicate. */
/* Skip verify of get_syscall_number, has predicate. */
+ /* Skip verify of syscall_pc_increment, has predicate. */
/* Skip verify of stap_integer_prefix, invalid_p == 0 */
/* Skip verify of stap_integer_suffix, invalid_p == 0 */
/* Skip verify of stap_register_prefix, invalid_p == 0 */
@@ -1345,6 +1348,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
"gdbarch_dump: static_transform_name = <%s>\n",
host_address_to_string (gdbarch->static_transform_name));
fprintf_unfiltered (file,
+ "gdbarch_dump: gdbarch_syscall_pc_increment_p() = %d\n",
+ gdbarch_syscall_pc_increment_p (gdbarch));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: syscall_pc_increment = <%s>\n",
+ host_address_to_string (gdbarch->syscall_pc_increment));
+ fprintf_unfiltered (file,
"gdbarch_dump: target_desc = %s\n",
host_address_to_string (gdbarch->target_desc));
fprintf_unfiltered (file,
@@ -3890,6 +3899,30 @@ set_gdbarch_get_syscall_number (struct g
gdbarch->get_syscall_number = get_syscall_number;
}
+int
+gdbarch_syscall_pc_increment_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->syscall_pc_increment != NULL;
+}
+
+int
+gdbarch_syscall_pc_increment (struct gdbarch *gdbarch, const struct frame_info *frame)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->syscall_pc_increment != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_syscall_pc_increment called\n");
+ return gdbarch->syscall_pc_increment (gdbarch, frame);
+}
+
+void
+set_gdbarch_syscall_pc_increment (struct gdbarch *gdbarch,
+ gdbarch_syscall_pc_increment_ftype syscall_pc_increment)
+{
+ gdbarch->syscall_pc_increment = syscall_pc_increment;
+}
+
const char *
gdbarch_stap_integer_prefix (struct gdbarch *gdbarch)
{
Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.373
diff -u -p -r1.373 arm-tdep.c
--- gdb/arm-tdep.c 21 Nov 2012 00:29:54 -0000 1.373
+++ gdb/arm-tdep.c 11 Dec 2012 20:13:21 -0000
@@ -5242,6 +5242,31 @@ arm_software_single_step (struct frame_i
next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+ if (gdbarch_syscall_pc_increment_p (gdbarch))
+ {
+ /* Some OS-es will increment pc to differentiate success vs
+ * error returning from a sys call. */
+ const int inc = gdbarch_syscall_pc_increment (gdbarch, frame);
+ const enum bfd_endian byte_order_for_code
+ = gdbarch_byte_order_for_code (gdbarch);
+ const LONGEST this_pc = get_frame_pc (frame);
+ LONGEST insn, mask, match;
+
+ if (arm_frame_is_thumb (frame))
+ {
+ mask = 0xff000000;
+ match = 0xdf000000;
+ }
+ else
+ {
+ mask = 0x0f000000;
+ match = 0x0f000000;
+ }
+ if (safe_read_memory_integer (this_pc, 4, byte_order_for_code, &insn)
+ && (insn & mask) == match)
+ arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc + inc);
+ }
+
return 1;
}
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [patch] gdbarch_syscall_pc_increment
2012-12-12 14:24 [patch] gdbarch_syscall_pc_increment Aleksandar Ristovski
@ 2012-12-12 15:30 ` Yao Qi
2012-12-12 15:43 ` Aleksandar Ristovski
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2012-12-12 15:30 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb-patches
On 12/12/2012 10:23 PM, Aleksandar Ristovski wrote:
> This patch fixes stepping over system call instruction on architectures
> that use software single stepping and also may increment PC upon return
> from the system call to communicate error. (e.g. this is what we do on
> Neutrino).
>
> Note: I could only test this on Neutrino.
>
Hi,
I don't understand why do you add a gdbarch hook, but use it only in a
target-specific part? The goal of gdbarch hooks is about hiding the
difference of ports and giving a common interface to the common part of
GDB. If your issue is arm specific, we don't need this new gdbarch hook
at all.
If I understand your problem correctly, you have to define your own
function 'arm_neutrino_syscall_next_pc' in your file
arm-neutrino-tdep.c, and install it on function pointer
'syscall_next_pc' (in 'struct gdbarch_tdep' in arm-tdep.h) in
'arm_neutrino_init_abi'. Please have a look on how 'syscall_next_pc' is
set in arm-linux-tdep.c. Then you can compute the pc for your own os in
'arm_neutrino_syscall_next_pc'. Hope it helps.
>
> ChangeLog:
>
> * gdbarch.sh (syscall_pc_increment): New function.
> * gdbarch.h, gdbarch.c: Regenerated.
> * arm-tdep.c (arm_software_single_step): Use
> gdbarch_syscall_pc_increment and if provided, insert second
> single step breakpoint at the incremented address.
I guess the reason you need the 2nd single step breakpoint is that GDB
computes the 'next pc' by mistake, so you need the 2nd single step
breakpoint setting on the 'right' address of 'next pc'. In other words,
do we really need the 2nd single step breakpoint if the address of 'next
pc' is computed correctly?
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] gdbarch_syscall_pc_increment
2012-12-12 15:30 ` Yao Qi
@ 2012-12-12 15:43 ` Aleksandar Ristovski
2012-12-13 1:33 ` Yao Qi
0 siblings, 1 reply; 9+ messages in thread
From: Aleksandar Ristovski @ 2012-12-12 15:43 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 12-12-12 10:30 AM, Yao Qi wrote:
> Hi,
> I don't understand why do you add a gdbarch hook, but use it only in a
> target-specific part? The goal of gdbarch hooks is about hiding the
> difference of ports and giving a common interface to the common part of
> GDB. If your issue is arm specific, we don't need this new gdbarch hook
> at all.
This is generic for a given OS that happens to increment instruction
pointer to allow user code to e.g. set errno.
I provided only arm implementation, but other target cpus would need the
same if they implement software single stepping.
Increment is cpu specific for a given architecture.
>
> If I understand your problem correctly, you have to define your own
> function 'arm_neutrino_syscall_next_pc' in your file
> arm-neutrino-tdep.c, and install it on function pointer
> 'syscall_next_pc' (in 'struct gdbarch_tdep' in arm-tdep.h) in
> 'arm_neutrino_init_abi'. Please have a look on how 'syscall_next_pc' is
> set in arm-linux-tdep.c. Then you can compute the pc for your own os in
> 'arm_neutrino_syscall_next_pc'. Hope it helps.
No, the destination is not a single address as we do not know the
outcome of the syscall. It may come back with the instruction pointer of
the next instruction after 'svc' but also 4 bytes later (4 bytes in our
case, some other kernel may implement it differently).
Hope this clarifies,
Aleksandar
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] gdbarch_syscall_pc_increment
2012-12-12 15:43 ` Aleksandar Ristovski
@ 2012-12-13 1:33 ` Yao Qi
2012-12-13 14:08 ` Aleksandar Ristovski
0 siblings, 1 reply; 9+ messages in thread
From: Yao Qi @ 2012-12-13 1:33 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb-patches
On 12/12/2012 11:42 PM, Aleksandar Ristovski wrote:
>
> This is generic for a given OS that happens to increment instruction
> pointer to allow user code to e.g. set errno.
>
> I provided only arm implementation, but other target cpus would need the
> same if they implement software single stepping.
>
> Increment is cpu specific for a given architecture.
>
'software single step' is implemented differently in the backend of each
port and your 'syscall_pc_increment' depends on the arch as well, so a
gdbarch hook is not needed here.
'gdbarch' stands for a certain general architecture, such as arm, mips,
and etc. 'gdbarch_tdep' contains the details of the cpus under this
architecture.
>
>> >
>> >If I understand your problem correctly, you have to define your own
>> >function 'arm_neutrino_syscall_next_pc' in your file
>> >arm-neutrino-tdep.c, and install it on function pointer
>> >'syscall_next_pc' (in 'struct gdbarch_tdep' in arm-tdep.h) in
>> >'arm_neutrino_init_abi'. Please have a look on how 'syscall_next_pc' is
>> >set in arm-linux-tdep.c. Then you can compute the pc for your own os in
>> >'arm_neutrino_syscall_next_pc'. Hope it helps.
>
> No, the destination is not a single address as we do not know the
> outcome of the syscall. It may come back with the instruction pointer of
> the next instruction after 'svc' but also 4 bytes later (4 bytes in our
> case, some other kernel may implement it differently).
You may need a specified field in 'struct gdbarch_tdep', for example,
/* Do a post fix of a software single step. */
void (*software_single_step_fixup) (struct frame_info *frame);
In arm_software_single_step,
@@ -5242,6 +5242,31 @@ arm_software_single_step (struct frame_i
next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+ tdep = gdbarch_tdep (gdbarch);
+ if (tdep->software_single_step_fixup)
+ tdep->software_single_step_fixup (frame);
+
and you need to initialize field 'software_single_step_fixup' somewhere,
and do what you need in it.
b.t.w, I don't see how 'set_gdbarch_syscall_pc_increment' is called in
your patch.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [patch] gdbarch_syscall_pc_increment
2012-12-13 1:33 ` Yao Qi
@ 2012-12-13 14:08 ` Aleksandar Ristovski
2012-12-13 14:21 ` Yao Qi
2012-12-13 21:47 ` Pedro Alves
0 siblings, 2 replies; 9+ messages in thread
From: Aleksandar Ristovski @ 2012-12-13 14:08 UTC (permalink / raw)
To: Yao Qi; +Cc: gdb-patches
On 12-12-12 08:32 PM, Yao Qi wrote:
> On 12/12/2012 11:42 PM, Aleksandar Ristovski wrote:
>>
>> This is generic for a given OS that happens to increment instruction
>> pointer to allow user code to e.g. set errno.
>>
>> I provided only arm implementation, but other target cpus would need the
>> same if they implement software single stepping.
>>
>> Increment is cpu specific for a given architecture.
>>
>
> 'software single step' is implemented differently in the backend of each
> port and your 'syscall_pc_increment' depends on the arch as well, so a
> gdbarch hook is not needed here.
>
> 'gdbarch' stands for a certain general architecture, such as arm, mips,
> and etc. 'gdbarch_tdep' contains the details of the cpus under this
> architecture.
Yes, I see your point, though I would say gdbarch stands for a certain
architecture such as arm-nto, arm-linux, etc... therefore, cpu/os
combination, not cpu only.
In this patch, we are talking about two things:
a) the concept of syscall behaving as a conditional branch with
uncomputable condition (i.e. gdb can not really compute whether the
branch will be taken or not). This is a concept specific to a given
kernel implementation of system calls and as such belongs to gdbarch.
b) The amount by which pc may be incremented if the branch is taken. For
an os that has a), this is cpu specific. It may also be dependent on the
instruction set mode on e.g. arm (this is why frame is being passed).
Where does this belong: in the case here, the line is a bit blurry since
a) is generic concept applicable for all cpus for a given os thus
definitely belonging to gdbarch. b) is cpu concept and strictly speaking
belongs to gdbarch_tdep. However, since a) can also answer b) I see no
point in further breaking it down.
Of course, the alternative is to not introduce concept from a) at all
and do everything in my cpu-os-tdep.c which is how I have it set up now
in our port.
>
> b.t.w, I don't see how 'set_gdbarch_syscall_pc_increment' is called in
> your patch.
>
No, as we have not yet contributed arm-nto-tdep.c to FSF.
---
Aleksandar
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] gdbarch_syscall_pc_increment
2012-12-13 14:08 ` Aleksandar Ristovski
@ 2012-12-13 14:21 ` Yao Qi
2012-12-13 21:47 ` Pedro Alves
1 sibling, 0 replies; 9+ messages in thread
From: Yao Qi @ 2012-12-13 14:21 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: gdb-patches
On 12/13/2012 10:07 PM, Aleksandar Ristovski wrote:
> Yes, I see your point, though I would say gdbarch stands for a certain
> architecture such as arm-nto, arm-linux, etc... therefore, cpu/os
> combination, not cpu only.
Yeah, that is more precise. We do have some gdbarch hook methods, such
as gdbarch_skip_trampoline_code, gdbarch_get_syscall_number,
gdbarch_skip_solib_resolver, they are about the cpu/os (or runtime lib)
combination.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [patch] gdbarch_syscall_pc_increment
2012-12-13 14:08 ` Aleksandar Ristovski
2012-12-13 14:21 ` Yao Qi
@ 2012-12-13 21:47 ` Pedro Alves
2012-12-14 14:23 ` Aleksandar Ristovski
1 sibling, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-12-13 21:47 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: Yao Qi, gdb-patches
On 12/13/2012 02:07 PM, Aleksandar Ristovski wrote:
> In this patch, we are talking about two things:
>
> a) the concept of syscall behaving as a conditional branch with uncomputable condition (i.e. gdb can not really compute whether the branch will be taken or not). This is a concept specific to a given kernel implementation of system calls and as such belongs to gdbarch.
>
> b) The amount by which pc may be incremented if the branch is taken. For an os that has a), this is cpu specific. It may also be dependent on the instruction set mode on e.g. arm (this is why frame is being passed).
>
> Where does this belong: in the case here, the line is a bit blurry since a) is generic concept applicable for all cpus for a given os thus definitely belonging to gdbarch. b) is cpu concept and strictly speaking belongs to gdbarch_tdep. However, since a) can also answer b) I see no point in further breaking it down.
The interface is not pretty, but you can just install an additional
breakpoint from your OS's tdep->syscall_next_pc hook or
gdbarch_software_single_step wrapper hook. See e.g.,:
/* Find the next PC after the current instruction executes. In some
cases we can not statically determine the answer (see the IT state
handling in this function); in that case, a breakpoint may be
inserted in addition to the returned PC, which will be used to set
another breakpoint by our caller. */
static CORE_ADDR
thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc)
{
...
/* Set a breakpoint on the following instruction. */
gdb_assert ((itstate & 0x0f) != 0);
arm_insert_single_step_breakpoint (gdbarch, aspace,
MAKE_THUMB_ADDR (pc));
...
I believe other ports do similar things in similar cases.
>> b.t.w, I don't see how 'set_gdbarch_syscall_pc_increment' is called in
>> your patch.
>>
>
> No, as we have not yet contributed arm-nto-tdep.c to FSF.
When do you plan to do so? I'm afraid we shouldn't be accepting
unused hooks in the tree.
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [patch] gdbarch_syscall_pc_increment
2012-12-13 21:47 ` Pedro Alves
@ 2012-12-14 14:23 ` Aleksandar Ristovski
2012-12-14 15:14 ` Pedro Alves
0 siblings, 1 reply; 9+ messages in thread
From: Aleksandar Ristovski @ 2012-12-14 14:23 UTC (permalink / raw)
To: Pedro Alves; +Cc: Yao Qi, gdb-patches
On 12-12-13 04:47 PM, Pedro Alves wrote:
> On 12/13/2012 02:07 PM, Aleksandar Ristovski wrote:
>
>> In this patch, we are talking about two things:
>>
>> a) the concept of syscall behaving as a conditional branch with uncomputable condition (i.e. gdb can not really compute whether the branch will be taken or not). This is a concept specific to a given kernel implementation of system calls and as such belongs to gdbarch.
>>
>> b) The amount by which pc may be incremented if the branch is taken. For an os that has a), this is cpu specific. It may also be dependent on the instruction set mode on e.g. arm (this is why frame is being passed).
>>
>> Where does this belong: in the case here, the line is a bit blurry since a) is generic concept applicable for all cpus for a given os thus definitely belonging to gdbarch. b) is cpu concept and strictly speaking belongs to gdbarch_tdep. However, since a) can also answer b) I see no point in further breaking it down.
>
> The interface is not pretty, but you can just install an additional
> breakpoint from your OS's tdep->syscall_next_pc hook or
> gdbarch_software_single_step wrapper hook. See e.g.,:
>
> /* Find the next PC after the current instruction executes. In some
> cases we can not statically determine the answer (see the IT state
> handling in this function); in that case, a breakpoint may be
> inserted in addition to the returned PC, which will be used to set
> another breakpoint by our caller. */
>
> static CORE_ADDR
> thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc)
> {
> ...
> /* Set a breakpoint on the following instruction. */
> gdb_assert ((itstate & 0x0f) != 0);
> arm_insert_single_step_breakpoint (gdbarch, aspace,
> MAKE_THUMB_ADDR (pc));
> ...
>
> I believe other ports do similar things in similar cases.
This seems just wrong to me, to install a breakpoint when answering a
question.
>
>>> b.t.w, I don't see how 'set_gdbarch_syscall_pc_increment' is called in
>>> your patch.
>>>
>>
>> No, as we have not yet contributed arm-nto-tdep.c to FSF.
>
> When do you plan to do so? I'm afraid we shouldn't be accepting
> unused hooks in the tree.
>
Well, I plan to, but can't provide any ETA.
No problem - there is no urgency in this, at least we have exchanged
thoughts on where would this fit (it doesn't fit anywhere ATM :-) ).
I'll stick with providing my own software_single_step.
Consider the patch abandoned.
Thanks,
Aleksandar
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [patch] gdbarch_syscall_pc_increment
2012-12-14 14:23 ` Aleksandar Ristovski
@ 2012-12-14 15:14 ` Pedro Alves
0 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves @ 2012-12-14 15:14 UTC (permalink / raw)
To: Aleksandar Ristovski; +Cc: Yao Qi, gdb-patches
On 12/14/2012 02:23 PM, Aleksandar Ristovski wrote:
> On 12-12-13 04:47 PM, Pedro Alves wrote:
>> On 12/13/2012 02:07 PM, Aleksandar Ristovski wrote:
>>
>>> In this patch, we are talking about two things:
>>>
>>> a) the concept of syscall behaving as a conditional branch with uncomputable condition (i.e. gdb can not really compute whether the branch will be taken or not). This is a concept specific to a given kernel implementation of system calls and as such belongs to gdbarch.
>>>
>>> b) The amount by which pc may be incremented if the branch is taken. For an os that has a), this is cpu specific. It may also be dependent on the instruction set mode on e.g. arm (this is why frame is being passed).
>>>
>>> Where does this belong: in the case here, the line is a bit blurry since a) is generic concept applicable for all cpus for a given os thus definitely belonging to gdbarch. b) is cpu concept and strictly speaking belongs to gdbarch_tdep. However, since a) can also answer b) I see no point in further breaking it down.
>>
>> The interface is not pretty, but you can just install an additional
>> breakpoint from your OS's tdep->syscall_next_pc hook or
>> gdbarch_software_single_step wrapper hook. See e.g.,:
>>
>> /* Find the next PC after the current instruction executes. In some
>> cases we can not statically determine the answer (see the IT state
>> handling in this function); in that case, a breakpoint may be
>> inserted in addition to the returned PC, which will be used to set
>> another breakpoint by our caller. */
>>
>> static CORE_ADDR
>> thumb_get_next_pc_raw (struct frame_info *frame, CORE_ADDR pc)
>> {
>> ...
>> /* Set a breakpoint on the following instruction. */
>> gdb_assert ((itstate & 0x0f) != 0);
>> arm_insert_single_step_breakpoint (gdbarch, aspace,
>> MAKE_THUMB_ADDR (pc));
>> ...
>>
>> I believe other ports do similar things in similar cases.
>
>
> This seems just wrong to me, to install a breakpoint when answering a question.
I did say the interface wasn't pretty. :-) "get_next_pc" returning a single address
is what IMO is broken. These hooks should be returning a list of locations, so that
the callers could install the multiple breakpoints themselves.
--
Pedro Alves
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-12-14 15:14 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-12 14:24 [patch] gdbarch_syscall_pc_increment Aleksandar Ristovski
2012-12-12 15:30 ` Yao Qi
2012-12-12 15:43 ` Aleksandar Ristovski
2012-12-13 1:33 ` Yao Qi
2012-12-13 14:08 ` Aleksandar Ristovski
2012-12-13 14:21 ` Yao Qi
2012-12-13 21:47 ` Pedro Alves
2012-12-14 14:23 ` Aleksandar Ristovski
2012-12-14 15:14 ` Pedro Alves
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox