diff options
author | Sergio Durigan Junior <sergiodj@redhat.com> | 2013-08-22 20:32:54 +0000 |
---|---|---|
committer | Sergio Durigan Junior <sergiodj@redhat.com> | 2013-08-22 20:32:54 +0000 |
commit | 9f948660082197e73991d4d0db07030420c33e45 (patch) | |
tree | e315922fd0a016cf8f350026411d6ea1b83fd030 /gdb/arm-linux-tdep.c | |
parent | f69a2f978fdcffafa9fe4c4a5b3b2b1af61698ba (diff) | |
download | binutils-gdb-9f948660082197e73991d4d0db07030420c33e45.tar.gz |
[Committing the `catch syscall' patch for ARM, from Samuel Bronson.]
This time, it passes all the tests and comes with a nearly complete
XML file (plus a script that can nearly regenerate the XML file).
(I elected to leave out __ARM_NR_cmpxchg, since it has dire warnings
to the effect that the only pieces of code that should be aware of it
are the implementation and the __kuser_cmpxchg code in entry-armv.S.)
gdb/
2013-08-14 Samuel Bronson <naesten@gmail.com>
ARM Linux support for `catch syscall'.
* syscalls/arm-linux.py: New file.
* syscalls/arm-linux.xml: Likewise.
* arm-linux-tdep.c (arm_linux_get_syscall_number): New function.
(arm_linux_init_abi): Register the new function and syscall xml file.
* data-directory/Makefile.in: Install the new syscall xml file.
* NEWS: Brag about this.
gdb/testsuite/
2013-08-14 Samuel Bronson <naesten@gmail.com>
ARM Linux support for `catch syscall'.
* gdb.base/catch-syscall.exp: Test this on ARM now.
(fill_all_syscalls_numbers): ARM has close/chroot on 6/61, too.
Diffstat (limited to 'gdb/arm-linux-tdep.c')
-rw-r--r-- | gdb/arm-linux-tdep.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 1502bdcfe63..6ac61cc1a14 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -33,6 +33,7 @@ #include "tramp-frame.h" #include "breakpoint.h" #include "auxv.h" +#include "xml-syscall.h" #include "arm-tdep.h" #include "arm-linux-tdep.h" @@ -794,6 +795,59 @@ arm_linux_sigreturn_return_addr (struct frame_info *frame, return 0; } +/* At a ptrace syscall-stop, return the syscall number. This either + comes from the SWI instruction (OABI) or from r7 (EABI). + + When the function fails, it should return -1. */ + +static LONGEST +arm_linux_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + struct regcache *regs = get_thread_regcache (ptid); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + ULONGEST pc; + ULONGEST cpsr; + ULONGEST t_bit = arm_psr_thumb_bit (gdbarch); + int is_thumb; + ULONGEST svc_number = -1; + + regcache_cooked_read_unsigned (regs, ARM_PC_REGNUM, &pc); + regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &cpsr); + is_thumb = (cpsr & t_bit) != 0; + + if (is_thumb) + { + regcache_cooked_read_unsigned (regs, 7, &svc_number); + } + else + { + enum bfd_endian byte_order_for_code = + gdbarch_byte_order_for_code (gdbarch); + + /* PC gets incremented before the syscall-stop, so read the + previous instruction. */ + unsigned long this_instr = + read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code); + + unsigned long svc_operand = (0x00ffffff & this_instr); + + if (svc_operand) + { + /* OABI */ + svc_number = svc_operand - 0x900000; + } + else + { + /* EABI */ + regcache_cooked_read_unsigned (regs, 7, &svc_number); + } + } + + return svc_number; +} + /* When FRAME is at a syscall instruction, return the PC of the next instruction to be executed. */ @@ -1294,6 +1348,10 @@ arm_linux_init_abi (struct gdbarch_info info, tdep->syscall_next_pc = arm_linux_syscall_next_pc; + /* `catch syscall' */ + set_xml_syscall_file_name ("syscalls/arm-linux.xml"); + set_gdbarch_get_syscall_number (gdbarch, arm_linux_get_syscall_number); + /* Syscall record. */ tdep->arm_swi_record = NULL; } |