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]

Re: [PATCH 0/4] 'catch syscall' feature



Hi Sergio,


AFAIK, we're still using the CVS repository as the official source
repo.  I don't use git.  We also ask that patches be relative to
the current top-of-tree.

However, I've done my best to massage your patch into the current
cvs tree.  I'm attaching a CVS diff based on my best effort.  Please
let me know if you can spot any mistakes.

I was able to build this, but it failed your test case
(thanks very much for including a test case, by the way).
I'm attaching my failing gdb.log.

I want to thank you for the contribution while strongly
encouraging you to resubmit it relative to CVS HEAD.

Michael

Sérgio Durigan Júnior wrote:
Hi Michael,

IMHO, the patch won't apply on CVS HEAD indeed. Also, I've used git to
generate it, so it might be easy for you to get the specific revision to
apply my patch.

The revision is: 337099393e64741ed0fbbb8c60ca3f6adb5d5974

You can easily checkout a copy of it by doing:

#> git clone git://sourceware.org/git/gdb.git
#> git reset --hard 337099393e64741ed0fbbb8c60ca3f6adb5d5974

Then the patch should apply without errors.

Well, to make things a little easier, that's the last ChangeLog entry
before mine:

2008-09-27 Tom Tromey <tromey@redhat.com>

        * NEWS: Update.
        * macrocmd.c (extract_identifier): Add is_parameter argument.
        (macro_define_command): Update.
        (macro_undef_command): Likewise.
        * macroexp.c (stringify): New function.
        (find_parameter): Likewise.
        (gather_arguments): Add nargs argument.  Handle varargs.
        (substitute_args): Add is_varargs and va_arg_name arguments.
        Handle varargs, splicing, stringification.  Use find_parameter.
        (expand): Handle varargs.


Hope that it helps :-).


Regards,

On Wed, 2008-10-01 at 15:38 -0700, Michael Snyder wrote:
Hi Sergio,

What source tree or snapshot is your diff taken from?
I tried applying it to current cvs, and got a lot of
failures and fuzzes.

Sérgio Durigan Júnior wrote:
Hello guys,

As this is my first "serious" patch to GDB, I'm sure there will be a lot
of mistakes in it :-). Anyway, I hope this adds something useful to the
program.

The purpose of this patch is to implement a new feature in GDB called
"catch syscall". In this first moment, the feature should look something
like the 'strace' utility, but less "capable" (it still can't, for
example, get the syscall arguments and return code - although, the way I
see, this would be easy to do).

With this feature, you can start over you GDB and tell it to start
catching syscalls in the inferior. Whenever a syscall is called (or
returns), GDB stops and tell you the name of it. You can also ask GDB to
"filter" the syscalls so that you'll only see calls/returns from that
specific syscall.

For now the feature is only implemented for PPC32 and PPC64, but in a
future not so distant I intend to send patches for x86 and x86_64 too.

I've tried to organize the code the best way I could, and I've
extensively used the codes for "catch fork", "catch exec" and "catch
unload" as an example. I'd be glad if you could give some opinions about
the way I did it :-).

I've also splitted the patch into 4 logical "sequences", that are
organized in this way:

- First part implements the architecture-independent part of the
feature.
- Second part implements the architecture-dependent (PPC32 and PPC64)
part of the feature.
- Third part refers to the documentation.
- Fourth part brings the testcase.

Unfortunately, if one applies the patch and compiles GDB for PPC64, it
doesn't work properly. This is due to a bug which we have found that
makes the inferior segfault when there is a breakpoint inserted at its
entrypoint (AT_ENTRY). Luis Machado is taking a closer look into this
issue, so I think he'll have a solution soon :-).

Special thanks goes to Thiago Bauermann, Luis Machado and Carlos Seo,
who helped me a lot with my never-ending questions about GDB.

Regards,

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


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


Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.352
diff -u -p -r1.352 breakpoint.c
--- breakpoint.c	16 Sep 2008 18:55:01 -0000	1.352
+++ breakpoint.c	1 Oct 2008 23:41:29 -0000
@@ -404,6 +404,18 @@ set_breakpoint_count (int num)
 		   value_from_longest (builtin_type_int32, (LONGEST) num));
 }
 
+/* Used in run_command to reset syscall catchpoints fields. */
+
+void
+clear_syscall_catchpoints_info (void)
+{
+  struct breakpoint *b;
+
+  ALL_BREAKPOINTS (b)
+    if (b->type == bp_catch_syscall)
+      b->syscall_number = UNKNOWN_SYSCALL;
+}
+
 /* Used in run_command to zero the hit count when a new run starts. */
 
 void
@@ -810,6 +822,9 @@ insert_catchpoint (struct ui_out *uo, vo
     case bp_catch_exec:
       target_insert_exec_catchpoint (PIDGET (inferior_ptid));
       break;
+    case bp_catch_syscall:
+      target_insert_syscall_catchpoint (PIDGET (inferior_ptid));
+      break;
     default:
       internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
       break;
@@ -1250,7 +1265,8 @@ Note: automatically using hardware break
 
   else if (bpt->owner->type == bp_catch_fork
 	   || bpt->owner->type == bp_catch_vfork
-	   || bpt->owner->type == bp_catch_exec)
+	   || bpt->owner->type == bp_catch_exec
+	   || bpt->owner->type == bp_catch_syscall)
     {
       struct gdb_exception e = catch_exception (uiout, insert_catchpoint,
 						bpt->owner, RETURN_MASK_ERROR);
@@ -1708,6 +1724,9 @@ remove_breakpoint (struct bp_location *b
 	case bp_catch_exec:
 	  val = target_remove_exec_catchpoint (PIDGET (inferior_ptid));
 	  break;
+	case bp_catch_syscall:
+	  val = target_remove_syscall_catchpoint (PIDGET (inferior_ptid));
+	  break;
 	default:
 	  warning (_("Internal error, %s line %d."), __FILE__, __LINE__);
 	  break;
@@ -1957,7 +1976,8 @@ ep_is_catchpoint (struct breakpoint *ep)
     || (ep->type == bp_catch_unload)
     || (ep->type == bp_catch_fork)
     || (ep->type == bp_catch_vfork)
-    || (ep->type == bp_catch_exec);
+    || (ep->type == bp_catch_exec)
+    || (ep->type == bp_catch_syscall);
 
   /* ??rehrauer: Add more kinds here, as are implemented... */
 }
@@ -2278,6 +2298,13 @@ print_it_typical (bpstat bs)
   struct cleanup *old_chain, *ui_out_chain;
   struct breakpoint *b;
   const struct bp_location *bl;
+  /* Used for "catch syscall".
+
+     This is needed because we want to know in which state a
+     syscall is. It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
+     or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we
+     must print "called syscall" or "returned from syscall". */
+  struct thread_info *th_info = find_thread_pid (inferior_ptid);
   struct ui_stream *stb;
   int bp_temp = 0;  
   stb = ui_out_stream_new (uiout);
@@ -2329,6 +2356,14 @@ print_it_typical (bpstat bs)
       return PRINT_NOTHING;
       break;
 
+    case bp_entry_breakpoint:
+       /* Not sure how we will get here.
+        GDB should not stop for these breakpoints.  */
+      internal_error (__FILE__, __LINE__,
+                      _("Entry Breakpoint: gdb should not stop!\n"));
+      return PRINT_NOTHING;
+      break;
+
     case bp_overlay_event:
       /* By analogy with the thread event, GDB should not stop for these. */
       printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
@@ -2375,6 +2410,17 @@ print_it_typical (bpstat bs)
       return PRINT_SRC_AND_LOC;
       break;
 
+    case bp_catch_syscall:
+      annotate_catchpoint (b->number);
+      printf_filtered (_("\nCatchpoint %d (%s syscall '%s ()'), "),
+                      b->number,
+                       (th_info->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+                        ? "called" : "returned from",
+                      gdbarch_syscall_name_from_number (current_gdbarch,
+                                                         b->syscall_number));
+      return PRINT_SRC_AND_LOC;
+      break;
+
     case bp_watchpoint:
     case bp_hardware_watchpoint:
       annotate_watchpoint (b->number);
@@ -2795,7 +2841,8 @@ bpstat_check_location (const struct bp_l
       && b->type != bp_hardware_breakpoint
       && b->type != bp_catch_fork
       && b->type != bp_catch_vfork
-      && b->type != bp_catch_exec)	/* a non-watchpoint bp */
+      && b->type != bp_catch_exec
+      && b->type != bp_catch_syscall)	/* a non-watchpoint bp */
     {
       if (bl->address != bp_addr) 	/* address doesn't match */
 	return 0;
@@ -2869,6 +2916,25 @@ bpstat_check_location (const struct bp_l
       && !inferior_has_execd (inferior_ptid, &b->exec_pathname))
     return 0;
 
+  /* We must check if we are catching specific syscalls in this breakpoint.
+     If we are, then we must guarantee that the called syscall is the same
+     syscall we are catching. */
+  if (b->type == bp_catch_syscall)
+    {
+      int syscall_number;
+      if (!inferior_has_called_syscall (inferior_ptid, &syscall_number))
+        return 0;
+      /* Now, checking if the syscall is the same. */
+      if (b->syscall_to_be_caught != CATCHING_ANY_SYSCALL
+          && b->syscall_to_be_caught != syscall_number)
+        /* Not the same. */
+        return 0;
+
+      /* It's the same syscall. We can update the breakpoint struct
+         with the correct information. */
+      b->syscall_number = syscall_number;
+    }
+
   return 1;
 }
 
@@ -3212,6 +3278,9 @@ bpstat_what (bpstat bs)
       /* We caught a shared library event.  */
       catch_shlib_event,
 
+      /* We are in a entry breakpoint. */
+      entry_breakpoint,
+
       /* This is just used to count how many enums there are.  */
       class_last
     };
@@ -3228,6 +3297,7 @@ bpstat_what (bpstat bs)
 #define sr BPSTAT_WHAT_STEP_RESUME
 #define shl BPSTAT_WHAT_CHECK_SHLIBS
 #define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
+#define entrybp BPSTAT_WHAT_ENTRY_BREAKPOINT
 
 /* "Can't happen."  Might want to print an error message.
    abort() is not out of the question, but chances are GDB is just
@@ -3272,30 +3342,33 @@ bpstat_what (bpstat bs)
     table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
   {
   /*                              old action */
-  /*       kc    ss    sn    sgl    slr   clr   sr   shl   shlr
+  /*       kc    ss    sn    sgl    slr   clr   sr   shl   shlr   entrybp
    */
 /*no_effect */
-    {kc, ss, sn, sgl, slr, clr, sr, shl, shlr},
+    {kc, ss, sn, sgl, slr, clr, sr, shl, shlr, shlr},
 /*wp_silent */
-    {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, sr, shl, shlr, shlr},
 /*wp_noisy */
-    {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sr, shl, shlr, shlr},
 /*bp_nostop */
-    {sgl, ss, sn, sgl, slr, slr, sr, shl, shlr},
+    {sgl, ss, sn, sgl, slr, slr, sr, shl, shlr, shlr},
 /*bp_silent */
-    {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, sr, shl, shlr, shlr},
 /*bp_noisy */
-    {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sr, shl, shlr, shlr},
 /*long_jump */
-    {slr, ss, sn, slr, slr, err, sr, shl, shlr},
+    {slr, ss, sn, slr, slr, err, sr, shl, shlr, shlr},
 /*long_resume */
-    {clr, ss, sn, err, err, err, sr, shl, shlr},
+    {clr, ss, sn, err, err, err, sr, shl, shlr, shlr},
 /*step_resume */
-    {sr, sr, sr, sr, sr, sr, sr, sr, sr},
+    {sr, sr, sr, sr, sr, sr, sr, sr, sr, sr},
 /*shlib */
-    {shl, shl, shl, shl, shl, shl, sr, shl, shlr},
+    {shl, shl, shl, shl, shl, shl, sr, shl, shlr, shl},
 /*catch_shlib */
-    {shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr}
+    {shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr, shlr},
+/* entry_breakpoint */
+    {entrybp, entrybp, entrybp, entrybp, entrybp, entrybp, sr, entrybp,
+      entrybp, entrybp}
   };
 
 #undef kc
@@ -3309,6 +3382,7 @@ bpstat_what (bpstat bs)
 #undef ts
 #undef shl
 #undef shlr
+#undef entrybp
   enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
   struct bpstat_what retval;
 
@@ -3396,6 +3470,7 @@ bpstat_what (bpstat bs)
 	case bp_catch_fork:
 	case bp_catch_vfork:
 	case bp_catch_exec:
+	case bp_catch_syscall:
 	  if (bs->stop)
 	    {
 	      if (bs->print)
@@ -3414,6 +3489,12 @@ bpstat_what (bpstat bs)
 	  bs_class = bp_silent;
 	  retval.call_dummy = 1;
 	  break;
+	case bp_entry_breakpoint:
+	  if (bs->stop)
+	    bs_class = entry_breakpoint;
+	  else
+	    bs_class = no_effect;
+	  break;
 	}
       current_action = table[(int) bs_class][(int) current_action];
     }
@@ -3577,7 +3658,9 @@ print_one_breakpoint_location (struct br
     {bp_catch_unload, "catch unload"},
     {bp_catch_fork, "catch fork"},
     {bp_catch_vfork, "catch vfork"},
-    {bp_catch_exec, "catch exec"}
+    {bp_catch_exec, "catch exec"},
+    {bp_catch_syscall, "catch syscall"},
+    {bp_entry_breakpoint, "entry breakpoint"}
   };
   
   static char bpenables[] = "nynny";
@@ -3743,6 +3826,23 @@ print_one_breakpoint_location (struct br
 	  }
 	break;
 
+      case bp_catch_syscall:
+       /* Field 4, the address, is omitted (which makes the columns
+          not line up too nicely with the headers, but the effect
+          is relatively readable).  */
+       if (addressprint)
+         ui_out_field_skip (uiout, "addr");
+       annotate_field (5);
+        ui_out_text (uiout, "syscall \"");
+        if (b->syscall_number != UNKNOWN_SYSCALL)
+          ui_out_field_string (uiout, "what",
+                       gdbarch_syscall_name_from_number (current_gdbarch,
+                                                         b->syscall_number));
+        else
+            ui_out_field_string (uiout, "what", "<unknown syscall>");
+        ui_out_text (uiout, "\" ");
+       break;
+
       case bp_breakpoint:
       case bp_hardware_breakpoint:
       case bp_until:
@@ -3755,6 +3855,7 @@ print_one_breakpoint_location (struct br
       case bp_shlib_event:
       case bp_thread_event:
       case bp_overlay_event:
+      case bp_entry_breakpoint:
 	if (addressprint)
 	  {
 	    annotate_field (4);
@@ -3944,6 +4045,7 @@ user_settable_breakpoint (const struct b
 	  || b->type == bp_catch_fork
 	  || b->type == bp_catch_vfork
 	  || b->type == bp_catch_exec
+	  || b->type == bp_catch_syscall
 	  || b->type == bp_hardware_breakpoint
 	  || b->type == bp_watchpoint
 	  || b->type == bp_read_watchpoint
@@ -4150,6 +4252,7 @@ set_default_breakpoint (int valid, CORE_
       bp_hardware_watchpoint
       bp_read_watchpoint
       bp_access_watchpoint
+      bp_catch_syscall
       bp_catch_exec
       bp_catch_fork
       bp_catch_vork */
@@ -4163,6 +4266,7 @@ breakpoint_address_is_meaningful (struct
 	  && type != bp_hardware_watchpoint
 	  && type != bp_read_watchpoint
 	  && type != bp_access_watchpoint
+	  && type != bp_catch_syscall
 	  && type != bp_catch_exec
 	  && type != bp_catch_fork
 	  && type != bp_catch_vfork);
@@ -4282,7 +4386,8 @@ adjust_breakpoint_address (CORE_ADDR bpa
            || bptype == bp_access_watchpoint
            || bptype == bp_catch_fork
            || bptype == bp_catch_vfork
-           || bptype == bp_catch_exec)
+           || bptype == bp_catch_exec
+          || bptype == bp_catch_syscall)
     {
       /* Watchpoints and the various bp_catch_* eventpoints should not
          have their addresses modified.  */
@@ -4333,6 +4438,7 @@ allocate_bp_location (struct breakpoint 
     case bp_watchpoint_scope:
     case bp_call_dummy:
     case bp_shlib_event:
+    case bp_entry_breakpoint:
     case bp_thread_event:
     case bp_overlay_event:
     case bp_catch_load:
@@ -4351,6 +4457,7 @@ allocate_bp_location (struct breakpoint 
     case bp_catch_fork:
     case bp_catch_vfork:
     case bp_catch_exec:
+    case bp_catch_syscall:
       loc->loc_type = bp_loc_other;
       break;
     default:
@@ -4396,6 +4503,8 @@ set_raw_breakpoint_without_location (enu
   b->triggered_dll_pathname = NULL;
   b->forked_inferior_pid = null_ptid;
   b->exec_pathname = NULL;
+  b->syscall_to_be_caught = CATCHING_ANY_SYSCALL;
+  b->syscall_number = UNKNOWN_SYSCALL;
   b->ops = NULL;
   b->condition_not_parsed = 0;
 
@@ -4618,6 +4727,31 @@ disable_overlay_breakpoints (void)
     }
 }
 
+int
+create_entry_breakpoint ()
+{
+  CORE_ADDR taddr, entry_addr;
+  struct breakpoint *b;
+
+  taddr = entry_point_address ();
+  /* Make certain that the address points at real code, and not a
+     function descriptor.  */
+  entry_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, taddr,
+                                                   &current_target);
+
+  /* Setting the breakpoint */
+  b = create_internal_breakpoint (entry_addr, bp_entry_breakpoint);
+
+  b->enable_state = bp_enabled;
+  b->disposition = disp_del;
+  /* addr_string has to be used or breakpoint_re_set will delete me. */
+  b->addr_string = xstrprintf ("AT_ENTRY (0x%s)", paddr (entry_addr));
+
+  update_global_location_list (1);
+
+  return 1;
+}
+
 struct breakpoint *
 create_thread_event_breakpoint (CORE_ADDR address)
 {
@@ -4817,6 +4951,31 @@ create_exec_event_catchpoint (int tempfl
   mention (b);
 }
 
+static void
+create_syscall_event_catchpoint (int tempflag, int syscall_number)
+{
+  struct symtab_and_line sal;
+  struct breakpoint *b;
+  int thread = -1;             /* All threads. */
+
+  init_sal (&sal);
+
+  b = set_raw_breakpoint (sal, bp_catch_syscall);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
+  b->cond_string = NULL;
+  b->thread = thread;
+  b->syscall_to_be_caught = syscall_number;
+  /* We still don't know the syscall that will be caught :-). */
+  b->syscall_number = UNKNOWN_SYSCALL;
+  b->addr_string = NULL;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
+  update_global_location_list (1);
+
+  mention (b);
+}
+
 static int
 hw_breakpoint_used_count (void)
 {
@@ -5034,6 +5193,16 @@ mention (struct breakpoint *b)
 	printf_filtered (_("Catchpoint %d (exec)"),
 			 b->number);
 	break;
+      case bp_catch_syscall:
+	if (b->syscall_to_be_caught != CATCHING_ANY_SYSCALL)
+	  printf_filtered (_("Catchpoint %d (syscall '%s ()')"),
+			   b->number,
+			   gdbarch_syscall_name_from_number (current_gdbarch,
+							     b->syscall_to_be_caught));
+	else
+	  printf_filtered (_("Catchpoint %d (syscall)"),
+			   b->number);
+        break;
 
       case bp_until:
       case bp_finish:
@@ -5045,6 +5214,7 @@ mention (struct breakpoint *b)
       case bp_shlib_event:
       case bp_thread_event:
       case bp_overlay_event:
+      case bp_entry_breakpoint:
 	break;
       }
 
@@ -6795,6 +6965,36 @@ catch_ada_exception_command (char *arg, 
                                    from_tty);
 }
 
+/* Implement the "catch syscall" command. */
+
+static void
+catch_syscall_command_1 (char *arg, int from_tty, struct cmd_list_element *command)
+{
+  int tempflag;
+  int syscall_number = CATCHING_ANY_SYSCALL;
+
+  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+
+  ep_skip_leading_whitespace (&arg);
+
+  /* The allowed syntax is:
+     catch syscall
+     catch syscall <name>
+
+     Let's check if there's a syscall name. */
+
+  if (arg != NULL)
+    {
+      syscall_number = gdbarch_syscall_number_from_name (current_gdbarch,
+                                                         (const char *) arg);
+      if (syscall_number == UNKNOWN_SYSCALL)
+        error (_("Invalid syscall name '%s'."), arg);
+    }
+
+  /* Now let's create the catchpoint */
+  create_syscall_event_catchpoint (tempflag, syscall_number);
+}
+
 /* Implement the "catch assert" command.  */
 
 static void
@@ -7312,6 +7512,7 @@ delete_command (char *arg, int from_tty)
 	    b->type != bp_shlib_event &&
 	    b->type != bp_thread_event &&
 	    b->type != bp_overlay_event &&
+	    b->type != bp_entry_breakpoint &&
 	    b->number >= 0)
 	  {
 	    breaks_to_delete = 1;
@@ -7329,6 +7530,7 @@ delete_command (char *arg, int from_tty)
 		b->type != bp_shlib_event &&
 		b->type != bp_thread_event &&
 		b->type != bp_overlay_event &&
+		b->type != bp_entry_breakpoint &&
 		b->number >= 0)
 	      delete_breakpoint (b);
 	  }
@@ -7620,6 +7822,7 @@ breakpoint_re_set_one (void *bint)
     case bp_catch_fork:
     case bp_catch_vfork:
     case bp_catch_exec:
+    case bp_catch_syscall:
       break;
 
     default:
@@ -7639,6 +7842,9 @@ breakpoint_re_set_one (void *bint)
 	 Once it is set up, we do not want to touch it.  */
     case bp_thread_event:
 
+      /* Same for this one */
+    case bp_entry_breakpoint:
+
       /* Keep temporary breakpoints, which can be encountered when we step
          over a dlopen call and SOLIB_ADD is resetting the breakpoints.
          Otherwise these should have been blown away via the cleanup chain
@@ -7893,6 +8099,7 @@ disable_command (char *args, int from_tt
       case bp_catch_fork:
       case bp_catch_vfork:
       case bp_catch_exec:
+      case bp_catch_syscall:
       case bp_hardware_breakpoint:
       case bp_watchpoint:
       case bp_hardware_watchpoint:
@@ -8027,6 +8234,7 @@ enable_command (char *args, int from_tty
       case bp_catch_fork:
       case bp_catch_vfork:
       case bp_catch_exec:
+      case bp_catch_syscall:
       case bp_hardware_breakpoint:
       case bp_watchpoint:
       case bp_hardware_watchpoint:
@@ -8209,6 +8417,45 @@ single_step_breakpoint_inserted_here_p (
   return 0;
 }
 
+/* Returns 0 if 'bp' is NOT a syscall catchpoint,
+   non-zero otherwise. */
+static int
+is_syscall_catchpoint_enabled (struct breakpoint *bp)
+{
+  if (bp->type == bp_catch_syscall
+      && bp->enable_state != bp_disabled
+      && bp->enable_state != bp_call_disabled)
+    return 1;
+  else
+    return 0;
+}
+
+int
+catch_syscall_enabled (void)
+{
+  struct breakpoint *bp;
+
+  ALL_BREAKPOINTS (bp)
+    if (is_syscall_catchpoint_enabled (bp))
+      return 1;
+
+  return 0;
+}
+
+int
+catching_syscall_number (int syscall_number)
+{
+  struct breakpoint *bp;
+
+  ALL_BREAKPOINTS (bp)
+    if (is_syscall_catchpoint_enabled (bp))
+      if (bp->syscall_to_be_caught == syscall_number
+          || bp->syscall_to_be_caught == CATCHING_ANY_SYSCALL)
+        return 1;
+
+  return 0;
+}
+
 
 /* This help string is used for the break, hbreak, tbreak and thbreak commands.
    It is defined as a macro to prevent duplication.
@@ -8549,6 +8796,12 @@ With an argument, catch only exceptions 
 		     catch_exec_command_1,
 		     CATCH_PERMANENT,
 		     CATCH_TEMPORARY);
+  add_catch_command ("syscall", _("\
+Catch calls to syscalls.\n\
+With an argument, catch only calls of that syscall."),
+		     catch_syscall_command_1,
+		     CATCH_PERMANENT,
+		     CATCH_TEMPORARY);
   add_catch_command ("load", _("\
 Catch library loads.\n\
 With an argument, catch only loads of that library."),
@@ -8595,7 +8848,6 @@ an expression is either read or written.
   add_info ("watchpoints", breakpoints_info,
 	    _("Synonym for ``info breakpoints''."));
 
-
   /* XXX: cagney/2005-02-23: This should be a boolean, and should
      respond to changes - contrary to the description.  */
   add_setshow_zinteger_cmd ("can-use-hw-watchpoints", class_support,
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.79
diff -u -p -r1.79 breakpoint.h
--- breakpoint.h	22 Sep 2008 15:26:53 -0000	1.79
+++ breakpoint.h	1 Oct 2008 23:41:29 -0000
@@ -32,6 +32,11 @@ struct block;
    arrays that should be independent of the target architecture.  */
 
 #define	BREAKPOINT_MAX	16
+
+/* A number to represent wether we are catching any syscalls. */
+
+#define CATCHING_ANY_SYSCALL (-1)
+
 
 /* Type of breakpoint. */
 /* FIXME In the future, we should fold all other breakpoint-like things into
@@ -127,6 +132,14 @@ enum bptype
     bp_catch_fork,
     bp_catch_vfork,
     bp_catch_exec,
+
+    /* This is not really a breakpoint, but the catchpoint which implements
+       the "catch syscall" functionality. */
+    bp_catch_syscall,
+
+    /* This type is used to signal an internal breakpoint located at
+       the AT_ENTRY address. */
+    bp_entry_breakpoint,
   };
 
 /* States of enablement of breakpoint. */
@@ -455,6 +468,21 @@ struct breakpoint
        triggered.  */
     char *exec_pathname;
 
+    /* Syscall number used for the 'catch syscall' feature.
+       If no syscall has been called, its value is UNKNOWN_SYSCALL.
+       Otherwise, it holds the system call number in the target.
+
+       This field is only valid immediately after this catchpoint has
+       triggered.  */
+    int syscall_number;
+
+    /* This field is used when we are "filtering" the syscalls
+       (i.e., when the user types "catch syscall <SYSCALL_NAME>".
+
+       It stores the syscall number in case we are in the "filter mode",
+       or CATCHING_ANY_SYSCALL otherwise. */
+    int syscall_to_be_caught;
+
     /* Methods associated with this breakpoint.  */
     struct breakpoint_ops *ops;
 
@@ -536,6 +564,10 @@ enum bpstat_what_main_action
        resume out of the dynamic linker's callback, stop and print.  */
     BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK,
 
+    /* This internal breakpoint is used syscall catchpoints only after the
+       shell and the dynamic linker have already ran. */
+    BPSTAT_WHAT_ENTRY_BREAKPOINT,
+
     /* This is just used to keep track of how many enums there are.  */
     BPSTAT_WHAT_LAST
   };
@@ -805,6 +837,8 @@ extern void enable_watchpoints_after_int
 extern enum command_control_type commands_from_control_command
   (char *arg, struct command_line *cmd);
 
+extern void clear_syscall_catchpoints_info (void);
+
 extern void clear_breakpoint_hit_counts (void);
 
 extern int get_number (char **);
@@ -884,4 +918,26 @@ extern int breakpoints_always_inserted_m
    in our opinion won't ever trigger.  */
 extern void breakpoint_retire_moribund (void);
 
+/* Checks if we are catching syscalls or not.
+   Returns 0 if not, greater than 0 if we are. */
+extern int catch_syscall_enabled (void);
+
+/* Checks if we are catching syscalls with the specific
+   syscall_number. Used for "filtering" the catchpoints.
+   Returns 0 if not, greater than 0 if we are. */
+extern int catching_syscall_number (int syscall_number);
+
+/* Function used to set an internal breakpoint at the AT_ENTRY
+   (a.k.a. the entry point of the inferior).
+
+   This is currently needed for us to know when to start setting
+   up catchpoints for syscalls in the inferior. If we don't do that,
+   then we would set a "catch syscall" too early, which would
+   catch syscalls from ld.so and/or libc (and we don't want that).
+
+   Returns zero if there was an error setting this breakpoint,
+   or 1 if everything went OK. */
+extern int create_entry_breakpoint (void);
+
+
 #endif /* !defined (BREAKPOINT_H) */
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.438
diff -u -p -r1.438 gdbarch.c
--- gdbarch.c	11 Sep 2008 14:26:59 -0000	1.438
+++ gdbarch.c	1 Oct 2008 23:41:29 -0000
@@ -240,6 +240,9 @@ struct gdbarch
   gdbarch_target_signal_from_host_ftype *target_signal_from_host;
   gdbarch_target_signal_to_host_ftype *target_signal_to_host;
   gdbarch_record_special_symbol_ftype *record_special_symbol;
+  gdbarch_get_syscall_number_ftype *get_syscall_number;
+  gdbarch_syscall_name_from_number_ftype *syscall_name_from_number;
+  gdbarch_syscall_number_from_name_ftype *syscall_number_from_name;
 };
 
 
@@ -371,6 +374,9 @@ struct gdbarch startup_gdbarch =
   default_target_signal_from_host,  /* target_signal_from_host */
   default_target_signal_to_host,  /* target_signal_to_host */
   0,  /* record_special_symbol */
+  0,  /* get_syscall_number */
+  0,  /* syscall_name_from_number */
+  0,  /* syscall_number_from_name */
   /* startup_gdbarch() */
 };
 
@@ -623,6 +629,9 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of target_signal_from_host, invalid_p == 0 */
   /* Skip verify of target_signal_to_host, invalid_p == 0 */
   /* Skip verify of record_special_symbol, has predicate */
+  /* Skip verify of get_syscall_number, has predicate */
+  /* Skip verify of syscall_name_from_number, has predicate */
+  /* Skip verify of syscall_number_from_name, has predicate */
   buf = ui_file_xstrdup (log, &dummy);
   make_cleanup (xfree, buf);
   if (strlen (buf) > 0)
@@ -832,6 +841,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: get_longjmp_target = <0x%lx>\n",
                       (long) gdbarch->get_longjmp_target);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_get_syscall_number_p() = %d\n",
+                      gdbarch_get_syscall_number_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: get_syscall_number = <0x%lx>\n",
+                      (long) gdbarch->get_syscall_number);
+  fprintf_unfiltered (file,
                       "gdbarch_dump: have_nonsteppable_watchpoint = %s\n",
                       plongest (gdbarch->have_nonsteppable_watchpoint));
   fprintf_unfiltered (file,
@@ -1051,6 +1066,18 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: static_transform_name = <0x%lx>\n",
                       (long) gdbarch->static_transform_name);
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_syscall_name_from_number_p() = %d\n",
+                      gdbarch_syscall_name_from_number_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: syscall_name_from_number = <0x%lx>\n",
+                      (long) gdbarch->syscall_name_from_number);
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_syscall_number_from_name_p() = %d\n",
+                      gdbarch_syscall_number_from_name_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: syscall_number_from_name = <0x%lx>\n",
+                      (long) gdbarch->syscall_number_from_name);
+  fprintf_unfiltered (file,
                       "gdbarch_dump: target_desc = %s\n",
                       plongest ((long) gdbarch->target_desc));
   fprintf_unfiltered (file,
@@ -3237,6 +3264,78 @@ set_gdbarch_record_special_symbol (struc
   gdbarch->record_special_symbol = record_special_symbol;
 }
 
+int
+gdbarch_get_syscall_number_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->get_syscall_number != NULL;
+}
+
+LONGEST
+gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->get_syscall_number != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_number called\n");
+  return gdbarch->get_syscall_number (gdbarch, ptid);
+}
+
+void
+set_gdbarch_get_syscall_number (struct gdbarch *gdbarch,
+                                gdbarch_get_syscall_number_ftype get_syscall_number)
+{
+  gdbarch->get_syscall_number = get_syscall_number;
+}
+
+int
+gdbarch_syscall_name_from_number_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->syscall_name_from_number != NULL;
+}
+
+const char *
+gdbarch_syscall_name_from_number (struct gdbarch *gdbarch, int syscall_number)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->syscall_name_from_number != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_syscall_name_from_number called\n");
+  return gdbarch->syscall_name_from_number (gdbarch, syscall_number);
+}
+
+void
+set_gdbarch_syscall_name_from_number (struct gdbarch *gdbarch,
+                                      gdbarch_syscall_name_from_number_ftype syscall_name_from_number)
+{
+  gdbarch->syscall_name_from_number = syscall_name_from_number;
+}
+
+int
+gdbarch_syscall_number_from_name_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->syscall_number_from_name != NULL;
+}
+
+int
+gdbarch_syscall_number_from_name (struct gdbarch *gdbarch, const char *syscall_name)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->syscall_number_from_name != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_syscall_number_from_name called\n");
+  return gdbarch->syscall_number_from_name (gdbarch, syscall_name);
+}
+
+void
+set_gdbarch_syscall_number_from_name (struct gdbarch *gdbarch,
+                                      gdbarch_syscall_number_from_name_ftype syscall_number_from_name)
+{
+  gdbarch->syscall_number_from_name = syscall_number_from_name;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.389
diff -u -p -r1.389 gdbarch.h
--- gdbarch.h	11 Sep 2008 14:26:59 -0000	1.389
+++ gdbarch.h	1 Oct 2008 23:41:29 -0000
@@ -811,6 +811,37 @@ typedef void (gdbarch_record_special_sym
 extern void gdbarch_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile, asymbol *sym);
 extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_record_special_symbol_ftype *record_special_symbol);
 
+/* Functions for the 'catch syscall' feature.
+   Get architecture-specific system calls information from registers. */
+
+extern int gdbarch_get_syscall_number_p (struct gdbarch *gdbarch);
+
+typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, ptid_t ptid);
+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);
+
+/* Translate a syscall number to its corresponding name. */
+
+extern int gdbarch_syscall_name_from_number_p (struct gdbarch *gdbarch);
+
+typedef const char * (gdbarch_syscall_name_from_number_ftype) (struct gdbarch *gdbarch, int syscall_number);
+extern const char * gdbarch_syscall_name_from_number (struct gdbarch *gdbarch, int syscall_number);
+extern void set_gdbarch_syscall_name_from_number (struct gdbarch *gdbarch, gdbarch_syscall_name_from_number_ftype *syscall_name_from_number);
+
+/* Translate a syscall name to its corresponding number.
+
+   This function must return the syscall number if found, or
+   UNKNOWN_SYSCALL if not found. */
+
+extern int gdbarch_syscall_number_from_name_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_syscall_number_from_name_ftype) (struct gdbarch *gdbarch, const char *syscall_name);
+extern int gdbarch_syscall_number_from_name (struct gdbarch *gdbarch, const char *syscall_name);
+extern void set_gdbarch_syscall_number_from_name (struct gdbarch *gdbarch, gdbarch_syscall_number_from_name_ftype *syscall_number_from_name);
+
+/* Definition for an unknown syscall, used basically in error-cases. */
+#define UNKNOWN_SYSCALL (-1)
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
 
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.479
diff -u -p -r1.479 gdbarch.sh
--- gdbarch.sh	11 Sep 2008 14:27:00 -0000	1.479
+++ gdbarch.sh	1 Oct 2008 23:41:29 -0000
@@ -707,6 +707,20 @@ m:int:target_signal_to_host:enum target_
 
 # Record architecture-specific information from the symbol table.
 M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym
+
+# Functions for the 'catch syscall' feature.
+
+# Get architecture-specific system calls information from registers.
+M:LONGEST:get_syscall_number:ptid_t ptid:ptid
+
+# Translate a syscall number to its corresponding name.
+M:const char *:syscall_name_from_number:int syscall_number:syscall_number
+
+# Translate a syscall name to its corresponding number.
+#
+# This function must return the syscall number if found, or
+# UNKNOWN_SYSCALL if not found.
+M:int:syscall_number_from_name:const char *syscall_name:syscall_name
 EOF
 }
 
@@ -888,6 +902,9 @@ done
 # close it off
 cat <<EOF
 
+/* Definition for an unknown syscall, used basically in error-cases. */
+#define UNKNOWN_SYSCALL (-1)
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
 
Index: gdbthread.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbthread.h,v
retrieving revision 1.41
diff -u -p -r1.41 gdbthread.h
--- gdbthread.h	8 Sep 2008 22:10:20 -0000	1.41
+++ gdbthread.h	1 Oct 2008 23:41:29 -0000
@@ -170,6 +170,13 @@ struct thread_info
 
   /* Private data used by the target vector implementation.  */
   struct private_thread_info *private;
+
+  /* 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;
 };
 
 /* Create an empty thread list, or empty the existing one.  */
Index: inf-child.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-child.c,v
retrieving revision 1.17
diff -u -p -r1.17 inf-child.c
--- inf-child.c	15 Mar 2008 14:55:21 -0000	1.17
+++ inf-child.c	1 Oct 2008 23:41:29 -0000
@@ -144,6 +144,21 @@ inf_child_remove_exec_catchpoint (int pi
   return 0;
 }
 
+static void
+inf_child_insert_syscall_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of syscall
+     events.  */
+}
+
+static int
+inf_child_remove_syscall_catchpoint (int pid)
+{
+  /* This version of Unix doesn't support notification of syscall
+     events.  */
+  return 0;
+}
+
 static int
 inf_child_can_run (void)
 {
@@ -187,6 +202,8 @@ inf_child_target (void)
   t->to_follow_fork = inf_child_follow_fork;
   t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint;
   t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint;
+  t->to_insert_syscall_catchpoint = inf_child_insert_syscall_catchpoint;
+  t->to_remove_syscall_catchpoint = inf_child_remove_syscall_catchpoint;
   t->to_can_run = inf_child_can_run;
   t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
   t->to_stratum = process_stratum;
Index: inf-ptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ptrace.c,v
retrieving revision 1.49
diff -u -p -r1.49 inf-ptrace.c
--- inf-ptrace.c	22 Sep 2008 15:21:30 -0000	1.49
+++ inf-ptrace.c	1 Oct 2008 23:41:29 -0000
@@ -355,13 +355,19 @@ static void
 inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
-  int request = PT_CONTINUE;
+  int request;
 
   if (pid == -1)
     /* Resume all threads.  Traditionally ptrace() only supports
        single-threaded processes, so simply resume the inferior.  */
     pid = ptid_get_pid (inferior_ptid);
 
+  if (target_passed_by_entrypoint () > 0
+      && catch_syscall_enabled () > 0)
+    request = PT_SYSCALL;
+  else
+    request = PT_CONTINUE;
+
   if (step)
     {
       /* If this system does not support PT_STEP, a higher level
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.212
diff -u -p -r1.212 infcmd.c
--- infcmd.c	22 Sep 2008 15:20:08 -0000	1.212
+++ infcmd.c	1 Oct 2008 23:41:30 -0000
@@ -450,6 +450,11 @@ run_command_1 (char *args, int from_tty,
   init_wait_for_inferior ();
   clear_breakpoint_hit_counts ();
 
+  /* If we already caught a syscall catchpoint, then reset its
+     syscall_number information because we are starting all over
+     again. */
+  clear_syscall_catchpoints_info ();
+
   /* Clean up any leftovers from other runs.  Some other things from
      this function should probably be moved into target_pre_inferior.  */
   target_pre_inferior (from_tty);
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.322
diff -u -p -r1.322 infrun.c
--- infrun.c	22 Sep 2008 15:26:53 -0000	1.322
+++ infrun.c	1 Oct 2008 23:41:30 -0000
@@ -964,7 +964,7 @@ a command like `return' or `jump' to con
         }
     }
 
-  /* If there were any forks/vforks/execs that were caught and are
+  /* If there were any forks/vforks/execs/syscalls that were caught and are
      now to be followed, then do so.  */
   switch (pending_follow.kind)
     {
@@ -980,6 +980,11 @@ a command like `return' or `jump' to con
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
       break;
 
+    case TARGET_WAITKIND_SYSCALL_ENTRY:
+    case TARGET_WAITKIND_SYSCALL_RETURN:
+      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+      break;
+
     default:
       break;
     }
@@ -1386,8 +1391,8 @@ init_wait_for_inferior (void)
 
   breakpoint_init_inferior (inf_starting);
 
-  /* The first resume is not following a fork/vfork/exec. */
-  pending_follow.kind = TARGET_WAITKIND_SPURIOUS;	/* I.e., none. */
+  /* The first resume is not following a fork/vfork/exec/syscall.  */
+  pending_follow.kind = TARGET_WAITKIND_SPURIOUS;	/* I.e., none.  */
 
   clear_proceed_status ();
 
@@ -1831,6 +1836,50 @@ ensure_not_running (void)
     error_is_running ();
 }
 
+/* Auxiliary function that handles syscall entry/return events.
+   It returns 1 if the inferior should keep going (and GDB
+   should ignore the event), or 0 if the event deserves to be
+   processed. */
+static int
+deal_with_syscall_event (struct execution_control_state *ecs)
+{
+  int syscall_number = gdbarch_get_syscall_number (current_gdbarch,
+                                                   ecs->ptid);
+  if (catch_syscall_enabled () > 0
+      && catching_syscall_number (syscall_number) > 0)
+    {
+      ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+      pending_follow.kind = ecs->ws.kind;
+
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+        {
+          context_switch (ecs->ptid);
+          reinit_frame_cache ();
+        }
+
+      stop_pc = read_pc ();
+
+      ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
+
+      ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+
+      /* If no catchpoint triggered for this, then keep going.  */
+      if (ecs->random_signal)
+        {
+          ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+          keep_going (ecs);
+          return 1;
+        }
+      return 0;
+    }
+  else
+    {
+      resume (0, TARGET_SIGNAL_0);
+      prepare_to_wait (ecs);
+      return 1;
+    }
+}
+
 /* Given an execution control state that has been freshly filled in
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
@@ -2119,9 +2168,11 @@ handle_inferior_event (struct execution_
     case TARGET_WAITKIND_SYSCALL_ENTRY:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
-      resume (0, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+      /* Getting the current syscall number */
+      if (deal_with_syscall_event (ecs) != 0)
+        return;
+      goto process_event_stop_test;
+      break;
 
       /* Before examining the threads further, step this thread to
          get it entirely out of the syscall.  (We get notice of the
@@ -2131,9 +2182,10 @@ handle_inferior_event (struct execution_
     case TARGET_WAITKIND_SYSCALL_RETURN:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+      if (deal_with_syscall_event (ecs) != 0)
+        return;
+      goto process_event_stop_test;
+      break;
 
     case TARGET_WAITKIND_STOPPED:
       if (debug_infrun)
@@ -2951,6 +3003,16 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	}
 	break;
 
+      case BPSTAT_WHAT_ENTRY_BREAKPOINT:
+        /* We hit the AT_ENTRY breakpoint, and now we have to enable
+           the PTRACE_O_TRACESYSGOOD option in the inferior *if* we
+           are catching syscalls. */
+        if (debug_infrun)
+          fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_ENTRY_BREAKPOINT\n");
+        target_enable_tracesysgood (ecs->ptid);
+        ecs->event_thread->stepping_over_breakpoint = 1;
+        break;
+
       case BPSTAT_WHAT_LAST:
 	/* Not a real code, but listed here to shut up gcc -Wall.  */
 
@@ -4563,6 +4625,25 @@ inferior_has_execd (ptid_t pid, char **e
   return 1;
 }
 
+int
+inferior_has_called_syscall (ptid_t pid, int *syscall_number)
+{
+  struct target_waitstatus last;
+  ptid_t last_ptid;
+
+  get_last_target_status (&last_ptid, &last);
+
+  if (last.kind != TARGET_WAITKIND_SYSCALL_ENTRY &&
+      last.kind != TARGET_WAITKIND_SYSCALL_RETURN)
+    return 0;
+
+  if (!ptid_equal (last_ptid, pid))
+    return 0;
+
+  *syscall_number = last.value.syscall_number;
+  return 1;
+}
+
 /* Oft used ptids */
 ptid_t null_ptid;
 ptid_t minus_one_ptid;
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.184
diff -u -p -r1.184 target.c
--- target.c	22 Sep 2008 15:21:30 -0000	1.184
+++ target.c	1 Oct 2008 23:41:30 -0000
@@ -426,6 +426,10 @@ update_current_target (void)
       /* Do not inherit to_follow_fork.  */
       INHERIT (to_insert_exec_catchpoint, t);
       INHERIT (to_remove_exec_catchpoint, t);
+      INHERIT (to_passed_by_entrypoint, t);
+      INHERIT (to_insert_syscall_catchpoint, t);
+      INHERIT (to_remove_syscall_catchpoint, t);
+      INHERIT (to_enable_tracesysgood, t);
       INHERIT (to_has_exited, t);
       INHERIT (to_mourn_inferior, t);
       INHERIT (to_can_run, t);
@@ -581,9 +585,21 @@ update_current_target (void)
   de_fault (to_insert_exec_catchpoint,
 	    (void (*) (int))
 	    tcomplain);
+  de_fault (to_passed_by_entrypoint,
+	    (int (*) (void))
+	    tcomplain);
   de_fault (to_remove_exec_catchpoint,
 	    (int (*) (int))
 	    tcomplain);
+  de_fault (to_insert_syscall_catchpoint,
+	    (void (*) (int))
+	    tcomplain);
+  de_fault (to_remove_syscall_catchpoint,
+	    (int (*) (int))
+	    tcomplain);
+  de_fault (to_enable_tracesysgood,
+	    (void (*) (ptid_t))
+	    tcomplain);
   de_fault (to_has_exited,
 	    (int (*) (int, int, int *))
 	    return_zero);
@@ -2532,6 +2548,12 @@ debug_to_wait (ptid_t ptid, struct targe
     case TARGET_WAITKIND_EXECD:
       fprintf_unfiltered (gdb_stdlog, "execd\n");
       break;
+    case TARGET_WAITKIND_SYSCALL_ENTRY:
+      fprintf_unfiltered (gdb_stdlog, "entered syscall\n");
+      break;
+    case TARGET_WAITKIND_SYSCALL_RETURN:
+      fprintf_unfiltered (gdb_stdlog, "exited syscall\n");
+      break;
     case TARGET_WAITKIND_SPURIOUS:
       fprintf_unfiltered (gdb_stdlog, "spurious\n");
       break;
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.130
diff -u -p -r1.130 target.h
--- target.h	19 Aug 2008 13:22:14 -0000	1.130
+++ target.h	1 Oct 2008 23:41:30 -0000
@@ -135,14 +135,15 @@ struct target_waitstatus
   {
     enum target_waitkind kind;
 
-    /* Forked child pid, execd pathname, exit status or signal number.  */
+    /* Forked child pid, execd pathname, exit status, signal number or
+       syscall name.  */
     union
       {
 	int integer;
 	enum target_signal sig;
 	ptid_t related_pid;
 	char *execd_pathname;
-	int syscall_id;
+	int syscall_number;
       }
     value;
   };
@@ -393,6 +394,10 @@ struct target_ops
     int (*to_follow_fork) (struct target_ops *, int);
     void (*to_insert_exec_catchpoint) (int);
     int (*to_remove_exec_catchpoint) (int);
+    int (*to_passed_by_entrypoint) (void);
+    void (*to_insert_syscall_catchpoint) (int);
+    int (*to_remove_syscall_catchpoint) (int);
+    void (*to_enable_tracesysgood) (ptid_t);
     int (*to_has_exited) (int, int, int *);
     void (*to_mourn_inferior) (void);
     int (*to_can_run) (void);
@@ -708,6 +713,8 @@ extern int inferior_has_vforked (ptid_t 
 
 extern int inferior_has_execd (ptid_t pid, char **execd_pathname);
 
+extern int inferior_has_called_syscall (ptid_t pid, int *syscall_number);
+
 /* From exec.c */
 
 extern void print_section_info (struct target_ops *, bfd *);
@@ -867,6 +874,24 @@ int target_follow_fork (int follow_child
 #define target_remove_exec_catchpoint(pid) \
      (*current_target.to_remove_exec_catchpoint) (pid)
 
+/* Has the inferior already passed through its entrypoint? */
+#define target_passed_by_entrypoint() \
+     (*current_target.to_passed_by_entrypoint) ()
+
+/* Syscall catch functions */
+
+#define target_insert_syscall_catchpoint(pid) \
+     (*current_target.to_insert_syscall_catchpoint) (pid)
+
+#define target_remove_syscall_catchpoint(pid) \
+     (*current_target.to_remove_syscall_catchpoint) (pid)
+
+/* Enable PTRACE_O_TRACESYSGOOD in the inferior.
+   This is mainly used for the "catch syscall" feature. */
+
+#define target_enable_tracesysgood(ptid) \
+     (*current_target.to_enable_tracesysgood) (ptid)
+
 /* Returns TRUE if PID has exited.  And, also sets EXIT_STATUS to the
    exit code of PID, if any.  */
 
Index: linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.106
diff -u -p -r1.106 linux-nat.c
--- linux-nat.c	25 Sep 2008 14:13:44 -0000	1.106
+++ linux-nat.c	1 Oct 2008 23:34:45 -0000
@@ -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 };
@@ -609,6 +625,41 @@ linux_test_for_tracefork (int original_p
   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.  */
 
@@ -629,11 +680,33 @@ linux_supports_tracevforkdone (int pid)
 }
 
 
+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);
@@ -641,15 +714,16 @@ linux_enable_event_reporting (ptid_t pti
   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
@@ -664,6 +738,12 @@ linux_child_post_startup_inferior (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
@@ -890,6 +970,19 @@ linux_child_insert_exec_catchpoint (int 
     error (_("Your system does not support exec catchpoints."));
 }
 
+static void
+linux_child_insert_syscall_catchpoint (int pid)
+{
+  if (! linux_supports_tracesysgood (pid))
+    error (_("Your system does not support syscall catchpoints."));
+}
+
+static int
+linux_child_remove_syscall_catchpoint (int pid)
+{
+  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
@@ -1310,6 +1403,9 @@ linux_nat_create_inferior (char *exec_fi
   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.  */
 
@@ -1940,6 +2036,27 @@ linux_handle_extended_wait (struct lwp_i
       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);
+          struct thread_info *th_info = find_thread_pid (lp->ptid);
+
+          ourstatus->kind =
+            (th_info->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY) ?
+            TARGET_WAITKIND_SYSCALL_RETURN : TARGET_WAITKIND_SYSCALL_ENTRY;
+          th_info->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);
 }
@@ -2550,11 +2667,16 @@ linux_nat_filter_event (int lwpid, int s
     }
 
   /* 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,
@@ -4000,6 +4122,8 @@ linux_target_install_ops (struct target_
   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_insert_syscall_catchpoint = linux_child_insert_syscall_catchpoint;
+  t->to_remove_syscall_catchpoint = linux_child_remove_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;
@@ -4007,6 +4131,9 @@ linux_target_install_ops (struct target_
   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;
 }
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.107
diff -u -p -r1.107 ppc-linux-tdep.c
--- ppc-linux-tdep.c	26 Aug 2008 15:16:41 -0000	1.107
+++ ppc-linux-tdep.c	1 Oct 2008 23:34:45 -0000
@@ -47,6 +47,142 @@
 #include "features/rs6000/powerpc-vsx64l.c"
 #include "features/rs6000/powerpc-e500l.c"
 
+/* Total number of syscalls */
+#define N_SYSCALLS 301
+
+/* Syscalls names for PPC 32-bit */
+static const char *syscalls_names[] = {
+    "restart_syscall", "exit", "fork", "read",
+    "write", "open", "close", "waitpid", "creat",
+    "link", "unlink", "execve", "chdir", "time",
+    "mknod", "chmod", "lchown", "break", "oldstat",
+    "lseek", "getpid", "mount", "umount", "setuid",
+    "getuid", "stime", "ptrace", "alarm", "oldfstat",
+    "pause", "utime", "stty", "gtty", "access", "nice",
+    "ftime", "sync", "kill", "rename", "mkdir", "rmdir",
+    "dup", "pipe", "times", "prof", "brk", "setgid",
+    "getgid", "signal", "geteuid", "getegid", "acct",
+    "umount2", "lock", "ioctl", "fcntl", "mpx", "setpgid",
+    "ulimit", "oldolduname", "umask", "chroot", "ustat",
+    "dup2", "getppid", "getpgrp", "setsid", "sigaction",
+    "sgetmask", "ssetmask", "setreuid", "setregid",
+    "sigsuspend", "sigpending", "sethostname", "setrlimit",
+    "getrlimit", "getrusage", "gettimeofday", "settimeofday",
+    "getgroups", "setgroups", "select", "symlink", "oldlstat",
+    "readlink",  "uselib", "swapon", "reboot", "readdir",
+    "mmap", "munmap", "truncate", "ftruncate", "fchmod",
+    "fchown", "getpriority", "setpriority", "profil",
+    "statfs", "fstatfs", "ioperm", "socketcall", "syslog",
+    "setitimer", "getitimer", "stat", "lstat", "fstat",
+    "olduname", "iopl", "vhangup", "idle", "vm86", "wait4",
+    "swapoff", "sysinfo", "ipc", "fsync", "sigreturn",
+    "clone", "setdomainname", "uname", "modify_ldt",
+    "adjtimex", "mprotect", "sigprocmask", "create_module",
+    "init_module", "delete_module", "get_kernel_syms",
+    "quotactl", "getpgid", "fchdir", "bdflush", "sysfs",
+    "personality", "afs_syscall", "setfsuid", "setfsgid",
+    "_llseek", "getdents", "_newselect", "flock", "msync",
+    "readv", "writev", "getsid", "fdatasync", "_sysctl",
+    "mlock", "munlock", "mlockall", "munlockall",
+    "sched_setparam", "sched_getparam", "sched_setscheduler",
+    "sched_getscheduler", "sched_yield",
+    "sched_get_priority_max", "sched_get_priority_min",
+    "sched_rr_get_interval", "nanosleep", "mremap",
+    "setresuid", "getresuid", "query_module", "poll",
+    "nfsservctl", "setresgid", "getresgid", "prctl",
+    "rt_sigreturn", "rt_sigaction", "rt_sigprocmask",
+    "rt_sigpending", "rt_sigtimedwait", "rt_sigqueueinfo",
+    "rt_sigsuspend", "pread64", "pwrite64", "chown",
+    "getcwd", "capget", "capset", "sigaltstack", "sendfile",
+    "getpmsg", "putpmsg", "vfork", "ugetrlimit", "readahead",
+    "mmap2", "truncate64", "ftruncate64", "stat64", "lstat64",
+    "fstat64", "pciconfig_read", "pciconfig_write",
+    "pciconfig_iobase", "multiplexer", "getdents64",
+    "pivot_root", "fcntl64", "madvise", "mincore", "gettid",
+    "tkill", "setxattr", "lsetxattr", "fsetxattr",
+    "getxattr", "lgetxattr", "fgetxattr", "listxattr",
+    "llistxattr", "flistxattr", "removexattr", "lremovexattr",
+    "fremovexattr", "futex", "sched_setaffinity",
+    "sched_getaffinity", "", "tuxcall", "sendfile64",
+    "io_setup", "io_destroy", "io_getevents", "io_submit",
+    "io_cancel", "set_tid_address", "fadvise64", "exit_group",
+    "lookup_dcookie", "epoll_create", "epoll_ctl",
+    "epoll_wait", "remap_file_pages", "timer_create",
+    "timer_settime", "timer_gettime", "timer_getoverrun",
+    "timer_delete", "clock_settime", "clock_gettime",
+    "clock_getres", "clock_nanosleep", "swapcontext",
+    "tgkill", "utimes", "statfs64", "fstatfs64", "fadvise64_64",
+    "rtas", "sys_debug_setcontext", "", "", "mbind",
+    "get_mempolicy", "set_mempolicy", "mq_open", "mq_unlink",
+    "mq_timedsend", "mq_timedreceive", "mq_notify",
+    "mq_getsetattr", "kexec_load", "add_key", "request_key",
+    "keyctl", "waitid", "ioprio_set", "ioprio_get",
+    "inotify_init", "inotify_add_watch", "inotify_rm_watch",
+    "spu_run", "spu_create", "pselect6", "ppoll", "unshare",
+    "", "", "", "openat", "mkdirat", "mknodat", "fchownat",
+    "futimesat", "fstatat64", "unlinkat", "renameat",
+    "linkat", "symlinkat", "readlinkat", "fchmodat",
+    "faccessat", "", ""
+};
+
+/* Syscalls names for PPC 64-bit */
+static const char *syscalls_names64[] = {
+    "restart_syscall", "exit", "fork", "read", "write", "open",
+    "close", "waitpid", "creat", "link", "unlink", "execve",
+    "chdir", "time", "mknod", "chmod", "lchown", "break", "oldstat",
+    "lseek", "getpid", "mount", "umount", "setuid", "getuid", "stime",
+    "ptrace", "alarm", "oldfstat", "pause", "utime", "stty", "gtty",
+    "access", "nice", "ftime", "sync", "kill", "rename", "mkdir",
+    "rmdir", "dup", "pipe", "times", "prof", "brk", "setgid",
+    "getgid", "signal", "geteuid", "getegid", "acct", "umount2",
+    "lock", "ioctl", "fcntl", "mpx", "setpgid", "ulimit",
+    "oldolduname", "umask", "chroot", "ustat", "dup2", "getppid",
+    "getpgrp", "setsid", "sigaction", "sgetmask", "ssetmask",
+    "setreuid", "setregid", "sigsuspend", "sigpending", "sethostname",
+    "setrlimit", "getrlimit", "getrusage", "gettimeofday", "settimeofday",
+    "getgroups", "setgroups", "select", "symlink", "oldlstat",
+    "readlink", "uselib", "swapon", "reboot", "readdir", "mmap",
+    "munmap", "truncate", "ftruncate", "fchmod", "fchown", "getpriority",
+    "setpriority", "profil", "statfs", "fstatfs", "ioperm", "socketcall",
+    "syslog", "setitimer", "getitimer", "stat", "lstat", "fstat",
+    "olduname", "iopl", "vhangup", "idle", "vm86", "wait4", "swapoff",
+    "sysinfo", "ipc", "fsync", "sigreturn", "clone", "setdomainname",
+    "uname", "modify_ldt", "adjtimex", "mprotect", "sigprocmask",
+    "create_module", "init_module", "delete_module", "get_kernel_syms",
+    "quotactl", "getpgid", "fchdir", "bdflush", "sysfs", "personality",
+    "afs_syscall", "setfsuid", "setfsgid", "_llseek", "getdents",
+    "_newselect", "flock", "msync", "readv", "writev", "getsid",
+    "fdatasync", "_sysctl", "mlock", "munlock", "mlockall",
+    "munlockall", "sched_setparam", "sched_getparam", "sched_setscheduler",
+    "sched_getscheduler", "sched_yield", "sched_get_priority_max",
+    "sched_get_priority_min", "sched_rr_get_interval", "nanosleep",
+    "mremap", "setresuid", "getresuid", "query_module", "poll",
+    "nfsservctl", "setresgid", "getresgid", "prctl", "rt_sigreturn",
+    "rt_sigaction", "rt_sigprocmask", "rt_sigpending", "rt_sigtimedwait",
+    "rt_sigqueueinfo", "rt_sigsuspend", "pread64", "pwrite64", "chown",
+    "getcwd", "capget", "capset", "sigaltstack", "sendfile", "getpmsg",
+    "putpmsg", "vfork", "ugetrlimit", "readahead", "", "", "", "", "", "",
+    "pciconfig_read", "pciconfig_write", "pciconfig_iobase", "multiplexer",
+    "getdents64", "pivot_root", "", "madvise", "mincore", "gettid", "tkill",
+    "setxattr", "lsetxattr", "fsetxattr", "getxattr", "lgetxattr", "fgetxattr",
+    "listxattr", "llistxattr", "flistxattr", "removexattr", "lremovexattr",
+    "fremovexattr", "futex", "sched_setaffinity", "sched_getaffinity",
+    "", "tuxcall", "", "io_setup", "io_destroy", "io_getevents", "io_submit",
+    "io_cancel", "set_tid_address", "fadvise64", "exit_group", "lookup_dcookie",
+    "epoll_create", "epoll_ctl", "epoll_wait", "remap_file_pages",
+    "timer_create", "timer_settime", "timer_gettime", "timer_getoverrun",
+    "timer_delete", "clock_settime", "clock_gettime", "clock_getres",
+    "clock_nanosleep", "swapcontext", "tgkill", "utimes", "statfs64",
+    "fstatfs64", "", "rtas", "sys_debug_setcontext", "", "", "mbind",
+    "get_mempolicy", "set_mempolicy", "mq_open", "mq_unlink", "mq_timedsend",
+    "mq_timedreceive", "mq_notify", "mq_getsetattr", "kexec_load", "add_key",
+    "request_key", "keyctl", "waitid", "ioprio_set", "ioprio_get",
+    "inotify_init", "inotify_add_watch", "inotify_rm_watch", "spu_run",
+    "spu_create", "pselect6", "ppoll", "unshare", "", "", "",
+    "openat", "mkdirat", "mknodat", "fchownat", "futimesat", "newfstatat",
+    "unlinkat", "renameat", "linkat", "symlinkat", "readlinkat",
+    "fchmodat", "faccessat", "", ""
+};
 
 /* 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 +1139,83 @@ ppc_linux_trap_reg_p (struct gdbarch *gd
          && 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. */
+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);
+  /* 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));
+
+  /* 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);
+  xfree (buf);
+
+  return ret;
+}
+
+const char *
+ppc_linux_syscall_name_from_number (struct gdbarch *gdbarch,
+                                    int syscall_number)
+{
+  if (syscall_number < 0
+      || syscall_number >= N_SYSCALLS)
+    return NULL;
+
+  return syscalls_names[syscall_number];
+}
+
+const char *
+ppc64_linux_syscall_name_from_number (struct gdbarch *gdbarch,
+                                      int syscall_number)
+{
+  if (syscall_number < 0
+      || syscall_number >= N_SYSCALLS)
+    return NULL;
+
+  return syscalls_names64[syscall_number];
+}
+
+int
+ppc_linux_syscall_number_from_name (struct gdbarch *gdbarch,
+                                    const char *syscall_name)
+{
+  int i;
+
+  for (i = 0; i < N_SYSCALLS; i++)
+    if (strcmp (syscall_name, syscalls_names[i]) == 0)
+      return i;
+
+  return UNKNOWN_SYSCALL;
+}
+
+int
+ppc64_linux_syscall_number_from_name (struct gdbarch *gdbarch,
+                                      const char *syscall_name)
+{
+  int i;
+
+  for (i = 0; i < N_SYSCALLS; i++)
+    if (strcmp (syscall_name, syscalls_names64[i]) == 0)
+      return i;
+
+  return UNKNOWN_SYSCALL;
+}
+
 static void
 ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
@@ -1074,8 +1287,13 @@ ppc_linux_init_abi (struct gdbarch_info 
   /* Handle inferior calls during interrupted system calls.  */
   set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc);
 
+  set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number);
+
   if (tdep->wordsize == 4)
     {
+      set_gdbarch_syscall_name_from_number (gdbarch, ppc_linux_syscall_name_from_number);
+      set_gdbarch_syscall_number_from_name (gdbarch, ppc_linux_syscall_number_from_name);
+
       /* Until November 2001, gcc did not comply with the 32 bit SysV
 	 R4 ABI requirement that structures less than or equal to 8
 	 bytes should be returned in registers.  Instead GCC was using
@@ -1100,6 +1318,9 @@ ppc_linux_init_abi (struct gdbarch_info 
   
   if (tdep->wordsize == 8)
     {
+      set_gdbarch_syscall_name_from_number (gdbarch, ppc64_linux_syscall_name_from_number);
+      set_gdbarch_syscall_number_from_name (gdbarch, ppc64_linux_syscall_number_from_name);
+
       /* Handle PPC GNU/Linux 64-bit function pointers (which are really
 	 function descriptors).  */
       set_gdbarch_convert_from_func_ptr_addr
Test Run By msnyder on Wed Oct  1 16:42:57 2008
Native configuration is i686-pc-linux-gnu

		=== gdb tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.exp ...
Executing on host: gcc /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c  -g  -lm   -o /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall    (timeout = 300)
GNU gdb (GDB) 6.8.50.20081001-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) set height 0
(gdb) set width 0
(gdb) dir
Reinitialize source path to empty? (y or n) y
Source directories searched: $cdir:$cwd
(gdb) dir /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base
Source directories searched: /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base:$cdir:$cwd
(gdb) kill
The program is not being run.
(gdb) file /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall
Reading symbols from /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall...done.
(gdb) help catch syscall
Catch calls to syscalls.
With an argument, catch only calls of that syscall.
(gdb) PASS: gdb.base/catch-syscall.exp: help catch syscall
catch syscall nonsense_syscall
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: gdb.base/catch-syscall.exp: catch syscall to a nonsense syscall is prohibited (GDB internal error)
n
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
(gdb) delete breakpoints
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break main
Breakpoint 1 at 0x80483f8: file /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c, line 19.
(gdb) run 
Starting program: /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall 

Breakpoint 1, main () at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
19	       close (-1);
(gdb) catch syscall
Catchpoint 2 (syscall)
(gdb) PASS: gdb.base/catch-syscall.exp: setting catch syscall without arguments
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) PASS: gdb.base/catch-syscall.exp: catch syscall appears in 'info breakpoints'
continue
Continuing.

Program exited normally.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'close'
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' has returned (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'chroot' (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' has returned (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'exit_group' (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
2       catch syscall  keep y              syscall "<unknown syscall>" 
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'exit_group' appears in 'info breakpoints'
delete breakpoints
Delete all breakpoints? (y or n) y
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: successful program end (the program is no longer running)
delete breakpoints
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break main
Breakpoint 3 at 0x80483f8: file /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c, line 19.
(gdb) run 
Starting program: /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall 

Breakpoint 3, main () at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
19	       close (-1);
(gdb) catch syscall close
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: gdb.base/catch-syscall.exp: catch syscall with arguments (close) (GDB internal error)
n
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
3       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: catch syscall appears in 'info breakpoints'
continue
Continuing.

Program exited normally.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'close'
info breakpoints
Num     Type           Disp Enb Address    What
3       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' has returned (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
3       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'close' appears in 'info breakpoints'
delete breakpoints
Delete all breakpoints? (y or n) y
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: successful program end (the program is no longer running)
delete breakpoints
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break main
Breakpoint 4 at 0x80483f8: file /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c, line 19.
(gdb) run 
Starting program: /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall 

Breakpoint 4, main () at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
19	       close (-1);
(gdb) catch syscall mlock
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: gdb.base/catch-syscall.exp: catch syscall with arguments (mlock) (GDB internal error)
n
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: catch syscall appears in 'info breakpoints'
continue
Continuing.

Program exited normally.
(gdb) PASS: gdb.base/catch-syscall.exp: catch syscall with unused syscall (mlock)
delete breakpoints
Delete all breakpoints? (y or n) y
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break main
Breakpoint 5 at 0x80483f8: file /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c, line 19.
(gdb) run 
Starting program: /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall 

Breakpoint 5, main () at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
19	       close (-1);
(gdb) catch syscall chroot
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: gdb.base/catch-syscall.exp: catch syscall with arguments (chroot) (GDB internal error)
n
/misc/home/msnyder/cvs/localhost/src-current/gdb/gdbarch.c:3326: internal-error: gdbarch_syscall_number_from_name: Assertion `gdbarch->syscall_number_from_name != NULL' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) n
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: catch syscall appears in 'info breakpoints'
continue
Continuing.

Program exited normally.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'chroot'
info breakpoints
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' appears in 'info breakpoints'
run
Starting program: /misc/home/msnyder/build/native/src-current/gdb/testsuite/gdb.base/catch-syscall 

Breakpoint 5, main () at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
19	       close (-1);
(gdb) PASS: gdb.base/catch-syscall.exp: rerun to main
continue
Continuing.

Program exited normally.
(gdb) FAIL: gdb.base/catch-syscall.exp: program has called 'chroot'
info breakpoints
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' appears in 'info breakpoints'
continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' has returned (the program is no longer running)
info breakpoints
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x080483f8 in main at /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.c:19
	breakpoint already hit 1 time
(gdb) FAIL: gdb.base/catch-syscall.exp: syscall 'chroot' appears in 'info breakpoints'
delete breakpoints
Delete all breakpoints? (y or n) y
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) continue
The program is not being run.
(gdb) FAIL: gdb.base/catch-syscall.exp: successful program end (the program is no longer running)
testcase /misc/home/msnyder/cvs/localhost/src-current/gdb/testsuite/gdb.base/catch-syscall.exp completed in 0 seconds

		=== gdb Summary ===

# of expected passes		5
# of unexpected failures	30
Executing on host: /misc/home/msnyder/build/native/src-current/gdb/testsuite/../../gdb/gdb -nw --command gdb_cmd    (timeout = 300)
GNU gdb (GDB) 6.8.50.20081001-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
/misc/home/msnyder/build/native/src-current/gdb/testsuite/../../gdb/gdb version  6.8.50.20081001-cvs -nx

runtest completed at Wed Oct  1 16:42:58 2008

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