2008-04-16 15:00:25 +00:00
|
|
|
|
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 */
|
2008-04-22 22:13:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2008-07-14 09:09:04 +00:00
|
|
|
|
Index: gdb-6.8/gdb/thread.c
|
2008-04-22 22:13:56 +00:00
|
|
|
|
===================================================================
|
2008-07-14 09:09:04 +00:00
|
|
|
|
--- 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)
|
2008-04-22 22:13:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
2008-07-14 09:09:04 +00:00
|
|
|
|
|
2008-04-22 22:13:56 +00:00
|
|
|
|
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-04 06:54:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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" \
|
2008-07-07 22:47:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"
|
2008-07-12 07:02:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2008-08-01 06:36:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2008-11-04 05:51:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-11-06 20:52:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (¤t_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 (¤t_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;
|
|
|
|
|
}
|
|
|
|
|
|