diff options
author | Yao Qi <yao.qi@linaro.org> | 2016-06-28 12:02:36 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2016-06-28 12:03:28 +0100 |
commit | 79e7fd4f78e0c33e77dd0b69d7de8167a60af06a (patch) | |
tree | ba92f6c43797cfe620f614faa7766a5264c6c22e /gdb | |
parent | 061fc021d5d110cc37a4c06c4ed94b87be00610a (diff) | |
download | gdb-79e7fd4f78e0c33e77dd0b69d7de8167a60af06a.zip gdb-79e7fd4f78e0c33e77dd0b69d7de8167a60af06a.tar.gz gdb-79e7fd4f78e0c33e77dd0b69d7de8167a60af06a.tar.bz2 |
Implement get_syscall_trapinfo for arm-linux
gdb/gdbserver:
2016-06-28 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (arm_get_syscall_trapinfo): New function.
(the_low_target): Install arm_get_syscall_trapinfo.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/gdbserver/linux-arm-low.c | 37 |
2 files changed, 41 insertions, 1 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 4c28195..f6f0ad9 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,10 @@ 2016-06-28 Yao Qi <yao.qi@linaro.org> + * linux-arm-low.c (arm_get_syscall_trapinfo): New function. + (the_low_target): Install arm_get_syscall_trapinfo. + +2016-06-28 Yao Qi <yao.qi@linaro.org> + * linux-aarch64-low.c (aarch64_get_syscall_trapinfo): New function. (the_low_target): Install aarch64_get_syscall_trapinfo. diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 2ffda87..e1261e5 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -951,6 +951,40 @@ arm_supports_hardware_single_step (void) return 0; } +/* Implementation of linux_target_ops method "get_syscall_trapinfo". */ + +static void +arm_get_syscall_trapinfo (struct regcache *regcache, int *sysno) +{ + if (arm_is_thumb_mode ()) + collect_register_by_name (regcache, "r7", sysno); + else + { + unsigned long pc; + unsigned long insn; + + collect_register_by_name (regcache, "pc", &pc); + + if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4)) + *sysno = UNKNOWN_SYSCALL; + else + { + unsigned long svc_operand = (0x00ffffff & insn); + + if (svc_operand) + { + /* OABI */ + *sysno = svc_operand - 0x900000; + } + else + { + /* EABI */ + collect_register_by_name (regcache, "r7", sysno); + } + } + } +} + /* Register sets without using PTRACE_GETREGSET. */ static struct regset_info arm_regsets[] = { @@ -1031,7 +1065,8 @@ struct linux_target_ops the_low_target = { NULL, /* get_min_fast_tracepoint_insn_len */ NULL, /* supports_range_stepping */ arm_breakpoint_kind_from_current_state, - arm_supports_hardware_single_step + arm_supports_hardware_single_step, + arm_get_syscall_trapinfo, }; void |