Blob Blame History Raw
2008-03-30  Daniel Jacobowitz  <dan@codesourcery.com>

	* ia64-tdep.c (examine_prologue): Correct array access.

===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -r1.172 -r1.173
--- src/gdb/ia64-tdep.c	2008/02/20 14:31:40	1.172
+++ src/gdb/ia64-tdep.c	2008/03/31 03:38:48	1.173
@@ -1234,7 +1234,7 @@
 	      spill_reg   = rN;
 	      last_prologue_pc = next_pc;
 	    }
-	  else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && 
+	  else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] && 
 		   rN < 256 && imm == 0)
 	    {
 	      /* mov rN, rM where rM is an input register */



https://bugzilla.redhat.com/show_bug.cgi?id=442765

http://sourceware.org/ml/gdb-patches/2008-03/msg00281.html
http://sourceware.org/ml/gdb-cvs/2008-03/msg00114.html

2008-03-21  Daniel Jacobowitz  <dan@codesourcery.com>

	* gdbthread.h (add_thread_with_info): New.
	* linux-thread-db.c: Add some documentation.
	(GET_LWP, GET_PID, GET_THREAD, is_lwp, is_thread, BUILD_LWP): Delete.
	(struct private_thread_info): Remove th_valid and ti_valid.
	Replace ti with tid.
	(thread_get_info_callback): Do not add TID to the new ptid.  Do
	not cache th or ti.
	(thread_db_map_id2thr, lwp_from_thread): Delete functions.
	(thread_from_lwp): Assert that the LWP is set.  Do not add TID to the
	new PTID.
	(attach_thread): Handle an already-existing thread.  Use
	add_thread_with_info.  Cache the th and tid.
	(detach_thread): Verify that private was set.  Remove verbose
	argument and printing.  Update caller.
	(thread_db_detach): Do not adjust inferior_ptid.
	(clear_lwpid_callback, thread_db_resume, thread_db_kill): Delete.
	(check_event, find_new_threads_callback): Do not add TID to the new PTID.
	(thread_db_wait): Do not use lwp_from_thread.
	(thread_db_pid_to_str): Use the cached TID.
	(thread_db_extra_thread_info): Check that private is set.
	(same_ptid_callback): Delete.
	(thread_db_get_thread_local_address): Do not use it or check
	is_thread.  Check that private is set.  Assume that the thread
	handle is already cached.
	(init_thread_db_ops): Remove to_resume and to_kill.
	* thread.c (add_thread_with_info): New.
	(add_thread): Use it.
	* linux-nat.c (find_thread_from_lwp): Delete.
	(exit_lwp): Do not use it.  Check print_thread_events.  Print before
	deleting the thread.
	(GET_PID, GET_LWP, BUILD_LWP, is_lwp): Move to...
	* linux-nat.h (GET_PID, GET_LWP, BUILD_LWP, is_lwp): ...here.
	* inf-ttrace.c (inf_ttrace_wait): Use print_thread_events and
	printf_unfiltered for thread exits.
	* procfs.c (procfs_wait): Likewise.

2008-03-21  Pedro Alves  <pedro@codesourcery.com>

	* gdb.threads/fork-child-threads.exp: Test next over fork.

===================================================================
RCS file: /cvs/src/src/gdb/gdbthread.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- src/gdb/gdbthread.h	2008/03/15 13:53:25	1.20
+++ src/gdb/gdbthread.h	2008/03/21 15:44:53	1.21
@@ -81,6 +81,10 @@
    about new thread.  */
 extern struct thread_info *add_thread_silent (ptid_t ptid);
 
+/* Same as add_thread, and sets the private info.  */
+extern struct thread_info *add_thread_with_info (ptid_t ptid,
+						 struct private_thread_info *);
+
 /* Delete an existing thread list entry.  */
 extern void delete_thread (ptid_t);
 
===================================================================
RCS file: /cvs/src/src/gdb/inf-ttrace.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- src/gdb/inf-ttrace.c	2008/01/29 21:11:24	1.27
+++ src/gdb/inf-ttrace.c	2008/03/21 15:44:53	1.28
@@ -964,7 +964,8 @@
       break;
 
     case TTEVT_LWP_EXIT:
-      printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid));
+      if (print_thread_events)
+	printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
       ti = find_thread_pid (ptid);
       gdb_assert (ti != NULL);
       ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -u -r1.76 -r1.77
--- src/gdb/linux-nat.c	2008/03/17 14:54:07	1.76
+++ src/gdb/linux-nat.c	2008/03/21 15:44:53	1.77
@@ -588,11 +588,6 @@
 static int num_lwps;
 
 
-#define GET_LWP(ptid)		ptid_get_lwp (ptid)
-#define GET_PID(ptid)		ptid_get_pid (ptid)
-#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
-#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
-
 /* If the last reported event was a SIGTRAP, this variable is set to
    the process id of the LWP/thread that got it.  */
 ptid_t trap_ptid;
@@ -813,20 +808,6 @@
       p = &(*p)->next;
 }
 
-/* Callback for iterate_over_threads that finds a thread corresponding
-   to the given LWP.  */
-
-static int
-find_thread_from_lwp (struct thread_info *thr, void *dummy)
-{
-  ptid_t *ptid_p = dummy;
-
-  if (GET_LWP (thr->ptid) && GET_LWP (thr->ptid) == GET_LWP (*ptid_p))
-    return 1;
-  else
-    return 0;
-}
-
 /* Handle the exit of a single thread LP.  */
 
 static void
@@ -834,32 +815,14 @@
 {
   if (in_thread_list (lp->ptid))
     {
+      if (print_thread_events)
+	printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid));
+
       /* Core GDB cannot deal with us deleting the current thread.  */
       if (!ptid_equal (lp->ptid, inferior_ptid))
 	delete_thread (lp->ptid);
       else
 	record_dead_thread (lp->ptid);
-      printf_unfiltered (_("[%s exited]\n"),
-			 target_pid_to_str (lp->ptid));
-    }
-  else
-    {
-      /* Even if LP->PTID is not in the global GDB thread list, the
-	 LWP may be - with an additional thread ID.  We don't need
-	 to print anything in this case; thread_db is in use and
-	 already took care of that.  But it didn't delete the thread
-	 in order to handle zombies correctly.  */
-
-      struct thread_info *thr;
-
-      thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
-      if (thr)
-	{
-	  if (!ptid_equal (thr->ptid, inferior_ptid))
-	    delete_thread (thr->ptid);
-	  else
-	    record_dead_thread (thr->ptid);
-	}
     }
 
   delete_lwp (lp->ptid);
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- src/gdb/linux-nat.h	2008/01/23 11:26:28	1.22
+++ src/gdb/linux-nat.h	2008/03/21 15:44:53	1.23
@@ -83,6 +83,11 @@
        (LP) != NULL;							\
        (LP) = (LP)->next, (PTID) = (LP) ? (LP)->ptid : (PTID))
 
+#define GET_LWP(ptid)		ptid_get_lwp (ptid)
+#define GET_PID(ptid)		ptid_get_pid (ptid)
+#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
+#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
+
 /* Attempt to initialize libthread_db.  */
 void check_for_thread_db (void);
 
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- src/gdb/linux-thread-db.c	2008/01/23 11:26:28	1.37
+++ src/gdb/linux-thread-db.c	2008/03/21 15:44:53	1.38
@@ -48,6 +48,32 @@
 #define LIBTHREAD_DB_SO "libthread_db.so.1"
 #endif
 
+/* GNU/Linux libthread_db support.
+
+   libthread_db is a library, provided along with libpthread.so, which
+   exposes the internals of the thread library to a debugger.  It
+   allows GDB to find existing threads, new threads as they are
+   created, thread IDs (usually, the result of pthread_self), and
+   thread-local variables.
+
+   The libthread_db interface originates on Solaris, where it is
+   both more powerful and more complicated.  This implementation
+   only works for LinuxThreads and NPTL, the two glibc threading
+   libraries.  It assumes that each thread is permanently assigned
+   to a single light-weight process (LWP).
+
+   libthread_db-specific information is stored in the "private" field
+   of struct thread_info.  When the field is NULL we do not yet have
+   information about the new thread; this could be temporary (created,
+   but the thread library's data structures do not reflect it yet)
+   or permanent (created using clone instead of pthread_create).
+
+   Process IDs managed by linux-thread-db.c match those used by
+   linux-nat.c: a common PID for all processes, an LWP ID for each
+   thread, and no TID.  We save the TID in private.  Keeping it out
+   of the ptid_t prevents thread IDs changing when libpthread is
+   loaded or unloaded.  */
+
 /* If we're running on GNU/Linux, we must explicitly attach to any new
    threads.  */
 
@@ -119,19 +145,7 @@
 static void thread_db_find_new_threads (void);
 static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
 			   const td_thrinfo_t *ti_p);
-static void detach_thread (ptid_t ptid, int verbose);
-
-
-/* Building process ids.  */
-
-#define GET_PID(ptid)		ptid_get_pid (ptid)
-#define GET_LWP(ptid)		ptid_get_lwp (ptid)
-#define GET_THREAD(ptid)	ptid_get_tid (ptid)
-
-#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
-#define is_thread(ptid)		(GET_THREAD (ptid) != 0)
-
-#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
+static void detach_thread (ptid_t ptid);
 
 
 /* Use "struct private_thread_info" to cache thread state.  This is
@@ -143,11 +157,8 @@
   unsigned int dying:1;
 
   /* Cached thread state.  */
-  unsigned int th_valid:1;
-  unsigned int ti_valid:1;
-
   td_thrhandle_t th;
-  td_thrinfo_t ti;
+  thread_t tid;
 };
 
 
@@ -257,7 +268,7 @@
 	   thread_db_err_str (err));
 
   /* Fill the cache.  */
-  thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid);
+  thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0);
   thread_info = find_thread_pid (thread_ptid);
 
   /* In the case of a zombie thread, don't continue.  We don't want to
@@ -266,13 +277,6 @@
     {
       if (infop != NULL)
         *(struct thread_info **) infop = thread_info;
-      if (thread_info != NULL)
-	{
-	  memcpy (&thread_info->private->th, thp, sizeof (*thp));
-	  thread_info->private->th_valid = 1;
-	  memcpy (&thread_info->private->ti, &ti, sizeof (ti));
-	  thread_info->private->ti_valid = 1;
-	}
       return TD_THR_ZOMBIE;
     }
 
@@ -284,39 +288,11 @@
       gdb_assert (thread_info != NULL);
     }
 
-  memcpy (&thread_info->private->th, thp, sizeof (*thp));
-  thread_info->private->th_valid = 1;
-  memcpy (&thread_info->private->ti, &ti, sizeof (ti));
-  thread_info->private->ti_valid = 1;
-
   if (infop != NULL)
     *(struct thread_info **) infop = thread_info;
 
   return 0;
 }
-
-/* Accessor functions for the thread_db information, with caching.  */
-
-static void
-thread_db_map_id2thr (struct thread_info *thread_info, int fatal)
-{
-  td_err_e err;
-
-  if (thread_info->private->th_valid)
-    return;
-
-  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
-			    &thread_info->private->th);
-  if (err != TD_OK)
-    {
-      if (fatal)
-	error (_("Cannot find thread %ld: %s"),
-	       (long) GET_THREAD (thread_info->ptid),
-	       thread_db_err_str (err));
-    }
-  else
-    thread_info->private->th_valid = 1;
-}
 
 /* Convert between user-level thread ids and LWP ids.  */
 
@@ -328,10 +304,9 @@
   struct thread_info *thread_info;
   ptid_t thread_ptid;
 
-  if (GET_LWP (ptid) == 0)
-    ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
-
-  gdb_assert (is_lwp (ptid));
+  /* This ptid comes from linux-nat.c, which should always fill in the
+     LWP.  */
+  gdb_assert (GET_LWP (ptid) != 0);
 
   err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
   if (err != TD_OK)
@@ -352,16 +327,8 @@
       && thread_info == NULL)
     return pid_to_ptid (-1);
 
-  gdb_assert (thread_info && thread_info->private->ti_valid);
-
-  return ptid_build (GET_PID (ptid), GET_LWP (ptid),
-		     thread_info->private->ti.ti_tid);
-}
-
-static ptid_t
-lwp_from_thread (ptid_t ptid)
-{
-  return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid));
+  gdb_assert (ptid_get_tid (ptid) == 0);
+  return ptid;
 }
 
 
@@ -672,7 +639,8 @@
 attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
 	       const td_thrinfo_t *ti_p)
 {
-  struct thread_info *tp;
+  struct private_thread_info *private;
+  struct thread_info *tp = NULL;
   td_err_e err;
 
   /* If we're being called after a TD_CREATE event, we may already
@@ -690,10 +658,21 @@
       tp = find_thread_pid (ptid);
       gdb_assert (tp != NULL);
 
-      if (!tp->private->dying)
-        return;
+      /* If tp->private is NULL, then GDB is already attached to this
+	 thread, but we do not know anything about it.  We can learn
+	 about it here.  This can only happen if we have some other
+	 way besides libthread_db to notice new threads (i.e.
+	 PTRACE_EVENT_CLONE); assume the same mechanism notices thread
+	 exit, so this can not be a stale thread recreated with the
+	 same ID.  */
+      if (tp->private != NULL)
+	{
+	  if (!tp->private->dying)
+	    return;
 
-      delete_thread (ptid);
+	  delete_thread (ptid);
+	  tp = NULL;
+	}
     }
 
   check_thread_signals ();
@@ -702,13 +681,28 @@
     return;			/* A zombie thread -- do not attach.  */
 
   /* Under GNU/Linux, we have to attach to each and every thread.  */
-  if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
+  if (tp == NULL
+      && lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
     return;
 
+  /* Construct the thread's private data.  */
+  private = xmalloc (sizeof (struct private_thread_info));
+  memset (private, 0, sizeof (struct private_thread_info));
+
+  /* A thread ID of zero may mean the thread library has not initialized
+     yet.  But we shouldn't even get here if that's the case.  FIXME:
+     if we change GDB to always have at least one thread in the thread
+     list this will have to go somewhere else; maybe private == NULL
+     until the thread_db target claims it.  */
+  gdb_assert (ti_p->ti_tid != 0);
+  private->th = *th_p;
+  private->tid = ti_p->ti_tid;
+
   /* Add the thread to GDB's thread list.  */
-  tp = add_thread (ptid);
-  tp->private = xmalloc (sizeof (struct private_thread_info));
-  memset (tp->private, 0, sizeof (struct private_thread_info));
+  if (tp == NULL)
+    tp = add_thread_with_info (ptid, private);
+  else
+    tp->private = private;
 
   /* Enable thread event reporting for this thread.  */
   err = td_thr_event_enable_p (th_p, 1);
@@ -718,22 +712,20 @@
 }
 
 static void
-detach_thread (ptid_t ptid, int verbose)
+detach_thread (ptid_t ptid)
 {
   struct thread_info *thread_info;
 
-  if (verbose)
-    printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
-
   /* Don't delete the thread now, because it still reports as active
      until it has executed a few instructions after the event
      breakpoint - if we deleted it now, "info threads" would cause us
      to re-attach to it.  Just mark it as having had a TD_DEATH
      event.  This means that we won't delete it from our thread list
      until we notice that it's dead (via prune_threads), or until
-     something re-uses its thread ID.  */
+     something re-uses its thread ID.  We'll report the thread exit
+     when the underlying LWP dies.  */
   thread_info = find_thread_pid (ptid);
-  gdb_assert (thread_info != NULL);
+  gdb_assert (thread_info != NULL && thread_info->private != NULL);
   thread_info->private->dying = 1;
 }
 
@@ -742,47 +734,12 @@
 {
   disable_thread_event_reporting ();
 
-  /* There's no need to save & restore inferior_ptid here, since the
-     inferior is not supposed to survive this function call.  */
-  inferior_ptid = lwp_from_thread (inferior_ptid);
-
   target_beneath->to_detach (args, from_tty);
 
   /* Should this be done by detach_command?  */
   target_mourn_inferior ();
 }
 
-static int
-clear_lwpid_callback (struct thread_info *thread, void *dummy)
-{
-  /* If we know that our thread implementation is 1-to-1, we could save
-     a certain amount of information; it's not clear how much, so we
-     are always conservative.  */
-
-  thread->private->th_valid = 0;
-  thread->private->ti_valid = 0;
-
-  return 0;
-}
-
-static void
-thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
-{
-  struct cleanup *old_chain = save_inferior_ptid ();
-
-  if (GET_PID (ptid) == -1)
-    inferior_ptid = lwp_from_thread (inferior_ptid);
-  else if (is_thread (ptid))
-    ptid = lwp_from_thread (ptid);
-
-  /* Clear cached data which may not be valid after the resume.  */
-  iterate_over_threads (clear_lwpid_callback, NULL);
-
-  target_beneath->to_resume (ptid, step, signo);
-
-  do_cleanups (old_chain);
-}
-
 /* Check if PID is currently stopped at the location of a thread event
    breakpoint location.  If it is, read the event message and act upon
    the event.  */
@@ -833,7 +790,7 @@
       if (err != TD_OK)
 	error (_("Cannot get thread info: %s"), thread_db_err_str (err));
 
-      ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid);
+      ptid = ptid_build (GET_PID (ptid), ti.ti_lid, 0);
 
       switch (msg.event)
 	{
@@ -849,7 +806,7 @@
 	  if (!in_thread_list (ptid))
 	    error (_("Spurious thread death event."));
 
-	  detach_thread (ptid, print_thread_events);
+	  detach_thread (ptid);
 
 	  break;
 
@@ -865,9 +822,6 @@
 {
   extern ptid_t trap_ptid;
 
-  if (GET_PID (ptid) != -1 && is_thread (ptid))
-    ptid = lwp_from_thread (ptid);
-
   ptid = target_beneath->to_wait (ptid, ourstatus);
 
   if (ourstatus->kind == TARGET_WAITKIND_EXITED
@@ -913,15 +867,6 @@
 }
 
 static void
-thread_db_kill (void)
-{
-  /* There's no need to save & restore inferior_ptid here, since the
-     inferior isn't supposed to survive this function call.  */
-  inferior_ptid = lwp_from_thread (inferior_ptid);
-  target_beneath->to_kill ();
-}
-
-static void
 thread_db_mourn_inferior (void)
 {
   /* Forget about the child's process ID.  We shouldn't need it
@@ -954,7 +899,7 @@
   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
     return 0;			/* A zombie -- ignore.  */
 
-  ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid);
+  ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0);
 
   if (ti.ti_tid == 0)
     {
@@ -994,18 +939,17 @@
 static char *
 thread_db_pid_to_str (ptid_t ptid)
 {
-  if (is_thread (ptid))
+  struct thread_info *thread_info = find_thread_pid (ptid);
+
+  if (thread_info != NULL && thread_info->private != NULL)
     {
       static char buf[64];
-      struct thread_info *thread_info;
+      thread_t tid;
 
+      tid = thread_info->private->tid;
       thread_info = find_thread_pid (ptid);
-      if (thread_info == NULL)
-	snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld) (Missing)",
-		  GET_THREAD (ptid), GET_LWP (ptid));
-      else
-	snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
-		  GET_THREAD (ptid), GET_LWP (ptid));
+      snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
+		tid, GET_LWP (ptid));
 
       return buf;
     }
@@ -1022,22 +966,15 @@
 static char *
 thread_db_extra_thread_info (struct thread_info *info)
 {
+  if (info->private == NULL)
+    return NULL;
+
   if (info->private->dying)
     return "Exiting";
 
   return NULL;
 }
 
-/* Return 1 if this thread has the same LWP as the passed PTID.  */
-
-static int
-same_ptid_callback (struct thread_info *thread, void *arg)
-{
-  ptid_t *ptid_p = arg;
-
-  return GET_LWP (thread->ptid) == GET_LWP (*ptid_p);
-}
-
 /* Get the address of the thread local variable in load module LM which
    is stored at OFFSET within the thread local storage for thread PTID.  */
 
@@ -1046,26 +983,19 @@
 				    CORE_ADDR lm,
 				    CORE_ADDR offset)
 {
+  struct thread_info *thread_info;
+
   /* If we have not discovered any threads yet, check now.  */
-  if (!is_thread (ptid) && !have_threads ())
+  if (!have_threads ())
     thread_db_find_new_threads ();
 
-  /* Try to find a matching thread if we still have the LWP ID instead
-     of the thread ID.  */
-  if (!is_thread (ptid))
-    {
-      struct thread_info *thread;
-
-      thread = iterate_over_threads (same_ptid_callback, &ptid);
-      if (thread != NULL)
-	ptid = thread->ptid;
-    }
+  /* Find the matching thread.  */
+  thread_info = find_thread_pid (ptid);
 
-  if (is_thread (ptid))
+  if (thread_info != NULL && thread_info->private != NULL)
     {
       td_err_e err;
       void *address;
-      struct thread_info *thread_info;
 
       /* glibc doesn't provide the needed interface.  */
       if (!td_thr_tls_get_addr_p)
@@ -1075,11 +1005,6 @@
       /* Caller should have verified that lm != 0.  */
       gdb_assert (lm != 0);
 
-      /* Get info about the thread.  */
-      thread_info = find_thread_pid (ptid);
-      gdb_assert (thread_info);
-      thread_db_map_id2thr (thread_info, 1);
-
       /* Finally, get the address of the variable.  */
       err = td_thr_tls_get_addr_p (&thread_info->private->th,
 				   (void *)(size_t) lm,
@@ -1122,9 +1047,7 @@
   thread_db_ops.to_longname = "multi-threaded child process.";
   thread_db_ops.to_doc = "Threads and pthreads support.";
   thread_db_ops.to_detach = thread_db_detach;
-  thread_db_ops.to_resume = thread_db_resume;
   thread_db_ops.to_wait = thread_db_wait;
-  thread_db_ops.to_kill = thread_db_kill;
   thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
   thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
   thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -r1.86 -r1.87
--- src/gdb/procfs.c	2008/03/12 20:00:21	1.86
+++ src/gdb/procfs.c	2008/03/21 15:44:53	1.87
@@ -4034,8 +4034,9 @@
 	      case PR_SYSENTRY:
 		if (syscall_is_lwp_exit (pi, what))
 		  {
-		    printf_filtered (_("[%s exited]\n"),
-				     target_pid_to_str (retval));
+		    if (print_thread_events)
+		      printf_unfiltered (_("[%s exited]\n"),
+					 target_pid_to_str (retval));
 		    delete_thread (retval);
 		    status->kind = TARGET_WAITKIND_SPURIOUS;
 		    return retval;
@@ -4165,8 +4166,9 @@
 		  }
 		else if (syscall_is_lwp_exit (pi, what))
 		  {
-		    printf_filtered (_("[%s exited]\n"),
-				     target_pid_to_str (retval));
+		    if (print_thread_events)
+		      printf_unfiltered (_("[%s exited]\n"),
+					 target_pid_to_str (retval));
 		    delete_thread (retval);
 		    status->kind = TARGET_WAITKIND_SPURIOUS;
 		    return retval;
Index: gdb-6.8/gdb/thread.c
===================================================================
--- gdb-6.8.orig/gdb/thread.c	2008-03-12 23:22:06.000000000 +0100
+++ gdb-6.8/gdb/thread.c	2008-07-14 10:24:32.000000000 +0200
@@ -131,16 +131,24 @@ add_thread_silent (ptid_t ptid)
 }
 
 struct thread_info *
-add_thread (ptid_t ptid)
+add_thread_with_info (ptid_t ptid, struct private_thread_info *private)
 {
   struct thread_info *result = add_thread_silent (ptid);
 
+  result->private = private;
+
   if (print_thread_events)
     printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
   
   return result;
 }
 
+struct thread_info *
+add_thread (ptid_t ptid)
+{
+  return add_thread_with_info (ptid, NULL);
+}
+
 void
 delete_thread (ptid_t ptid)
 {
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.threads/fork-child-threads.exp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- src/gdb/testsuite/gdb.threads/fork-child-threads.exp	2008/01/02 13:36:38	1.1
+++ src/gdb/testsuite/gdb.threads/fork-child-threads.exp	2008/03/21 15:44:53	1.2
@@ -38,6 +38,10 @@
 
 gdb_test "set follow-fork-mode child"
 gdb_breakpoint "start"
+
+# Make sure we can step over fork without losing our breakpoint.
+gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork"
+
 gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread"
 
 # Wrong:

http://sourceware.org/ml/gdb-patches/2008-04/msg00238.html
http://sourceware.org/ml/gdb-cvs/2008-04/msg00068.html

2008-04-14  Daniel Jacobowitz  <dan@codesourcery.com>

	* linux-thread-db.c (have_threads_callback): Check thread->private.

===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- src/gdb/linux-thread-db.c	2008/03/25 12:26:21	1.40
+++ src/gdb/linux-thread-db.c	2008/04/14 14:02:23	1.41
@@ -235,7 +235,7 @@
 static int
 have_threads_callback (struct thread_info *thread, void *dummy)
 {
-  return 1;
+  return thread->private != NULL;
 }
 
 static int



2008-05-03  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/dfp-test.exp: Fix random FAIL risk on calling functions.

===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/dfp-test.exp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- src/gdb/testsuite/gdb.base/dfp-test.exp	2008/01/30 03:19:26	1.5
+++ src/gdb/testsuite/gdb.base/dfp-test.exp	2008/05/03 21:56:38	1.6
@@ -252,16 +252,16 @@
 
 # Test calling inferior function with DFP arguments or return value.
 
-send_gdb "call arg0_32 (1.2df, 2.2df, 3.2df, 4.2df, 5.2df, 6.2df)\n"
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_32 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal32 arguments."
+gdb_test "call arg0_32 (1.2df, 2.2df, 3.2df, 4.2df, 5.2df, 6.2df)" "Breakpoint.*arg0_32.*" "Call function with correct _Decimal32 arguments."
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_32 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal32 arguments."
 gdb_test "finish" " = 1.2" "Correct _Decimal32 return value from called function."
 
-send_gdb "call arg0_64 (1.2dd, 2.2dd, 3.2dd, 4.2dd, 5.2dd, 6.2dd)\n"
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_64 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal64 arguments."
+gdb_test "call arg0_64 (1.2dd, 2.2dd, 3.2dd, 4.2dd, 5.2dd, 6.2dd)" "Breakpoint.*arg0_64.*" "Call function with correct _Decimal64 arguments."
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_64 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal64 arguments."
 gdb_test "finish" " = 1.2" "Correct _Decimal64 return value from called function."
 
-send_gdb "call arg0_128 (1.2dl, 2.2dl, 3.2dl, 4.2dl, 5.2dl, 6.2dl)\n"
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_128 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal128 arguments."
+gdb_test "call arg0_128 (1.2dl, 2.2dl, 3.2dl, 4.2dl, 5.2dl, 6.2dl)" "Breakpoint.*arg0_128.*" "Call function with correct _Decimal128 arguments."
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_128 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal128 arguments."
 gdb_test "finish" " = 1.2" "Correct _Decimal128 return value from called function."
 
 gdb_test "call decimal_dec128_align (double_val1, dec128_val2, double_val3, double_val4, double_val5, double_val6, double_val7, double_val8, double_val9, double_val10, double_val11, double_val12, double_val13, double_val14)" " = 1" \



gdb/
2008-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* breakpoint.c (bpstat_copy): Call RELEASE_VALUE on the new OLD_VAL.

gdb/testsuite/
2008-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/value-double-free.exp, gdb.base/value-double-free.c: New.

===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.327
retrieving revision 1.328
diff -u -r1.327 -r1.328
--- src/gdb/breakpoint.c	2008/06/28 09:42:15	1.327
+++ src/gdb/breakpoint.c	2008/07/07 22:39:58	1.328
@@ -1996,7 +1996,10 @@
       if (bs->commands != NULL)
 	tmp->commands = copy_command_lines (bs->commands);
       if (bs->old_val != NULL)
-	tmp->old_val = value_copy (bs->old_val);
+	{
+	  tmp->old_val = value_copy (bs->old_val);
+	  release_value (tmp->old_val);
+	}
 
       if (p == NULL)
 	/* This is the first thing in the chain.  */
/cvs/src/src/gdb/testsuite/gdb.base/value-double-free.c,v  -->  standard output
revision 1.1
--- src/gdb/testsuite/gdb.base/value-double-free.c
+++ src/gdb/testsuite/gdb.base/value-double-free.c	2008-07-07 22:40:47.485459000 +0000
@@ -0,0 +1,36 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008 Free Software Foundation, Inc.
+
+   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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@prep.ai.mit.edu  */
+
+volatile int var;
+
+void
+empty (void)
+{
+}
+
+int
+main (void)
+{
+  var = 1;
+  /* Workaround PR 38: We may miss the first watchpoint hit as we stop on the
+     exact instruction which would cause the watchpoint hit.  */
+  var = 2;
+  return 0;
+}
/cvs/src/src/gdb/testsuite/gdb.base/value-double-free.exp,v  -->  standard output
revision 1.1
--- src/gdb/testsuite/gdb.base/value-double-free.exp
+++ src/gdb/testsuite/gdb.base/value-double-free.exp	2008-07-07 22:40:48.139680000 +0000
@@ -0,0 +1,38 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# 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/>.
+
+set testfile value-double-free
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] {
+    return -1
+}
+gdb_test "watch var" "atchpoint \[0-9\]+: var"
+gdb_test "continue" "atchpoint \[0-9\]+: var.*Old value = 0.*New value = \[12\].*"
+gdb_test "print empty()" " = void"
+# We did segfault here.
+gdb_test "help help"



http://sourceware.org/ml/gdb-patches/2008-03/msg00356.html
http://sourceware.org/ml/gdb-cvs/2008-03/msg00130.html

2008-03-24  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix random false FAILs on i386.
	* gdb.base/prelink.exp: Use `--no-exec-shield' for prelink.

===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/prelink.exp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- src/gdb/testsuite/gdb.base/prelink.exp	2008/01/01 22:53:19	1.7
+++ src/gdb/testsuite/gdb.base/prelink.exp	2008/03/24 15:16:12	1.8
@@ -47,7 +47,15 @@
     return -1
 }
 
-if {[catch "system \"prelink -qNR ${libfile}\""] != 0} {
+# `--no-exec-shield' is for i386 where prelink in the exec-shield mode is
+# forced to push all the libraries tight together to fit into the first two
+# memory areas (either the ASCII Shield area or at least below the executable).
+# In this case its -R option cannot be applied and we falsely FAIL here as if
+# the system is already prelinked prelink has no choice how to randomize the
+# single new unprelinked library address without wasting the first one/two
+# memory areas.  We do not care of the efficiency of loading such resulting
+# exec-shield unfriendly prelinked library.
+if {[catch "system \"prelink -qNR --no-exec-shield ${libfile}\""] != 0} {
     # Maybe we don't have prelink.
     return -1
 }
@@ -92,7 +100,7 @@
     untested "${testfile}.so was not prelinked, maybe system libraries are not prelinked?"
     return 0
 }
-catch "system \"prelink -qNR ${libfile}\""
+catch "system \"prelink -qNR --no-exec-shield ${libfile}\""
 
 # Start with a fresh gdb
 



https://bugzilla.redhat.com/show_bug.cgi?id=452960

bfd/
2008-05-14  Ulrich Weigand  <uweigand@de.ibm.com>

	* elf32-ppc.c (ppc_elf_get_synthetic_symtab): Fix memset calls.
	* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.

bfd/
2008-05-14  Ulrich Weigand  <uweigand@de.ibm.com>
	    Alan Modra  <amodra@bigpond.net.au>

	* elf32-ppc.c (section_covers_vma): New function.
	(ppc_elf_get_synthetic_symtab): New function.
	(bfd_elf32_get_synthetic_symtab): Define.
	* elf64-ppc.c (section_covers_vma): New function.
	(ppc64_elf_get_synthetic_symtab): Generate sym@plt on glink branch
	table entries, and __glink_PLTresolve on resolver stub.
	(ppc64_elf_build_stubs): Rename __glink sym to __glink_PLTresolve.

gdb/
2008-05-14  Ulrich Weigand  <uweigand@de.ibm.com>

	* ppc-linux-tdep.c (ppc_linux_convert_from_func_ptr_addr): Rename ...
	(ppc64_linux_convert_from_func_ptr_addr): ... to this.  No longer try
	to handle ppc32 PLT entries.
	(ppc_linux_init_abi): Install ppc64_linux_convert_from_func_ptr_addr
	only on ppc64.

gdb/
2008-05-14  Daniel Jacobowitz  <dan@codesourcery.com>

	* elfread.c (elf_symtab_read): Create trampolines for @plt symbols.
	* minsyms.c (lookup_minimal_symbol_by_pc_section_1): Renamed from
	lookup_minimal_symbol_by_pc_section.  Prefer trampolines if requested.
	(lookup_minimal_symbol_by_pc_section): Use
	lookup_minimal_symbol_by_pc_section_1.
	(lookup_solib_trampoline_symbol_by_pc): Likewise.

[ Backported for GDB-6.8f.  ]

--- ./bfd/elf32-ppc.c	2008-02-26 09:36:03.000000000 +0100
+++ ./bfd/elf32-ppc.c	2008-07-24 15:42:47.000000000 +0200
@@ -2291,6 +2291,208 @@ ppc_elf_final_write_processing (bfd *abf
   apuinfo_list_finish ();
 }
 
+static bfd_boolean
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
+{
+  bfd_vma vma = *(bfd_vma *) ptr;
+  return ((section->flags & SEC_ALLOC) != 0
+	  && section->vma <= vma
+	  && vma < section->vma + section->size);
+}
+
+static long
+ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
+			      long dynsymcount, asymbol **dynsyms,
+			      asymbol **ret)
+{
+  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+  asection *plt, *relplt, *dynamic, *glink;
+  bfd_vma glink_vma = 0;
+  bfd_vma resolv_vma = 0;
+  bfd_vma stub_vma;
+  asymbol *s;
+  arelent *p;
+  long count, i;
+  size_t size;
+  char *names;
+  bfd_byte buf[4];
+
+  *ret = NULL;
+
+  if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
+    return 0;
+
+  if (dynsymcount <= 0)
+    return 0;
+
+  relplt = bfd_get_section_by_name (abfd, ".rela.plt");
+  if (relplt == NULL)
+    return 0;
+
+  plt = bfd_get_section_by_name (abfd, ".plt");
+  if (plt == NULL)
+    return 0;
+
+  /* Call common code to handle old-style executable PLTs.  */
+  if (elf_section_flags (plt) & SHF_EXECINSTR)
+    return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
+					  dynsymcount, dynsyms, ret);
+
+  /* If this object was prelinked, the prelinker stored the address
+     of .glink at got[1].  If it wasn't prelinked, got[1] will be zero.  */
+  dynamic = bfd_get_section_by_name (abfd, ".dynamic");
+  if (dynamic != NULL)
+    {
+      bfd_byte *dynbuf, *extdyn, *extdynend;
+      size_t extdynsize;
+      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+
+      if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
+	return -1;
+
+      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
+      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
+
+      extdyn = dynbuf;
+      extdynend = extdyn + dynamic->size;
+      for (; extdyn < extdynend; extdyn += extdynsize)
+	{
+	  Elf_Internal_Dyn dyn;
+	  (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+	  if (dyn.d_tag == DT_NULL)
+	    break;
+
+	  if (dyn.d_tag == DT_PPC_GOT)
+	    {
+	      unsigned int g_o_t = dyn.d_un.d_val;
+	      asection *got = bfd_get_section_by_name (abfd, ".got");
+	      if (got != NULL
+		  && bfd_get_section_contents (abfd, got, buf,
+					       g_o_t - got->vma + 4, 4))
+		glink_vma = bfd_get_32 (abfd, buf);
+	      break;
+	    }
+	}
+      free (dynbuf);
+    }
+
+  /* Otherwise we read the first plt entry.  */
+  if (glink_vma == 0)
+    {
+      if (bfd_get_section_contents (abfd, plt, buf, 0, 4))
+	glink_vma = bfd_get_32 (abfd, buf);
+    }
+
+  if (glink_vma == 0)
+    return 0;
+
+  /* The .glink section usually does not survive the final
+     link; search for the section (usually .text) where the
+     glink stubs now reside.  */
+  glink = bfd_sections_find_if (abfd, section_covers_vma, &glink_vma);
+  if (glink == NULL)
+    return 0;
+
+  /* Determine glink PLT resolver by reading the relative branch
+     from the first glink stub.  */
+  if (bfd_get_section_contents (abfd, glink, buf,
+				glink_vma - glink->vma, 4))
+    {
+      unsigned int insn = bfd_get_32 (abfd, buf);
+
+      /* The first glink stub may either branch to the resolver ...  */
+      insn ^= B;
+      if ((insn & ~0x3fffffc) == 0)
+	resolv_vma = glink_vma + (insn ^ 0x2000000) - 0x2000000;
+
+      /* ... or fall through a bunch of NOPs.  */
+      else if ((insn ^ B ^ NOP) == 0)
+	for (i = 4;
+	     bfd_get_section_contents (abfd, glink, buf,
+				       glink_vma - glink->vma + i, 4);
+	     i += 4)
+	  if (bfd_get_32 (abfd, buf) != NOP)
+	    {
+	      resolv_vma = glink_vma + i;
+	      break;
+	    }
+    }
+
+  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+  if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+    return -1;
+
+  count = relplt->size / sizeof (Elf32_External_Rela);
+  stub_vma = glink_vma - (bfd_vma) count * 16;
+  size = count * sizeof (asymbol);
+  p = relplt->relocation;
+  for (i = 0; i < count; i++, p++)
+    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+
+  size += sizeof (asymbol) + sizeof ("__glink");
+
+  if (resolv_vma)
+    size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
+
+  s = *ret = bfd_malloc (size);
+  if (s == NULL)
+    return -1;
+
+  names = (char *) (s + count + 1 + (resolv_vma != 0));
+  p = relplt->relocation;
+  for (i = 0; i < count; i++, p++)
+    {
+      size_t len;
+
+      *s = **p->sym_ptr_ptr;
+      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
+	 we are defining a symbol, ensure one of them is set.  */
+      if ((s->flags & BSF_LOCAL) == 0)
+	s->flags |= BSF_GLOBAL;
+      s->section = glink;
+      s->value = stub_vma - glink->vma;
+      s->name = names;
+      s->udata.p = NULL;
+      len = strlen ((*p->sym_ptr_ptr)->name);
+      memcpy (names, (*p->sym_ptr_ptr)->name, len);
+      names += len;
+      memcpy (names, "@plt", sizeof ("@plt"));
+      names += sizeof ("@plt");
+      ++s;
+      stub_vma += 16;
+    }
+
+  /* Add a symbol at the start of the glink branch table.  */
+  memset (s, 0, sizeof *s);
+  s->the_bfd = abfd;
+  s->flags = BSF_GLOBAL;
+  s->section = glink;
+  s->value = glink_vma - glink->vma;
+  s->name = names;
+  memcpy (names, "__glink", sizeof ("__glink"));
+  names += sizeof ("__glink");
+  s++;
+  count++;
+
+  if (resolv_vma)
+    {
+      /* Add a symbol for the glink PLT resolver.  */
+      memset (s, 0, sizeof *s);
+      s->the_bfd = abfd;
+      s->flags = BSF_GLOBAL;
+      s->section = glink;
+      s->value = resolv_vma - glink->vma;
+      s->name = names;
+      memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
+      names += sizeof ("__glink_PLTresolve");
+      s++;
+      count++;
+    }
+
+  return count;
+}
+
 /* The following functions are specific to the ELF linker, while
    functions above are used generally.  They appear in this file more
    or less in the order in which they are called.  eg.
@@ -7733,6 +7935,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
 #define bfd_elf32_bfd_reloc_name_lookup	ppc_elf_reloc_name_lookup
 #define bfd_elf32_bfd_set_private_flags		ppc_elf_set_private_flags
 #define bfd_elf32_bfd_link_hash_table_create	ppc_elf_link_hash_table_create
+#define bfd_elf32_get_synthetic_symtab		ppc_elf_get_synthetic_symtab
 
 #define elf_backend_object_p			ppc_elf_object_p
 #define elf_backend_gc_mark_hook		ppc_elf_gc_mark_hook
@@ -7847,6 +8050,8 @@ ppc_elf_vxworks_final_write_processing (
 #undef elf_backend_got_header_size
 #define elf_backend_got_header_size		12
 
+#undef bfd_elf32_get_synthetic_symtab
+
 #undef bfd_elf32_bfd_link_hash_table_create
 #define bfd_elf32_bfd_link_hash_table_create \
   ppc_elf_vxworks_link_hash_table_create
--- ./bfd/elf64-ppc.c	2008-02-15 09:27:19.000000000 +0100
+++ ./bfd/elf64-ppc.c	2008-07-24 15:42:47.000000000 +0200
@@ -2771,8 +2771,17 @@ sym_exists_at (asymbol **syms, long lo, 
   return NULL;
 }
 
+static bfd_boolean
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
+{
+  bfd_vma vma = *(bfd_vma *) ptr;
+  return ((section->flags & SEC_ALLOC) != 0
+	  && section->vma <= vma
+	  && vma < section->vma + section->size);
+}
+
 /* Create synthetic symbols, effectively restoring "dot-symbol" function
-   entry syms.  */
+   entry syms.  Also generate @plt symbols for the glink branch table.  */
 
 static long
 ppc64_elf_get_synthetic_symtab (bfd *abfd,
@@ -2862,8 +2871,6 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
   symcount = i;
 
   count = 0;
-  if (opdsymend == secsymend)
-    goto done;
 
   if (relocatable)
     {
@@ -2872,6 +2879,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
       size_t size;
       long relcount;
 
+      if (opdsymend == secsymend)
+	goto done;
+
       slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
       relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
       if (relcount == 0)
@@ -2960,8 +2970,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
     }
   else
     {
+      bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
       bfd_byte *contents;
       size_t size;
+      long plt_count = 0;
+      bfd_vma glink_vma = 0, resolv_vma = 0;
+      asection *dynamic, *glink = NULL, *relplt = NULL;
+      arelent *p;
 
       if (!bfd_malloc_and_get_section (abfd, opd, &contents))
 	{
@@ -2988,11 +3003,85 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
 	    }
 	}
 
+      /* Get start of .glink stubs from DT_PPC64_GLINK.  */
+      dynamic = bfd_get_section_by_name (abfd, ".dynamic");
+      if (dynamic != NULL)
+	{
+	  bfd_byte *dynbuf, *extdyn, *extdynend;
+	  size_t extdynsize;
+	  void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+
+	  if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
+	    goto free_contents_and_exit;
+
+	  extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
+	  swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
+
+	  extdyn = dynbuf;
+	  extdynend = extdyn + dynamic->size;
+	  for (; extdyn < extdynend; extdyn += extdynsize)
+	    {
+	      Elf_Internal_Dyn dyn;
+	      (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+	      if (dyn.d_tag == DT_NULL)
+		break;
+
+	      if (dyn.d_tag == DT_PPC64_GLINK)
+		{
+		  /* The first glink stub starts at offset 32; see comment in
+		     ppc64_elf_finish_dynamic_sections. */
+		  glink_vma = dyn.d_un.d_val + 32;
+		  /* The .glink section usually does not survive the final
+		     link; search for the section (usually .text) where the
+		     glink stubs now reside.  */
+		  glink = bfd_sections_find_if (abfd, section_covers_vma,
+						&glink_vma);
+		  break;
+		}
+	    }
+
+	  free (dynbuf);
+	}
+
+      if (glink != NULL)
+	{
+	  /* Determine __glink trampoline by reading the relative branch
+	     from the first glink stub.  */
+	  bfd_byte buf[4];
+	  if (bfd_get_section_contents (abfd, glink, buf,
+					glink_vma + 4 - glink->vma, 4))
+	    {
+	      unsigned int insn = bfd_get_32 (abfd, buf);
+	      insn ^= B_DOT;
+	      if ((insn & ~0x3fffffc) == 0)
+		resolv_vma = glink_vma + 4 + (insn ^ 0x2000000) - 0x2000000;
+	    }
+
+	  if (resolv_vma)
+	    size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
+	}
+
+      relplt = bfd_get_section_by_name (abfd, ".rela.plt");
+      if (glink != NULL && relplt != NULL)
+	{
+	  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+	  if (! (*slurp_relocs) (abfd, relplt, dyn_syms, TRUE))
+	    goto free_contents_and_exit;
+	
+	  plt_count = relplt->size / sizeof (Elf64_External_Rela);
+	  size += plt_count * sizeof (asymbol);
+
+	  p = relplt->relocation;
+	  for (i = 0; i < plt_count; i++, p++)
+	    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+	}
+
       s = *ret = bfd_malloc (size);
       if (s == NULL)
 	goto free_contents_and_exit;
 
-      names = (char *) (s + count);
+      names = (char *) (s + count + plt_count + (resolv_vma != 0));
 
       for (i = secsymend; i < opdsymend; ++i)
 	{
@@ -3048,6 +3137,66 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
 	    }
 	}
       free (contents);
+
+      if (glink != NULL && relplt != NULL)
+	{
+	  if (resolv_vma)
+	    {
+	      /* Add a symbol for the main glink trampoline.  */
+	      memset (s, 0, sizeof *s);
+	      s->the_bfd = abfd;
+	      s->flags = BSF_GLOBAL;
+	      s->section = glink;
+	      s->value = resolv_vma - glink->vma;
+	      s->name = names;
+	      memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
+	      names += sizeof ("__glink_PLTresolve");
+	      s++;
+	      count++;
+	    }
+
+	  /* FIXME: It would be very much nicer to put sym@plt on the
+	     stub rather than on the glink branch table entry.  The
+	     objdump disassembler would then use a sensible symbol
+	     name on plt calls.  The difficulty in doing so is
+	     a) finding the stubs, and,
+	     b) matching stubs against plt entries, and,
+	     c) there can be multiple stubs for a given plt entry.
+
+	     Solving (a) could be done by code scanning, but older
+	     ppc64 binaries used different stubs to current code.
+	     (b) is the tricky one since you need to known the toc
+	     pointer for at least one function that uses a pic stub to
+	     be able to calculate the plt address referenced.
+	     (c) means gdb would need to set multiple breakpoints (or
+	     find the glink branch itself) when setting breakpoints
+	     for pending shared library loads.  */
+	  p = relplt->relocation;
+	  for (i = 0; i < plt_count; i++, p++)
+	    {
+	      size_t len;
+
+	      *s = **p->sym_ptr_ptr;
+	      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
+		 we are defining a symbol, ensure one of them is set.  */
+	      if ((s->flags & BSF_LOCAL) == 0)
+		s->flags |= BSF_GLOBAL;
+	      s->section = glink;
+	      s->value = glink_vma - glink->vma;
+	      s->name = names;
+	      s->udata.p = NULL;
+	      len = strlen ((*p->sym_ptr_ptr)->name);
+	      memcpy (names, (*p->sym_ptr_ptr)->name, len);
+	      names += len;
+	      memcpy (names, "@plt", sizeof ("@plt"));
+	      names += sizeof ("@plt");
+	      s++;
+	      glink_vma += 8;
+	      if (i >= 0x8000)
+		glink_vma += 4;
+	    }
+	  count += plt_count;
+	}
     }
 
  done:
@@ -9705,7 +9854,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_
       if (htab->emit_stub_syms)
 	{
 	  struct elf_link_hash_entry *h;
-	  h = elf_link_hash_lookup (&htab->elf, "__glink", TRUE, FALSE, FALSE);
+	  h = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
+				    TRUE, FALSE, FALSE);
 	  if (h == NULL)
 	    return FALSE;
 	  if (h->root.type == bfd_link_hash_new)
--- ./gdb/elfread.c	2008-07-24 15:41:07.000000000 +0200
+++ ./gdb/elfread.c	2008-07-24 15:42:48.000000000 +0200
@@ -514,6 +514,34 @@ elf_symtab_read (struct objfile *objfile
 	  if (msym != NULL)
 	    msym->filename = filesymname;
 	  gdbarch_elf_make_msymbol_special (current_gdbarch, sym, msym);
+ 
+ 	  /* For @plt symbols, also record a trampoline to the
+ 	     destination symbol.  The @plt symbol will be used in
+ 	     disassembly, and the trampoline will be used when we are
+ 	     trying to find the target.  */
+ 	  if (msym && ms_type == mst_text && type == ST_SYNTHETIC)
+ 	    {
+ 	      int len = strlen (sym->name);
+ 
+ 	      if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0)
+ 		{
+ 		  char *base_name = alloca (len - 4 + 1);
+ 		  struct minimal_symbol *mtramp;
+ 
+ 		  memcpy (base_name, sym->name, len - 4);
+ 		  base_name[len - 4] = '\0';
+ 		  mtramp = record_minimal_symbol (base_name, symaddr,
+ 						  mst_solib_trampoline,
+ 						  sym->section, objfile);
+ 		  if (mtramp)
+ 		    {
+ 		      MSYMBOL_SIZE (mtramp) = MSYMBOL_SIZE (msym);
+ 		      mtramp->filename = filesymname;
+ 		      gdbarch_elf_make_msymbol_special (current_gdbarch, sym,
+							mtramp);
+ 		    }
+ 		}
+ 	    }
 	}
     }
 }
--- ./gdb/minsyms.c	2008-07-24 15:41:07.000000000 +0200
+++ ./gdb/minsyms.c	2008-07-24 15:42:48.000000000 +0200
@@ -357,10 +357,15 @@ lookup_minimal_symbol_solib_trampoline (
    ALL the minimal symbol tables before deciding on the symbol that
    comes closest to the specified PC.  This is because objfiles can
    overlap, for example objfile A has .text at 0x100 and .data at
-   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.  */
+   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.
 
-struct minimal_symbol *
-lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+   If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when
+   there are text and trampoline symbols at the same address.
+   Otherwise prefer mst_text symbols.  */
+
+static struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
+				       int want_trampoline)
 {
   int lo;
   int hi;
@@ -369,7 +374,11 @@ lookup_minimal_symbol_by_pc_section (COR
   struct minimal_symbol *msymbol;
   struct minimal_symbol *best_symbol = NULL;
   struct obj_section *pc_section;
+  enum minimal_symbol_type want_type, other_type;
 
+  want_type = want_trampoline ? mst_solib_trampoline : mst_text;
+  other_type = want_trampoline ? mst_text : mst_solib_trampoline;
+  
   /* PC has to be in a known section.  This ensures that anything
      beyond the end of the last segment doesn't appear to be part of
      the last function in the last segment.  */
@@ -491,6 +500,24 @@ lookup_minimal_symbol_by_pc_section (COR
 		      continue;
 		    }
 
+		  /* If we are looking for a trampoline and this is a
+		     text symbol, or the other way around, check the
+		     preceeding symbol too.  If they are otherwise
+		     identical prefer that one.  */
+		  if (hi > 0
+		      && MSYMBOL_TYPE (&msymbol[hi]) == other_type
+		      && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type
+		      && (MSYMBOL_SIZE (&msymbol[hi])
+			  == MSYMBOL_SIZE (&msymbol[hi - 1]))
+		      && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+			  == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
+		      && (SYMBOL_BFD_SECTION (&msymbol[hi])
+			  == SYMBOL_BFD_SECTION (&msymbol[hi - 1])))
+		    {
+		      hi--;
+		      continue;
+		    }
+
 		  /* If the minimal symbol has a zero size, save it
 		     but keep scanning backwards looking for one with
 		     a non-zero size.  A zero size may mean that the
@@ -571,6 +598,12 @@ lookup_minimal_symbol_by_pc_section (COR
   return (best_symbol);
 }
 
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+{
+  return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
+}
+
 /* Backward compatibility: search through the minimal symbol table 
    for a matching PC (no section given) */
 
@@ -1024,7 +1057,13 @@ msymbols_sort (struct objfile *objfile)
 struct minimal_symbol *
 lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
 {
-  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+  struct obj_section *section = find_pc_section (pc);
+  struct minimal_symbol *msymbol;
+
+  if (section == NULL)
+    return NULL;
+  msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section->the_bfd_section,
+						   1);
 
   if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
     return msymbol;
--- ./gdb/ppc-linux-tdep.c	2008-02-20 15:31:40.000000000 +0100
+++ ./gdb/ppc-linux-tdep.c	2008-07-24 15:43:24.000000000 +0200
@@ -545,7 +545,7 @@ ppc64_skip_trampoline_code (struct frame
 }
 
 
-/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC
+/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
    GNU/Linux.
 
    Usually a function pointer's representation is simply the address
@@ -557,12 +557,6 @@ ppc64_skip_trampoline_code (struct frame
    function, the second word is the TOC pointer (r2), and the third word
    is the static chain value.
 
-   For PPC32, there are two kinds of function pointers: non-secure and
-   secure.  Non-secure function pointers point directly to the
-   function in a code section and thus need no translation.  Secure
-   ones (from GCC's -msecure-plt option) are in a data section and
-   contain one word: the address of the function.
-
    Throughout GDB it is currently assumed that a function pointer contains
    the address of the function, which is not easy to fix.  In addition, the
    conversion of a function address to a function pointer would
@@ -578,40 +572,15 @@ ppc64_skip_trampoline_code (struct frame
    random addresses such as occur when there is no symbol table.  */
 
 static CORE_ADDR
-ppc_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
-				      CORE_ADDR addr,
-				      struct target_ops *targ)
+ppc64_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
+					CORE_ADDR addr,
+					struct target_ops *targ)
 {
-  struct gdbarch_tdep *tdep;
   struct section_table *s = target_section_by_addr (targ, addr);
-  char *sect_name = NULL;
-
-  if (!s)
-    return addr;
-
-  tdep = gdbarch_tdep (gdbarch);
-
-  switch (tdep->wordsize)
-    {
-      case 4:
-	sect_name = ".plt";
-	break;
-      case 8:
-	sect_name = ".opd";
-	break;
-      default:
-	internal_error (__FILE__, __LINE__,
-			_("failed internal consistency check"));
-    }
 
   /* Check if ADDR points to a function descriptor.  */
-
-  /* NOTE: this depends on the coincidence that the address of a functions
-     entry point is contained in the first word of its function descriptor
-     for both PPC-64 and for PPC-32 with secure PLTs.  */
-  if ((strcmp (s->the_bfd_section->name, sect_name) == 0)
-      && s->the_bfd_section->flags & SEC_DATA)
-    return get_target_memory_unsigned (targ, addr, tdep->wordsize);
+  if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
+    return get_target_memory_unsigned (targ, addr, 8);
 
   return addr;
 }
@@ -905,11 +874,6 @@ ppc_linux_init_abi (struct gdbarch_info 
   set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
   set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
 
-  /* Handle PPC GNU/Linux 64-bit function pointers (which are really
-     function descriptors) and 32-bit secure PLT entries.  */
-  set_gdbarch_convert_from_func_ptr_addr
-    (gdbarch, ppc_linux_convert_from_func_ptr_addr);
-
   if (tdep->wordsize == 4)
     {
       /* Until November 2001, gcc did not comply with the 32 bit SysV
@@ -937,6 +901,11 @@ ppc_linux_init_abi (struct gdbarch_info 
   
   if (tdep->wordsize == 8)
     {
+      /* Handle PPC GNU/Linux 64-bit function pointers (which are really
+	 function descriptors).  */
+      set_gdbarch_convert_from_func_ptr_addr
+	(gdbarch, ppc64_linux_convert_from_func_ptr_addr);
+
       /* Shared library handling.  */
       set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets



http://sourceware.org/ml/gdb-patches/2008-04/msg00379.html
http://sourceware.org/ml/gdb-cvs/2008-04/msg00104.html

2008-04-17  Marc Khouzam  <marc.khouzam@ericsson.com>

	* breakpoint.c (update_watchpoint): Always reparse
	condition.

===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.309
retrieving revision 1.310
diff -u -r1.309 -r1.310
--- src/gdb/breakpoint.c	2008/04/17 22:43:17	1.309
+++ src/gdb/breakpoint.c	2008/04/18 00:41:28	1.310
@@ -994,14 +994,13 @@
 	    value_free (v);
 	}
 
-      if (reparse && b->cond_string != NULL)
+      /* We just regenerated the list of breakpoint locations.
+         The new location does not have its condition field set to anything
+         and therefore, we must always reparse the cond_string, independently
+         of the value of the reparse flag.  */
+      if (b->cond_string != NULL)
 	{
 	  char *s = b->cond_string;
-	  if (b->loc->cond)
-	    {
-	      xfree (b->loc->cond);
-	      b->loc->cond = NULL;
-	    }
 	  b->loc->cond = parse_exp_1 (&s, b->exp_valid_block, 0);
 	}
     }



https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=196439
http://sourceware.org/ml/gdb-patches/2008-04/msg00628.html
http://sourceware.org/ml/gdb-cvs/2008-05/msg00051.html

Testcase:
gdb-6.5-bz196439-valgrind-memcheck-compat-test.patch

2008-05-04  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* dwarf2loc.c (dwarf_expr_frame_base): Error out on missing
	SYMBOL_LOCATION_BATON.

===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- src/gdb/dwarf2loc.c	2008/03/26 14:53:28	1.50
+++ src/gdb/dwarf2loc.c	2008/05/04 12:44:16	1.51
@@ -166,8 +166,13 @@
     {
       struct dwarf2_locexpr_baton *symbaton;
       symbaton = SYMBOL_LOCATION_BATON (framefunc);
-      *length = symbaton->size;
-      *start = symbaton->data;
+      if (symbaton != NULL)
+	{
+	  *length = symbaton->size;
+	  *start = symbaton->data;
+	}
+      else
+	*start = NULL;
     }
 
   if (*start == NULL)



http://sourceware.org/ml/gdb-patches/2008-04/msg00508.html
http://sourceware.org/ml/gdb-cvs/2008-05/msg00017.html

Test applicable from:
gdb-6.8-watchpoint-conditionals-test.patch

gdb/
2008-05-02  Andreas Schwab  <schwab@suse.de>

	* target.h (struct target_ops): Add
	to_watchpoint_addr_within_range.
	(target_watchpoint_addr_within_range): New function.
	* target.c (update_current_target): Inherit
	to_watchpoint_addr_within_range, defaulting to
	default_watchpoint_addr_within_range.
	(default_watchpoint_addr_within_range): New function.
	(debug_to_watchpoint_addr_within_range): New function.
	(setup_target_debug): Set to_watchpoint_addr_within_range.
	* ppc-linux-nat.c (ppc_linux_watchpoint_addr_within_range):
	New function.
	(_initialize_ppc_linux_nat): Set to_watchpoint_addr_within_range.
	* breakpoint.c (watchpoints_triggered): Use
	target_watchpoint_addr_within_range.

gdb/doc/
2008-05-02  Andreas Schwab  <schwab@suse.de>

	* gdbint.texinfo (Algorithms): Describe
	target_watchpoint_addr_within_range.

===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -r1.117 -r1.118
--- src/gdb/target.h	2008/05/01 19:31:51	1.117
+++ src/gdb/target.h	2008/05/02 11:07:25	1.118
@@ -367,6 +367,8 @@
     int to_have_steppable_watchpoint;
     int to_have_continuable_watchpoint;
     int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *);
+    int (*to_watchpoint_addr_within_range) (struct target_ops *,
+					    CORE_ADDR, CORE_ADDR, int);
     int (*to_region_ok_for_hw_watchpoint) (CORE_ADDR, int);
     void (*to_terminal_init) (void);
     void (*to_terminal_inferior) (void);
@@ -1093,6 +1095,9 @@
 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
 #endif
 
+#define target_watchpoint_addr_within_range(target, addr, start, length) \
+  (*target.to_watchpoint_addr_within_range) (target, addr, start, length)
+
 extern const struct target_desc *target_read_description (struct target_ops *);
 
 /* Command logging facility.  */
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.160
retrieving revision 1.161
diff -u -r1.160 -r1.161
--- src/gdb/target.c	2008/04/24 10:21:44	1.160
+++ src/gdb/target.c	2008/05/02 11:07:25	1.161
@@ -49,6 +49,9 @@
 
 static void default_terminal_info (char *, int);
 
+static int default_watchpoint_addr_within_range (struct target_ops *,
+						 CORE_ADDR, CORE_ADDR, int);
+
 static int default_region_ok_for_hw_watchpoint (CORE_ADDR, int);
 
 static int nosymbol (char *, CORE_ADDR *);
@@ -131,6 +134,9 @@
 
 static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *);
 
+static int debug_to_watchpoint_addr_within_range (struct target_ops *,
+						  CORE_ADDR, CORE_ADDR, int);
+
 static int debug_to_region_ok_for_hw_watchpoint (CORE_ADDR, int);
 
 static void debug_to_terminal_init (void);
@@ -416,9 +422,10 @@
       INHERIT (to_insert_watchpoint, t);
       INHERIT (to_remove_watchpoint, t);
       INHERIT (to_stopped_data_address, t);
-      INHERIT (to_stopped_by_watchpoint, t);
       INHERIT (to_have_steppable_watchpoint, t);
       INHERIT (to_have_continuable_watchpoint, t);
+      INHERIT (to_stopped_by_watchpoint, t);
+      INHERIT (to_watchpoint_addr_within_range, t);
       INHERIT (to_region_ok_for_hw_watchpoint, t);
       INHERIT (to_terminal_init, t);
       INHERIT (to_terminal_inferior, t);
@@ -544,6 +551,8 @@
   de_fault (to_stopped_data_address,
 	    (int (*) (struct target_ops *, CORE_ADDR *))
 	    return_zero);
+  de_fault (to_watchpoint_addr_within_range,
+	    default_watchpoint_addr_within_range);
   de_fault (to_region_ok_for_hw_watchpoint,
 	    default_region_ok_for_hw_watchpoint);
   de_fault (to_terminal_init,
@@ -1881,6 +1890,14 @@
 }
 
 static int
+default_watchpoint_addr_within_range (struct target_ops *target,
+				      CORE_ADDR addr,
+				      CORE_ADDR start, int length)
+{
+  return addr >= start && addr < start + length;
+}
+
+static int
 return_zero (void)
 {
   return 0;
@@ -2448,6 +2465,23 @@
 }
 
 static int
+debug_to_watchpoint_addr_within_range (struct target_ops *target,
+				       CORE_ADDR addr,
+				       CORE_ADDR start, int length)
+{
+  int retval;
+
+  retval = debug_target.to_watchpoint_addr_within_range (target, addr,
+							 start, length);
+
+  fprintf_filtered (gdb_stdlog,
+		    "target_watchpoint_addr_within_range (0x%lx, 0x%lx, %d) = %d\n",
+		    (unsigned long) addr, (unsigned long) start, length,
+		    retval);
+  return retval;
+}
+
+static int
 debug_to_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
 {
   int retval;
@@ -2790,6 +2824,7 @@
   current_target.to_remove_watchpoint = debug_to_remove_watchpoint;
   current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint;
   current_target.to_stopped_data_address = debug_to_stopped_data_address;
+  current_target.to_watchpoint_addr_within_range = debug_to_watchpoint_addr_within_range;
   current_target.to_region_ok_for_hw_watchpoint = debug_to_region_ok_for_hw_watchpoint;
   current_target.to_terminal_init = debug_to_terminal_init;
   current_target.to_terminal_inferior = debug_to_terminal_inferior;
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -r1.78 -r1.79
--- src/gdb/ppc-linux-nat.c	2008/01/16 04:48:55	1.78
+++ src/gdb/ppc-linux-nat.c	2008/05/02 11:07:25	1.79
@@ -889,6 +889,16 @@
   return ppc_linux_stopped_data_address (&current_target, &addr);
 }
 
+static int
+ppc_linux_watchpoint_addr_within_range (struct target_ops *target,
+					CORE_ADDR addr,
+					CORE_ADDR start, int length)
+{
+  addr &= ~7;
+  /* Check whether [start, start+length-1] intersects [addr, addr+7]. */
+  return start <= addr + 7 && start + length - 1 >= addr;
+}
+
 static void
 ppc_linux_store_inferior_registers (struct regcache *regcache, int regno)
 {
@@ -997,6 +1007,7 @@
   t->to_remove_watchpoint = ppc_linux_remove_watchpoint;
   t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint;
   t->to_stopped_data_address = ppc_linux_stopped_data_address;
+  t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
 
   t->to_read_description = ppc_linux_read_description;
 
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.317
retrieving revision 1.318
diff -u -r1.317 -r1.318
--- src/gdb/breakpoint.c	2008/05/01 20:35:33	1.317
+++ src/gdb/breakpoint.c	2008/05/02 11:07:25	1.318
@@ -2616,8 +2616,9 @@
 	for (loc = b->loc; loc; loc = loc->next)
 	  /* Exact match not required.  Within range is
 	     sufficient.  */
-	  if (addr >= loc->address
-	      && addr < loc->address + loc->length)
+	  if (target_watchpoint_addr_within_range (&current_target,
+						   addr, loc->address,
+						   loc->length))
 	    {
 	      b->watchpoint_triggered = watch_triggered_yes;
 	      break;
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.282
retrieving revision 1.283
diff -u -r1.282 -r1.283
--- src/gdb/doc/gdbint.texinfo	2008/04/30 21:16:46	1.282
+++ src/gdb/doc/gdbint.texinfo	2008/05/02 11:07:25	1.283
@@ -9,7 +9,7 @@
 @ifinfo
 This file documents the internals of the GNU debugger @value{GDBN}.
 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006
+   2002, 2003, 2004, 2005, 2006, 2008
    Free Software Foundation, Inc.
 Contributed by Cygnus Solutions.  Written by John Gilmore.
 Second Edition by Stan Shebs.
@@ -711,10 +711,19 @@
 resuming, this method should clear it.  For instance, the x86 debug
 control register has sticky triggered flags.
 
+@findex target_watchpoint_addr_within_range
+@item target_watchpoint_addr_within_range (@var{target}, @var{addr}, @var{start}, @var{length})
+Check whether @var{addr} (as returned by @code{target_stopped_data_address})
+lies within the hardware-defined watchpoint region described by
+@var{start} and @var{length}.  This only needs to be provided if the
+granularity of a watchpoint is greater than one byte, i.e., if the
+watchpoint can also trigger on nearby addresses outside of the watched
+region.
+
 @findex HAVE_STEPPABLE_WATCHPOINT
 @item HAVE_STEPPABLE_WATCHPOINT
 If defined to a non-zero value, it is not necessary to disable a
-watchpoint to step over it.    Like @code{gdbarch_have_nonsteppable_watchpoint},
+watchpoint to step over it.  Like @code{gdbarch_have_nonsteppable_watchpoint},
 this is usually set when watchpoints trigger at the instruction
 which will perform an interesting read or write.  It should be
 set if there is a temporary disable bit which allows the processor



[RFA] Try2: Ignore breakpoints when reading memory.
http://sourceware.org/ml/gdb-patches/2008-03/msg00106.html
http://sourceware.org/ml/gdb-cvs/2008-03/msg00058.html

2008-03-13  Vladimir Prus  <vladimir@codesourcery.com>
	    Daniel Jacobowitz  <dan@codesourcery.com>

	* breakpoint.h (breakpoint_restore_shadows): New
	declaration.
	* breakpoint.c (breakpoint_restore_shadows): New.
	(read_memory_nobpt): Delete.
	* gdbcore.h (read_memory_nobpt): Delete declaration.
	* target.c (memory_xfer_partial): Call
	breakpoint_restore_shadows.
	(restore_show_memory_breakpoints)
	(make_show_memory_beakpoints_cleanup): New.
	(show_memory_breakpoints): New.
	* target.h (make_show_memory_beakpoints_cleanup): Declare.
	* ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint):
	Make sure we see memory breakpoints when checking if
	breakpoint is still there.
	* alpha-tdep.c, alphanbsd-tdep.c, frame.c, frv-tdep.c,
	hppa-linux-tdep.c, hppa-tdep.c, i386-linux-nat.c, i386-tdep.c,
	m68klinux-tdep.c, mips-tdep.c, mn10300-tdep.c, s390-tdep.c,
	sparc-tdep.c: Use target_read_memory instead of read_memory_nobpt.

===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.988
retrieving revision 1.989
diff -u -r1.988 -r1.989
--- src/gdb/Makefile.in	2008/03/10 23:14:05	1.988
+++ src/gdb/Makefile.in	2008/03/13 12:22:08	1.989
@@ -2873,7 +2873,7 @@
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
 	$(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
 	$(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \
-	$(exceptions_h) $(target_descriptions_h)
+	$(exceptions_h) $(target_descriptions_h) $(gdb_stdint_h)
 target-descriptions.o: target-descriptions.c $(defs_h) $(arch_utils_h) \
 	$(target_h) $(target_descriptions_h) $(vec_h) $(xml_tdesc_h) \
 	$(gdbcmd_h) $(gdb_assert_h) $(gdbtypes_h) $(reggroups_h) \
===================================================================
RCS file: /cvs/src/src/gdb/alpha-tdep.c,v
retrieving revision 1.182
retrieving revision 1.183
diff -u -r1.182 -r1.183
--- src/gdb/alpha-tdep.c	2008/02/20 15:45:20	1.182
+++ src/gdb/alpha-tdep.c	2008/03/13 12:22:11	1.183
@@ -638,7 +638,7 @@
   gdb_byte buf[ALPHA_INSN_SIZE];
   int status;
 
-  status = read_memory_nobpt (pc, buf, sizeof (buf));
+  status = target_read_memory (pc, buf, sizeof (buf));
   if (status)
     memory_error (status, pc);
   return extract_unsigned_integer (buf, sizeof (buf));
===================================================================
RCS file: /cvs/src/src/gdb/alphanbsd-tdep.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- src/gdb/alphanbsd-tdep.c	2008/01/01 22:53:09	1.36
+++ src/gdb/alphanbsd-tdep.c	2008/03/13 12:22:11	1.37
@@ -216,7 +216,7 @@
   LONGEST off;
   int i;
 
-  if (read_memory_nobpt (pc, (char *) w, 4) != 0)
+  if (target_read_memory (pc, (char *) w, 4) != 0)
     return -1;
 
   for (i = 0; i < RETCODE_NWORDS; i++)
@@ -230,7 +230,7 @@
   off = i * 4;
   pc -= off;
 
-  if (read_memory_nobpt (pc, (char *) ret, sizeof (ret)) != 0)
+  if (target_read_memory (pc, (char *) ret, sizeof (ret)) != 0)
     return -1;
 
   if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.305
retrieving revision 1.306
diff -u -r1.305 -r1.306
--- src/gdb/breakpoint.c	2008/03/03 13:24:12	1.305
+++ src/gdb/breakpoint.c	2008/03/13 12:22:11	1.306
@@ -702,25 +702,16 @@
   error (_("No breakpoint number %d."), bnum);
 }
 
-/* Like target_read_memory() but if breakpoints are inserted, return
-   the shadow contents instead of the breakpoints themselves.
+/* Update BUF, which is LEN bytes read from the target address MEMADDR,
+   by replacing any memory breakpoints with their shadowed contents.  */
 
-   Read "memory data" from whatever target or inferior we have. 
-   Returns zero if successful, errno value if not.  EIO is used
-   for address out of bounds.  If breakpoints are inserted, returns
-   shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
-
-int
-read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len)
+void
+breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len)
 {
-  int status;
-  const struct bp_location *b;
+  struct bp_location *b;
   CORE_ADDR bp_addr = 0;
   int bp_size = 0;
-
-  if (gdbarch_breakpoint_from_pc (current_gdbarch, &bp_addr, &bp_size) == NULL)
-    /* No breakpoints on this machine. */
-    return target_read_memory (memaddr, myaddr, len);
+  int bptoffset = 0;
 
   ALL_BP_LOCATIONS (b)
   {
@@ -739,59 +730,35 @@
     if (bp_size == 0)
       /* bp isn't valid, or doesn't shadow memory.  */
       continue;
+
     if (bp_addr + bp_size <= memaddr)
       /* The breakpoint is entirely before the chunk of memory we
          are reading.  */
       continue;
+
     if (bp_addr >= memaddr + len)
       /* The breakpoint is entirely after the chunk of memory we are
          reading. */
       continue;
-    /* Copy the breakpoint from the shadow contents, and recurse for
-       the things before and after.  */
-    {
-      /* Offset within shadow_contents.  */
-      int bptoffset = 0;
-
-      if (bp_addr < memaddr)
-	{
-	  /* Only copy the second part of the breakpoint.  */
-	  bp_size -= memaddr - bp_addr;
-	  bptoffset = memaddr - bp_addr;
-	  bp_addr = memaddr;
-	}
-
-      if (bp_addr + bp_size > memaddr + len)
-	{
-	  /* Only copy the first part of the breakpoint.  */
-	  bp_size -= (bp_addr + bp_size) - (memaddr + len);
-	}
 
-      memcpy (myaddr + bp_addr - memaddr,
-	      b->target_info.shadow_contents + bptoffset, bp_size);
+    /* Offset within shadow_contents.  */
+    if (bp_addr < memaddr)
+      {
+	/* Only copy the second part of the breakpoint.  */
+	bp_size -= memaddr - bp_addr;
+	bptoffset = memaddr - bp_addr;
+	bp_addr = memaddr;
+      }
 
-      if (bp_addr > memaddr)
-	{
-	  /* Copy the section of memory before the breakpoint.  */
-	  status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
-	  if (status != 0)
-	    return status;
-	}
+    if (bp_addr + bp_size > memaddr + len)
+      {
+	/* Only copy the first part of the breakpoint.  */
+	bp_size -= (bp_addr + bp_size) - (memaddr + len);
+      }
 
-      if (bp_addr + bp_size < memaddr + len)
-	{
-	  /* Copy the section of memory after the breakpoint.  */
-	  status = read_memory_nobpt (bp_addr + bp_size,
-				      myaddr + bp_addr + bp_size - memaddr,
-				      memaddr + len - (bp_addr + bp_size));
-	  if (status != 0)
-	    return status;
-	}
-      return 0;
-    }
+    memcpy (buf + bp_addr - memaddr,
+	    b->target_info.shadow_contents + bptoffset, bp_size);
   }
-  /* Nothing overlaps.  Just call read_memory_noerr.  */
-  return target_read_memory (memaddr, myaddr, len);
 }
 
 
@@ -4299,7 +4266,7 @@
   /* Adjust the breakpoint's address prior to allocating a location.
      Once we call allocate_bp_location(), that mostly uninitialized
      location will be placed on the location chain.  Adjustment of the
-     breakpoint may cause read_memory_nobpt() to be called and we do
+     breakpoint may cause target_read_memory() to be called and we do
      not want its scan of the location chain to find a breakpoint and
      location that's only been partially initialized.  */
   adjusted_address = adjust_breakpoint_address (sal.pc, bptype);
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- src/gdb/breakpoint.h	2008/03/03 13:24:12	1.66
+++ src/gdb/breakpoint.h	2008/03/13 12:22:12	1.67
@@ -859,4 +859,9 @@
    target.  */
 int watchpoints_triggered (struct target_waitstatus *);
 
+/* Update BUF, which is LEN bytes read from the target address MEMADDR,
+   by replacing any memory breakpoints with their shadowed contents.  */
+void breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, 
+				 LONGEST len);
+
 #endif /* !defined (BREAKPOINT_H) */
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.237
retrieving revision 1.238
diff -u -r1.237 -r1.238
--- src/gdb/frame.c	2008/02/28 16:24:24	1.237
+++ src/gdb/frame.c	2008/03/13 12:22:12	1.238
@@ -1691,8 +1691,8 @@
 safe_frame_unwind_memory (struct frame_info *this_frame,
 			  CORE_ADDR addr, gdb_byte *buf, int len)
 {
-  /* NOTE: read_memory_nobpt returns zero on success!  */
-  return !read_memory_nobpt (addr, buf, len);
+  /* NOTE: target_read_memory returns zero on success!  */
+  return !target_read_memory (addr, buf, len);
 }
 
 /* Architecture method.  */
===================================================================
RCS file: /cvs/src/src/gdb/frv-tdep.c,v
retrieving revision 1.118
retrieving revision 1.119
diff -u -r1.118 -r1.119
--- src/gdb/frv-tdep.c	2008/01/11 13:19:59	1.118
+++ src/gdb/frv-tdep.c	2008/03/13 12:22:12	1.119
@@ -449,7 +449,7 @@
       char instr[frv_instr_size];
       int status;
 
-      status = read_memory_nobpt (addr, instr, sizeof instr);
+      status = target_read_memory (addr, instr, sizeof instr);
 
       if (status != 0)
 	break;
===================================================================
RCS file: /cvs/src/src/gdb/gdbcore.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- src/gdb/gdbcore.h	2008/01/01 22:53:10	1.28
+++ src/gdb/gdbcore.h	2008/03/13 12:22:12	1.29
@@ -39,18 +39,6 @@
 
 extern int have_core_file_p (void);
 
-/* Read "memory data" from whatever target or inferior we have.
-   Returns zero if successful, errno value if not.  EIO is used for
-   address out of bounds.  If breakpoints are inserted, returns shadow
-   contents, not the breakpoints themselves.  From breakpoint.c.  */
-
-/* NOTE: cagney/2004-06-10: Code reading from a live inferior can use
-   the get_frame_memory methods, code reading from an exec can use the
-   target methods.  */
-
-extern int read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr,
-			      unsigned len);
-
 /* Report a memory error with error().  */
 
 extern void memory_error (int status, CORE_ADDR memaddr);
===================================================================
RCS file: /cvs/src/src/gdb/hppa-linux-tdep.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- src/gdb/hppa-linux-tdep.c	2008/02/18 16:11:21	1.27
+++ src/gdb/hppa-linux-tdep.c	2008/03/13 12:22:12	1.28
@@ -101,7 +101,7 @@
     {
       char buf[4];
 
-      read_memory_nobpt (npc, buf, 4);
+      target_read_memory (npc, buf, 4);
       insn[i] = extract_unsigned_integer (buf, 4);
       if ((insn[i] & pattern[i].mask) == pattern[i].data)
         npc += 4;
===================================================================
RCS file: /cvs/src/src/gdb/hppa-tdep.c,v
retrieving revision 1.247
retrieving revision 1.248
diff -u -r1.247 -r1.248
--- src/gdb/hppa-tdep.c	2008/02/18 16:11:21	1.247
+++ src/gdb/hppa-tdep.c	2008/03/13 12:22:12	1.248
@@ -545,7 +545,7 @@
   char buf[4];
   int off;
 
-  status = read_memory_nobpt (pc, buf, 4);
+  status = target_read_memory (pc, buf, 4);
   if (status != 0)
     return 0;
 
@@ -1552,7 +1552,7 @@
       old_save_sp = save_sp;
       old_stack_remaining = stack_remaining;
 
-      status = read_memory_nobpt (pc, buf, 4);
+      status = target_read_memory (pc, buf, 4);
       inst = extract_unsigned_integer (buf, 4);
 
       /* Yow! */
@@ -1603,7 +1603,7 @@
 		 && reg_num <= 26)
 	    {
 	      pc += 4;
-	      status = read_memory_nobpt (pc, buf, 4);
+	      status = target_read_memory (pc, buf, 4);
 	      inst = extract_unsigned_integer (buf, 4);
 	      if (status != 0)
 		return pc;
@@ -1616,7 +1616,7 @@
       reg_num = inst_saves_fr (inst);
       save_fr &= ~(1 << reg_num);
 
-      status = read_memory_nobpt (pc + 4, buf, 4);
+      status = target_read_memory (pc + 4, buf, 4);
       next_inst = extract_unsigned_integer (buf, 4);
 
       /* Yow! */
@@ -1647,13 +1647,13 @@
 		      <= (gdbarch_ptr_bit (gdbarch) == 64 ? 11 : 7))
 	    {
 	      pc += 8;
-	      status = read_memory_nobpt (pc, buf, 4);
+	      status = target_read_memory (pc, buf, 4);
 	      inst = extract_unsigned_integer (buf, 4);
 	      if (status != 0)
 		return pc;
 	      if ((inst & 0xfc000000) != 0x34000000)
 		break;
-	      status = read_memory_nobpt (pc + 4, buf, 4);
+	      status = target_read_memory (pc + 4, buf, 4);
 	      next_inst = extract_unsigned_integer (buf, 4);
 	      if (status != 0)
 		return pc;
@@ -2857,7 +2857,7 @@
     {
       gdb_byte buf[HPPA_INSN_SIZE];
 
-      read_memory_nobpt (npc, buf, HPPA_INSN_SIZE);
+      target_read_memory (npc, buf, HPPA_INSN_SIZE);
       insn[i] = extract_unsigned_integer (buf, HPPA_INSN_SIZE);
       if ((insn[i] & pattern[i].mask) == pattern[i].data)
         npc += 4;
===================================================================
RCS file: /cvs/src/src/gdb/i386-linux-nat.c,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -r1.86 -r1.87
--- src/gdb/i386-linux-nat.c	2008/03/01 04:39:36	1.86
+++ src/gdb/i386-linux-nat.c	2008/03/13 12:22:13	1.87
@@ -770,7 +770,7 @@
          that's about to be restored, and set the trace flag there.  */
 
       /* First check if PC is at a system call.  */
-      if (read_memory_nobpt (pc, buf, LINUX_SYSCALL_LEN) == 0
+      if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0
 	  && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
 	{
 	  ULONGEST syscall;
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.251
retrieving revision 1.252
diff -u -r1.251 -r1.252
--- src/gdb/i386-tdep.c	2008/03/11 05:21:38	1.251
+++ src/gdb/i386-tdep.c	2008/03/13 12:22:13	1.252
@@ -344,7 +344,7 @@
   long delta = 0;
   int data16 = 0;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
   if (op == 0x66)
     {
       data16 = 1;
@@ -410,12 +410,12 @@
   if (current_pc <= pc)
     return pc;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op != 0x58)		/* popl %eax */
     return pc;
 
-  read_memory_nobpt (pc + 1, buf, 4);
+  target_read_memory (pc + 1, buf, 4);
   if (memcmp (buf, proto1, 3) != 0 && memcmp (buf, proto2, 4) != 0)
     return pc;
 
@@ -454,7 +454,7 @@
   gdb_byte buf[8];
   gdb_byte op;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op == 0x68 || op == 0x6a)
     {
@@ -541,7 +541,7 @@
   struct i386_insn *insn;
   gdb_byte op;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   for (insn = skip_insns; insn->len > 0; insn++)
     {
@@ -554,7 +554,7 @@
 	  gdb_assert (insn->len > 1);
 	  gdb_assert (insn->len <= I386_MAX_INSN_LEN);
 
-	  read_memory_nobpt (pc + 1, buf, insn->len - 1);
+	  target_read_memory (pc + 1, buf, insn->len - 1);
 	  for (i = 1; i < insn->len; i++)
 	    {
 	      if ((buf[i - 1] & insn->mask[i]) != insn->insn[i])
@@ -632,7 +632,7 @@
   gdb_byte op;
   int check = 1;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   while (check) 
     {
@@ -641,7 +641,7 @@
       if (op == 0x90) 
 	{
 	  pc += 1;
-	  read_memory_nobpt (pc, &op, 1);
+	  target_read_memory (pc, &op, 1);
 	  check = 1;
 	}
       /* Ignore no-op instruction `mov %edi, %edi'.
@@ -657,11 +657,11 @@
 
       else if (op == 0x8b)
 	{
-	  read_memory_nobpt (pc + 1, &op, 1);
+	  target_read_memory (pc + 1, &op, 1);
 	  if (op == 0xff)
 	    {
 	      pc += 2;
-	      read_memory_nobpt (pc, &op, 1);
+	      target_read_memory (pc, &op, 1);
 	      check = 1;
 	    }
 	}
@@ -685,7 +685,7 @@
   if (limit <= pc)
     return limit;
 
-  read_memory_nobpt (pc, &op, 1);
+  target_read_memory (pc, &op, 1);
 
   if (op == 0x55)		/* pushl %ebp */
     {
@@ -720,7 +720,7 @@
       if (limit <= pc + skip)
 	return limit;
 
-      read_memory_nobpt (pc + skip, &op, 1);
+      target_read_memory (pc + skip, &op, 1);
 
       /* Check for `movl %esp, %ebp' -- can be written in two ways.  */
       switch (op)
@@ -754,7 +754,7 @@
 
 	 NOTE: You can't subtract a 16-bit immediate from a 32-bit
 	 reg, so we don't have to worry about a data16 prefix.  */
-      read_memory_nobpt (pc, &op, 1);
+      target_read_memory (pc, &op, 1);
       if (op == 0x83)
 	{
 	  /* `subl' with 8-bit immediate.  */
@@ -810,7 +810,7 @@
     offset -= cache->locals;
   for (i = 0; i < 8 && pc < current_pc; i++)
     {
-      read_memory_nobpt (pc, &op, 1);
+      target_read_memory (pc, &op, 1);
       if (op < 0x50 || op > 0x57)
 	break;
 
@@ -900,7 +900,7 @@
 
   for (i = 0; i < 6; i++)
     {
-      read_memory_nobpt (pc + i, &op, 1);
+      target_read_memory (pc + i, &op, 1);
       if (pic_pat[i] != op)
 	break;
     }
@@ -908,7 +908,7 @@
     {
       int delta = 6;
 
-      read_memory_nobpt (pc + delta, &op, 1);
+      target_read_memory (pc + delta, &op, 1);
 
       if (op == 0x89)		/* movl %ebx, x(%ebp) */
 	{
@@ -921,7 +921,7 @@
 	  else			/* Unexpected instruction.  */
 	    delta = 0;
 
-          read_memory_nobpt (pc + delta, &op, 1);
+          target_read_memory (pc + delta, &op, 1);
 	}
 
       /* addl y,%ebx */
===================================================================
RCS file: /cvs/src/src/gdb/m68klinux-tdep.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- src/gdb/m68klinux-tdep.c	2008/01/01 22:53:12	1.27
+++ src/gdb/m68klinux-tdep.c	2008/03/13 12:22:13	1.28
@@ -69,7 +69,7 @@
   char buf[12];
   unsigned long insn0, insn1, insn2;
 
-  if (read_memory_nobpt (pc - 4, buf, sizeof (buf)))
+  if (target_read_memory (pc - 4, buf, sizeof (buf)))
     return 0;
   insn1 = extract_unsigned_integer (buf + 4, 4);
   insn2 = extract_unsigned_integer (buf + 8, 4);
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.469
retrieving revision 1.470
diff -u -r1.469 -r1.470
--- src/gdb/mips-tdep.c	2008/02/20 14:34:43	1.469
+++ src/gdb/mips-tdep.c	2008/03/13 12:22:13	1.470
@@ -926,7 +926,7 @@
     }
   else
     instlen = MIPS_INSN32_SIZE;
-  status = read_memory_nobpt (addr, buf, instlen);
+  status = target_read_memory (addr, buf, instlen);
   if (status)
     memory_error (status, addr);
   return extract_unsigned_integer (buf, instlen);
===================================================================
RCS file: /cvs/src/src/gdb/mn10300-tdep.c,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -r1.154 -r1.155
--- src/gdb/mn10300-tdep.c	2008/02/05 16:20:20	1.154
+++ src/gdb/mn10300-tdep.c	2008/03/13 12:22:13	1.155
@@ -620,7 +620,7 @@
 	goto finish_prologue;
 
       /* Get the next two bytes so the prologue scan can continue.  */
-      status = read_memory_nobpt (addr, buf, 2);
+      status = target_read_memory (addr, buf, 2);
       if (status != 0)
 	goto finish_prologue;
     }
@@ -761,7 +761,7 @@
       if (!fmov_found)
 	{
 	  addr = restore_addr;
-	  status = read_memory_nobpt (addr, buf, 2);
+	  status = target_read_memory (addr, buf, 2);
 	  if (status != 0)
 	    goto finish_prologue;
 	  stack_extra_size = 0;
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -r1.94 -r1.95
--- src/gdb/ppc-linux-tdep.c	2008/02/20 14:31:40	1.94
+++ src/gdb/ppc-linux-tdep.c	2008/03/13 12:22:13	1.95
@@ -281,12 +281,15 @@
   int val;
   int bplen;
   gdb_byte old_contents[BREAKPOINT_MAX];
+  struct cleanup *cleanup;
 
   /* Determine appropriate breakpoint contents and size for this address.  */
   bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
   if (bp == NULL)
     error (_("Software breakpoints not implemented for this target."));
 
+  /* Make sure we see the memory breakpoints.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
   val = target_read_memory (addr, old_contents, bplen);
 
   /* If our breakpoint is no longer at the address, this means that the
@@ -295,6 +298,7 @@
   if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
     val = target_write_memory (addr, bp_tgt->shadow_contents, bplen);
 
+  do_cleanups (cleanup);
   return val;
 }
 
===================================================================
RCS file: /cvs/src/src/gdb/s390-tdep.c,v
retrieving revision 1.170
retrieving revision 1.171
diff -u -r1.170 -r1.171
--- src/gdb/s390-tdep.c	2008/01/31 15:43:32	1.170
+++ src/gdb/s390-tdep.c	2008/03/13 12:22:13	1.171
@@ -503,12 +503,12 @@
   static int s390_instrlen[] = { 2, 4, 4, 6 };
   int instrlen;
 
-  if (read_memory_nobpt (at, &instr[0], 2))
+  if (target_read_memory (at, &instr[0], 2))
     return -1;
   instrlen = s390_instrlen[instr[0] >> 6];
   if (instrlen > 2)
     {
-      if (read_memory_nobpt (at + 2, &instr[2], instrlen - 2))
+      if (target_read_memory (at + 2, &instr[2], instrlen - 2))
         return -1;
     }
   return instrlen;
@@ -1132,19 +1132,19 @@
   int d2;
 
   if (word_size == 4
-      && !read_memory_nobpt (pc - 4, insn, 4)
+      && !target_read_memory (pc - 4, insn, 4)
       && is_rs (insn, op_lm, &r1, &r3, &d2, &b2)
       && r3 == S390_SP_REGNUM - S390_R0_REGNUM)
     return 1;
 
   if (word_size == 4
-      && !read_memory_nobpt (pc - 6, insn, 6)
+      && !target_read_memory (pc - 6, insn, 6)
       && is_rsy (insn, op1_lmy, op2_lmy, &r1, &r3, &d2, &b2)
       && r3 == S390_SP_REGNUM - S390_R0_REGNUM)
     return 1;
 
   if (word_size == 8
-      && !read_memory_nobpt (pc - 6, insn, 6)
+      && !target_read_memory (pc - 6, insn, 6)
       && is_rsy (insn, op1_lmg, op2_lmg, &r1, &r3, &d2, &b2)
       && r3 == S390_SP_REGNUM - S390_R0_REGNUM)
     return 1;
@@ -1658,7 +1658,7 @@
   CORE_ADDR pc = frame_pc_unwind (next_frame);
   bfd_byte sigreturn[2];
 
-  if (read_memory_nobpt (pc, sigreturn, 2))
+  if (target_read_memory (pc, sigreturn, 2))
     return NULL;
 
   if (sigreturn[0] != 0x0a /* svc */)
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.193
retrieving revision 1.194
diff -u -r1.193 -r1.194
--- src/gdb/sparc-tdep.c	2008/01/11 14:43:15	1.193
+++ src/gdb/sparc-tdep.c	2008/03/13 12:22:13	1.194
@@ -99,7 +99,7 @@
   int i;
 
   /* If we can't read the instruction at PC, return zero.  */
-  if (read_memory_nobpt (pc, buf, sizeof (buf)))
+  if (target_read_memory (pc, buf, sizeof (buf)))
     return 0;
 
   insn = 0;
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -r1.155 -r1.156
--- src/gdb/target.c	2008/02/28 16:26:17	1.155
+++ src/gdb/target.c	2008/03/13 12:22:13	1.156
@@ -39,6 +39,7 @@
 #include "gdbcore.h"
 #include "exceptions.h"
 #include "target-descriptions.h"
+#include "gdb_stdint.h"
 
 static void target_info (char *, int);
 
@@ -203,6 +204,11 @@
 
 static int trust_readonly = 0;
 
+/* Nonzero if we should show true memory content including
+   memory breakpoint inserted by gdb.  */
+
+static int show_memory_breakpoints = 0;
+
 /* Non-zero if we want to see trace of target level stuff.  */
 
 static int targetdebug = 0;
@@ -1064,7 +1070,11 @@
       if (res <= 0)
 	return -1;
       else
-	return res;
+	{
+	  if (readbuf && !show_memory_breakpoints)
+	    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+	  return res;
+	}
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1082,22 +1092,41 @@
       res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
 				  readbuf, writebuf, memaddr, reg_len);
       if (res > 0)
-	return res;
+	break;
 
       /* We want to continue past core files to executables, but not
 	 past a running target's memory.  */
       if (ops->to_has_all_memory)
-	return res;
+	break;
 
       ops = ops->beneath;
     }
   while (ops != NULL);
 
+  if (readbuf && !show_memory_breakpoints)
+    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+
   /* If we still haven't got anything, return the last error.  We
      give up.  */
   return res;
 }
 
+static void
+restore_show_memory_breakpoints (void *arg)
+{
+  show_memory_breakpoints = (uintptr_t) arg;
+}
+
+struct cleanup *
+make_show_memory_breakpoints_cleanup (int show)
+{
+  int current = show_memory_breakpoints;
+  show_memory_breakpoints = show;
+
+  return make_cleanup (restore_show_memory_breakpoints,
+		       (void *) (uintptr_t) current);
+}
+
 static LONGEST
 target_xfer_partial (struct target_ops *ops,
 		     enum target_object object, const char *annex,
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -r1.111 -r1.112
--- src/gdb/target.h	2008/02/28 16:26:17	1.111
+++ src/gdb/target.h	2008/03/13 12:22:14	1.112
@@ -1250,6 +1250,11 @@
 
 /* Any target can call this to switch to remote protocol (in remote.c). */
 extern void push_remote_target (char *name, int from_tty);
+
+/* Set the show memory breakpoints mode to show, and installs a cleanup
+   to restore it back to the current value.  */
+extern struct cleanup *make_show_memory_breakpoints_cleanup (int show);
+
 
 /* Imported from machine dependent code */
 



[commit] SIGILL in ld.so when running program from GDB on ia64-linux
http://sourceware.org/ml/gdb-patches/2008-04/msg00674.html
http://sourceware.org/ml/gdb-cvs/2008-04/msg00173.html

2008-04-29  Joel Brobecker  <brobecker@adacore.com>

	* ia64-tdep.c (ia64_memory_remove_breakpoint): Set
	show_memory_breakpoints to 1 while reading the instruction bundle.

===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.174
retrieving revision 1.175
diff -u -r1.174 -r1.175
--- src/gdb/ia64-tdep.c	2008/04/22 11:03:41	1.174
+++ src/gdb/ia64-tdep.c	2008/04/29 21:14:06	1.175
@@ -598,9 +598,15 @@
   long long instr;
   int val;
   int template;
+  struct cleanup *cleanup;
 
   addr &= ~0x0f;
 
+  /* Disable the automatic memory restoration from breakpoints while
+     we read our instruction bundle.  Otherwise, the general restoration
+     mechanism kicks in and ends up corrupting our bundle, because it
+     is not aware of the concept of instruction bundles.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
   val = target_read_memory (addr, bundle, BUNDLE_LEN);
 
   /* Check for L type instruction in 2nd slot, if present then
@@ -616,6 +622,7 @@
   if (val == 0)
     target_write_memory (addr, bundle, BUNDLE_LEN);
 
+  do_cleanups (cleanup);
   return val;
 }