This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/4] catch syscall -- try 3 -- Architecture-dependent part


That's the arch-dependent part of the patch.

Regards,

-- 
Sérgio Durigan Júnior
Linux on Power Toolchain - Software Engineer
Linux Technology Center - LTC
IBM Brazil

gdb/ChangeLog:

2008-11-18  Sergio Durigan Junior  <sergiodj@linux.vnet.ibm.com>

	* 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.
	* 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 filename for the arch.
	(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_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.
	* 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.

diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 146f5a6..c634275 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 5284f4a..fe7ce00 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 913bfec..7f72568 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -57,6 +57,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
@@ -269,17 +273,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 };
@@ -624,6 +640,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.  */
 
@@ -643,12 +694,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);
@@ -656,15 +729,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
@@ -679,6 +753,12 @@ linux_child_post_startup_inferior (ptid_t ptid)
 {
   linux_enable_event_reporting (ptid);
   check_for_thread_db ();
+  /* We have to create the entry breakpoint here because
+     if we have 'catch syscall' enabled, we ought to know
+     when to enable PTRACE_O_TRACESYSGOOD.  Otherwise, we would
+     start catching syscalls from ld.so/libc (which is not
+     what we want).  */
+  create_entry_breakpoint ();
 }
 
 static int
@@ -905,6 +985,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
@@ -1326,6 +1416,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.  */
 
@@ -1956,6 +2049,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);
 }
@@ -2566,11 +2679,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,
@@ -4023,6 +4141,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;
@@ -4030,6 +4149,9 @@ linux_target_install_ops (struct target_ops *t)
   t->to_find_memory_regions = linux_nat_find_memory_regions;
   t->to_make_corefile_notes = linux_nat_make_corefile_notes;
 
+  t->to_enable_tracesysgood = linux_enable_tracesysgood;
+  t->to_passed_by_entrypoint = linux_passed_by_entrypoint;
+
   super_xfer_partial = t->to_xfer_partial;
   t->to_xfer_partial = linux_xfer_partial;
 }
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index a25719b..0fca44b 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 <http://www.gnu.org/licenses/>.  */
+
+#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 <http://www.gnu.org/licenses/>.  */
+
+#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 2804857..9480a90 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"
@@ -47,6 +48,9 @@
 #include "features/rs6000/powerpc-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,
@@ -1003,6 +1007,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)
 {
@@ -1063,6 +1099,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
@@ -1074,6 +1113,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
@@ -1093,6 +1135,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);
@@ -1110,6 +1155,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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]