From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21142 invoked by alias); 26 Jan 2009 00:31:05 -0000 Received: (qmail 20932 invoked by uid 22791); 26 Jan 2009 00:30:56 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_40,J_CHICKENPOX_13 X-Spam-Check-By: sourceware.org Received: from e24smtp01.br.ibm.com (HELO e24smtp01.br.ibm.com) (32.104.18.85) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 26 Jan 2009 00:30:48 +0000 Received: from d24relay01.br.ibm.com (d24relay01.br.ibm.com [9.8.31.16]) by e24smtp01.br.ibm.com (8.13.1/8.13.1) with ESMTP id n0Q0Z1vA029129 for ; Sun, 25 Jan 2009 22:35:01 -0200 Received: from d24av02.br.ibm.com (d24av02.br.ibm.com [9.18.232.47]) by d24relay01.br.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id n0Q1UEup3895346 for ; Sun, 25 Jan 2009 22:30:14 -0300 Received: from d24av02.br.ibm.com (loopback [127.0.0.1]) by d24av02.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id n0Q0Ui30003648 for ; Sun, 25 Jan 2009 22:30:44 -0200 Received: from [9.8.5.52] ([9.8.5.52]) by d24av02.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id n0Q0Uidj003633; Sun, 25 Jan 2009 22:30:44 -0200 Subject: [PATCH 2/4] catch syscall -- try 4 -- Architecture-dependent part From: =?ISO-8859-1?Q?S=E9rgio?= Durigan =?ISO-8859-1?Q?J=FAnior?= To: gdb-patches@sourceware.org Cc: teawater Content-Type: multipart/mixed; boundary="=-FseWXy1/LIM7KA+hdbsJ" Date: Mon, 26 Jan 2009 00:31:00 -0000 Message-Id: <1232929833.26873.23.camel@miki> Mime-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-01/txt/msg00485.txt.bz2 --=-FseWXy1/LIM7KA+hdbsJ Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Content-length: 2387 Here is the architecture-dependent part of the patch. It's worth noting that the current supported architectures are x86, PPC and PPC64. I intend to submit a patch for x86_64 ASAP. Regards, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil gdb/ChangeLog: 2009-01-25 Sergio Durigan Junior * i386-linux-nat.c (i386_linux_resume): Select the proper request to be made for ptrace() considering if we are catching syscalls or not. * i386-linux-tdep.c: Include linux-tdep.h header, define the XML syscall name for the architecture. (i386_linux_get_syscall_number): New. (i386_linux_init_abi): Call linux_tdep_init to initialize common functions. Register the correct functions for syscall catchpoint. * linux-nat.c: Define some helpful variables to track wether we have support for the needed ptrace() option. (linux_test_for_tracesysgood): New. (linux_supports_tracesysgood): New. (linux_enable_tracesysgood): New. (linux_passed_by_entrypoint): New. (linux_enable_event_reporting): Save the current used ptrace() options. (linux_child_set_syscall_catchpoint): New function. (linux_child_post_startup_inferior): Create the entry breakpoint. (linux_child_insert_syscall_catchpoint): New. (linux_child_remove_syscall_catchpoint): New. (linux_nat_create_inferior): Properly set the flag which indicates if the inferior have already passed through its entrypoint. (linux_handle_extended_wait): Handle the case which the inferior stops because it has called or returned from a syscall. (linux_nat_filter_event): Likewise. (linux_target_install_ops): Install the necessary functions to handle syscall catchpoints and entry breakpoints. * linux-nat.h (struct lwp_info): Include syscall_state into the structure, which indicates if we are in a syscall entry or return. * linux-tdep.c: New file. (init_sysinfo): New function. (linux_get_syscall_by_number): Likewise. (linux_get_syscall_by_name): Likewise. (linux_get_syscall_names): Likewise. (linux_tdep_init): Likewise. * linux-tdep.h: New file. * ppc-linux-tdep.c: Include linux-tdep.h header, define the XML syscall filename for the arch. (ppc_linux_get_syscall_number): New. (ppc_linux_init_abi): Call linux_tdep_init to initialize common functions. Register the correct functions for syscall catchpoint. --=-FseWXy1/LIM7KA+hdbsJ Content-Disposition: attachment; filename=catch-syscall-arch-dep.patch Content-Type: text/x-patch; name=catch-syscall-arch-dep.patch; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 19793 diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 493ae7f..da5e707 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -748,7 +748,13 @@ i386_linux_resume (ptid_t ptid, int step, enum target_signal signal) { int pid = PIDGET (ptid); - int request = PTRACE_CONT; + int request; + + if (target_passed_by_entrypoint () > 0 + && catch_syscall_enabled () > 0) + request = PTRACE_SYSCALL; + else + request = PTRACE_CONT; if (step) { diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 81c8d31..7fdfdac 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -36,6 +36,10 @@ #include "symtab.h" #include "arch-utils.h" #include "regset.h" +#include "linux-tdep.h" + +/* The syscall's XML filename for i386. */ +#define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml" /* Supported register note sections. */ static struct core_regset_section i386_linux_regset_sections[] = @@ -348,6 +352,26 @@ i386_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) } +static LONGEST +i386_linux_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + struct regcache *regcache = get_thread_regcache (ptid); + /* The content of a register. */ + gdb_byte buf[4]; + /* The result. */ + LONGEST ret; + + /* Getting the system call number from the register. + When dealing with x86 architecture, this information + is stored at %eax register. */ + regcache_cooked_read (regcache, I386_LINUX_ORIG_EAX_REGNUM, buf); + + ret = extract_signed_integer (buf, 4); + + return ret; +} + /* The register sets used in GNU/Linux ELF core-dumps are identical to the register sets in `struct user' that are used for a.out core-dumps. These are also used by ptrace(2). The corresponding @@ -418,6 +442,9 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* Initializing common functions. */ + linux_tdep_init (gdbarch); + /* GNU/Linux uses ELF. */ i386_elf_init_abi (info, gdbarch); @@ -469,6 +496,11 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) simple_displaced_step_free_closure); set_gdbarch_displaced_step_location (gdbarch, displaced_step_at_entry_point); + + /* Functions for 'catch syscall'. */ + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_I386); + set_gdbarch_get_syscall_number (gdbarch, + i386_linux_get_syscall_number); } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 1d0f66f..c5c20f2 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -61,6 +61,10 @@ # endif #endif /* HAVE_PERSONALITY */ +/* To be used when one needs to know wether a + WSTOPSIG (status) is a syscall */ +#define TRAP_IS_SYSCALL (SIGTRAP | 0x80) + /* This comment documents high-level logic of this file. Waiting for events in sync mode @@ -273,17 +277,29 @@ struct simple_pid_list *stopped_pids; static int linux_supports_tracefork_flag = -1; +/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACESYSGOOD + can not be used, 1 if it can. */ + +static int linux_supports_tracesysgood_flag = -1; + /* If we have PTRACE_O_TRACEFORK, this flag indicates whether we also have PTRACE_O_TRACEVFORKDONE. */ static int linux_supports_tracevforkdone_flag = -1; +/* If the inferior have passed through its entrypoint (AT_ENTRY), + then this flag is set to 1. Otherwise, its value is 0. */ +static int linux_passed_by_entrypoint_flag = 0; + /* Async mode support */ /* Zero if the async mode, although enabled, is masked, which means linux_nat_wait should behave as if async mode was off. */ static int linux_nat_async_mask_value = 1; +/* Stores the current used ptrace() options. */ +static int current_ptrace_options = 0; + /* The read/write ends of the pipe registered as waitable file in the event loop. */ static int linux_nat_event_pipe[2] = { -1, -1 }; @@ -628,6 +644,41 @@ linux_test_for_tracefork (int original_pid) linux_nat_async_events (async_events_original_state); } +/* Determine if PTRACE_O_TRACESYSGOOD can be used to follow syscalls. + + We try to enable syscall tracing on ORIGINAL_PID. If this fails, + we know that the feature is not available. This may change the tracing + options for ORIGINAL_PID, but we'll be setting them shortly anyway. */ + +static void +linux_test_for_tracesysgood (int original_pid) +{ + int ret; + enum sigchld_state async_events_original_state; + + async_events_original_state = linux_nat_async_events (sigchld_sync); + + linux_supports_tracesysgood_flag = 0; + + ret = ptrace (PTRACE_SETOPTIONS, original_pid, 0, PTRACE_O_TRACESYSGOOD); + if (ret != 0) + return; + + linux_supports_tracesysgood_flag = 1; + linux_nat_async_events (async_events_original_state); +} + +/* Determine wether we support PTRACE_O_TRACESYSGOOD option available. + This function also sets linux_supports_tracesysgood_flag. */ + +static int +linux_supports_tracesysgood (int pid) +{ + if (linux_supports_tracesysgood_flag == -1) + linux_test_for_tracesysgood (pid); + return linux_supports_tracesysgood_flag; +} + /* Return non-zero iff we have tracefork functionality available. This function also sets linux_supports_tracefork_flag. */ @@ -647,12 +698,34 @@ linux_supports_tracevforkdone (int pid) return linux_supports_tracevforkdone_flag; } +static void +linux_enable_tracesysgood (ptid_t ptid) +{ + int pid = ptid_get_lwp (ptid); + + if (pid == 0) + pid = ptid_get_pid (ptid); + + if (linux_supports_tracesysgood (pid) == 0) + return; + + current_ptrace_options |= PTRACE_O_TRACESYSGOOD; + linux_passed_by_entrypoint_flag = 1; + + ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); +} + +static int +linux_passed_by_entrypoint (void) +{ + return linux_passed_by_entrypoint_flag; +} + void linux_enable_event_reporting (ptid_t ptid) { int pid = ptid_get_lwp (ptid); - int options; if (pid == 0) pid = ptid_get_pid (ptid); @@ -660,15 +733,16 @@ linux_enable_event_reporting (ptid_t ptid) if (! linux_supports_tracefork (pid)) return; - options = PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEEXEC - | PTRACE_O_TRACECLONE; + current_ptrace_options |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK + | PTRACE_O_TRACEEXEC | PTRACE_O_TRACECLONE; + if (linux_supports_tracevforkdone (pid)) - options |= PTRACE_O_TRACEVFORKDONE; + current_ptrace_options |= PTRACE_O_TRACEVFORKDONE; /* Do not enable PTRACE_O_TRACEEXIT until GDB is more prepared to support read-only process state. */ - ptrace (PTRACE_SETOPTIONS, pid, 0, options); + ptrace (PTRACE_SETOPTIONS, pid, 0, current_ptrace_options); } static void @@ -917,6 +991,16 @@ linux_child_insert_exec_catchpoint (int pid) error (_("Your system does not support exec catchpoints.")); } +static int +linux_child_set_syscall_catchpoint (int pid, int needed, int any_count, + int table_size, int *table) +{ + if (! linux_supports_tracesysgood (pid)) + error (_("Your system does not support syscall catchpoints.")); + /* We ignore the arguments. */ + return 0; +} + /* On GNU/Linux there are no real LWP's. The closest thing to LWP's are processes sharing the same VM space. A multi-threaded process is basically a group of such processes. However, such a grouping @@ -1338,6 +1422,9 @@ linux_nat_create_inferior (struct target_ops *ops, int personality_orig = 0, personality_set = 0; #endif /* HAVE_PERSONALITY */ + /* We are sarting, so we still have not passed through our entrypoint. */ + linux_passed_by_entrypoint_flag = 0; + /* The fork_child mechanism is synchronous and calls target_wait, so we have to mask the async mode. */ @@ -1980,6 +2067,26 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, return 0; } + /* Used for 'catch syscall' feature. */ + if (WSTOPSIG (status) == TRAP_IS_SYSCALL) + { + if (catch_syscall_enabled () == 0) + ourstatus->kind = TARGET_WAITKIND_IGNORE; + else + { + struct regcache *regcache = get_thread_regcache (lp->ptid); + struct gdbarch *gdbarch = get_regcache_arch (regcache); + + ourstatus->kind = + (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY) ? + TARGET_WAITKIND_SYSCALL_RETURN : TARGET_WAITKIND_SYSCALL_ENTRY; + lp->syscall_state = ourstatus->kind; + ourstatus->value.syscall_number = + (int) gdbarch_get_syscall_number (gdbarch, lp->ptid); + } + return 0; + } + internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event); } @@ -2590,11 +2697,16 @@ linux_nat_filter_event (int lwpid, int status, int options) } /* Save the trap's siginfo in case we need it later. */ - if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP) + if (WIFSTOPPED (status) + && (WSTOPSIG (status) == SIGTRAP || WSTOPSIG (status) == TRAP_IS_SYSCALL)) save_siginfo (lp); - /* Handle GNU/Linux's extended waitstatus for trace events. */ - if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0) + /* Handle GNU/Linux's extended waitstatus for trace events. + It is necessary to check if WSTOPSIG is signaling a that + the inferior is entering/exiting a system call. */ + if (WIFSTOPPED (status) + && ((WSTOPSIG (status) == TRAP_IS_SYSCALL) + || (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0))) { if (debug_linux_nat) fprintf_unfiltered (gdb_stdlog, @@ -4156,6 +4268,7 @@ linux_target_install_ops (struct target_ops *t) t->to_insert_fork_catchpoint = linux_child_insert_fork_catchpoint; t->to_insert_vfork_catchpoint = linux_child_insert_vfork_catchpoint; t->to_insert_exec_catchpoint = linux_child_insert_exec_catchpoint; + t->to_set_syscall_catchpoint = linux_child_set_syscall_catchpoint; t->to_pid_to_exec_file = linux_child_pid_to_exec_file; t->to_post_startup_inferior = linux_child_post_startup_inferior; t->to_post_attach = linux_child_post_attach; diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h index 13a1088..e31cd93 100644 --- a/gdb/linux-nat.h +++ b/gdb/linux-nat.h @@ -70,6 +70,13 @@ struct lwp_info or to a local variable in lin_lwp_wait. */ struct target_waitstatus waitstatus; + /* Signal wether we are in a SYSCALL_ENTRY or + in a SYSCALL_RETURN event. + Values: + - TARGET_WAITKIND_SYSCALL_ENTRY + - TARGET_WAITKIND_SYSCALL_RETURN */ + int syscall_state; + /* Next LWP in list. */ struct lwp_info *next; }; diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c new file mode 100644 index 0000000..0500766 --- /dev/null +++ b/gdb/linux-tdep.c @@ -0,0 +1,117 @@ +/* Target-dependent code for GDB, the GNU debugger. + + Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "frame.h" +#include "inferior.h" +#include "symtab.h" +#include "target.h" +#include "gdbcore.h" +#include "gdbcmd.h" +#include "symfile.h" +#include "objfiles.h" +#include "regcache.h" +#include "value.h" +#include "osabi.h" +#include "regset.h" +#include "solib-svr4.h" +#include "trad-frame.h" +#include "frame-unwind.h" +#include "tramp-frame.h" +#include "xml-syscall.h" + +/* Structure used to store information about the available syscalls in + the system. */ +static const struct syscalls_info *sysinfo = NULL; + +/* A flag to tell if we already initialized the structure above. */ +static int have_initialized_sysinfo = 0; + +/* The filename of the syscall's XML. */ +static const char *xml_syscall_file = NULL; + +/* Initializes the syscalls_info structure according to the + architecture. */ +static void +init_sysinfo (struct gdbarch *gdbarch) +{ + /* Did we already try to initialize the structure? */ + if (have_initialized_sysinfo) + return; + + if (xml_syscall_file == NULL) + xml_syscall_file = gdbarch_xml_syscall_filename (gdbarch); + + sysinfo = xml_init_syscalls_info (xml_syscall_file); + + have_initialized_sysinfo = 1; + + if (sysinfo == NULL) + { + if (xml_syscall_file) + /* The initialization failed. Let's show a warning + message to the user (just this time) and leave. */ + warning (_("Could not load the syscall XML file '%s'.\n\ +GDB will not be able to display syscall names."), xml_syscall_file); + else + /* There's no file to open. Let's warn the user. */ + warning (_("There is no XML file to open.\n\ +GDB will not be able to display syscall names.")); + } +} + +static void +linux_get_syscall_by_number (struct gdbarch *gdbarch, + int syscall_number, + struct syscall *s) +{ + init_sysinfo (gdbarch); + + s->number = syscall_number; + s->name = xml_get_syscall_name (sysinfo, syscall_number); +} + +static void +linux_get_syscall_by_name (struct gdbarch *gdbarch, + const char *syscall_name, + struct syscall *s) +{ + init_sysinfo (gdbarch); + + s->number = xml_get_syscall_number (sysinfo, syscall_name); + s->name = syscall_name; +} + +static const char ** +linux_get_syscall_names (struct gdbarch *gdbarch) +{ + init_sysinfo (gdbarch); + + return xml_list_of_syscalls (sysinfo); +} + +void +linux_tdep_init (struct gdbarch *gdbarch) +{ + set_gdbarch_get_syscall_by_number (gdbarch, linux_get_syscall_by_number); + set_gdbarch_get_syscall_by_name (gdbarch, linux_get_syscall_by_name); + set_gdbarch_get_syscall_names (gdbarch, linux_get_syscall_names); +} diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h new file mode 100644 index 0000000..968fd58 --- /dev/null +++ b/gdb/linux-tdep.h @@ -0,0 +1,27 @@ +/* Target-dependent code for GDB, the GNU debugger. + + Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef LINUX_TDEP_H +#define LINUX_TDEP_H 1 + +extern void linux_tdep_init (struct gdbarch *gdbarch); + +#endif /* LINUX_TDEP_H */ diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 7f13188..674ebb4 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -38,6 +38,7 @@ #include "trad-frame.h" #include "frame-unwind.h" #include "tramp-frame.h" +#include "linux-tdep.h" #include "features/rs6000/powerpc-32l.c" #include "features/rs6000/powerpc-altivec32l.c" @@ -53,6 +54,9 @@ #include "features/rs6000/powerpc-isa205-vsx64l.c" #include "features/rs6000/powerpc-e500l.c" +/* The syscall's XML filename for PPC and PPC64. */ +#define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml" +#define XML_SYSCALL_FILENAME_PPC64 "syscalls/ppc64-linux.xml" /* ppc_linux_memory_remove_breakpoints attempts to remove a breakpoint in much the same fashion as memory_remove_breakpoint in mem-break.c, @@ -1009,6 +1013,38 @@ ppc_linux_trap_reg_p (struct gdbarch *gdbarch) && register_size (gdbarch, PPC_TRAP_REGNUM) > 0; } +/* Return the current system call's number present in the + r0 register. When the function fails, it returns -1. */ +static LONGEST +ppc_linux_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + struct regcache *regcache = get_thread_regcache (ptid); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct cleanup *cleanbuf; + /* The content of a register */ + gdb_byte *buf; + /* The result */ + LONGEST ret; + + /* Make sure we're in a 32- or 64-bit machine */ + gdb_assert (tdep->wordsize == 4 || tdep->wordsize == 8); + + buf = (gdb_byte *) xmalloc (tdep->wordsize * sizeof (gdb_byte)); + + cleanbuf = make_cleanup (xfree, buf); + + /* Getting the system call number from the register. + When dealing with PowerPC architecture, this information + is stored at 0th register. */ + regcache_cooked_read (regcache, tdep->ppc_gp0_regnum, buf); + + ret = extract_signed_integer (buf, tdep->wordsize); + do_cleanups (cleanbuf); + + return ret; +} + static void ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) { @@ -1069,6 +1105,9 @@ ppc_linux_init_abi (struct gdbarch_info info, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; + /* Initializing common methods. */ + linux_tdep_init (gdbarch); + /* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where 128-bit, they are IBM long double, not IEEE quad long double as in the System V ABI PowerPC Processor Supplement. We can safely @@ -1080,6 +1119,9 @@ ppc_linux_init_abi (struct gdbarch_info info, /* Handle inferior calls during interrupted system calls. */ set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc); + /* Get the syscall number from the arch's register. */ + set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number); + if (tdep->wordsize == 4) { /* Until November 2001, gcc did not comply with the 32 bit SysV @@ -1099,6 +1141,9 @@ ppc_linux_init_abi (struct gdbarch_info info, set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); + /* Setting the correct XML syscall filename. */ + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_PPC); + /* Trampolines. */ tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sigaction_tramp_frame); tramp_frame_prepend_unwinder (gdbarch, &ppc32_linux_sighandler_tramp_frame); @@ -1116,6 +1161,9 @@ ppc_linux_init_abi (struct gdbarch_info info, set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); + /* Setting the correct XML syscall filename. */ + set_gdbarch_xml_syscall_filename (gdbarch, XML_SYSCALL_FILENAME_PPC64); + /* Trampolines. */ tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame); tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame); --=-FseWXy1/LIM7KA+hdbsJ--