Link Here
|
|
|
1 |
diff --git bfd/elf.c bfd/elf.c |
2 |
index 9846046..6ccdb8f 100644 |
3 |
--- bfd/elf.c |
4 |
+++ bfd/elf.c |
5 |
@@ -9126,6 +9126,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) |
6 |
case NT_SIGINFO: |
7 |
return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo", |
8 |
note); |
9 |
+ |
10 |
+ case NT_FREEBSD_THRMISC: |
11 |
+ if (note->namesz == 8 |
12 |
+ && strcmp (note->namedata, "FreeBSD") == 0) |
13 |
+ return elfcore_make_note_pseudosection (abfd, ".thrmisc", note); |
14 |
+ else |
15 |
+ return TRUE; |
16 |
} |
17 |
} |
18 |
|
19 |
diff --git gdb/amd64bsd-nat.c gdb/amd64bsd-nat.c |
20 |
index 66d4289..9bb34d6 100644 |
21 |
--- gdb/amd64bsd-nat.c |
22 |
+++ gdb/amd64bsd-nat.c |
23 |
@@ -39,6 +39,17 @@ |
24 |
size_t amd64bsd_xsave_len; |
25 |
#endif |
26 |
|
27 |
+static pid_t |
28 |
+get_ptrace_pid (ptid_t ptid) |
29 |
+{ |
30 |
+ pid_t pid; |
31 |
+ |
32 |
+ pid = ptid_get_lwp (ptid); |
33 |
+ if (pid == 0) |
34 |
+ pid = ptid_get_pid (ptid); |
35 |
+ return pid; |
36 |
+} |
37 |
+ |
38 |
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this |
39 |
for all registers (including the floating-point registers). */ |
40 |
|
41 |
@@ -53,7 +64,7 @@ amd64bsd_fetch_inferior_registers (struc |
42 |
{ |
43 |
struct reg regs; |
44 |
|
45 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
46 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
47 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
48 |
perror_with_name (_("Couldn't get registers")); |
49 |
|
50 |
@@ -71,7 +82,7 @@ amd64bsd_fetch_inferior_registers (struc |
51 |
if (amd64bsd_xsave_len != 0) |
52 |
{ |
53 |
xstateregs = alloca (amd64bsd_xsave_len); |
54 |
- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), |
55 |
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), |
56 |
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1) |
57 |
perror_with_name (_("Couldn't get extended state status")); |
58 |
|
59 |
@@ -80,7 +91,7 @@ amd64bsd_fetch_inferior_registers (struc |
60 |
} |
61 |
#endif |
62 |
|
63 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
64 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
65 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
66 |
perror_with_name (_("Couldn't get floating point status")); |
67 |
|
68 |
@@ -103,11 +114,11 @@ amd64bsd_store_inferior_registers (struc |
69 |
|
70 |
memset( ®s, 0, sizeof(struct reg)); |
71 |
memset( &oldregs, 0, sizeof(struct reg)); |
72 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
73 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
74 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
75 |
perror_with_name (_("Couldn't get registers")); |
76 |
|
77 |
- ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
78 |
+ ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
79 |
(PTRACE_TYPE_ARG3) &oldregs, 0); |
80 |
amd64_collect_native_gregset (regcache, ®s, regnum); |
81 |
|
82 |
@@ -117,7 +128,7 @@ amd64bsd_store_inferior_registers (struc |
83 |
regs.r_rflags ^= (regs.r_rflags ^ oldregs.r_rflags ) & ~PSL_USERCHANGE; |
84 |
//printf(" allowed regs.r_rflags = 0x%8.8X\n", regs.r_rflags ); |
85 |
} |
86 |
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), |
87 |
+ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), |
88 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
89 |
perror_with_name (_("Couldn't write registers")); |
90 |
|
91 |
@@ -134,26 +145,26 @@ amd64bsd_store_inferior_registers (struc |
92 |
if (amd64bsd_xsave_len != 0) |
93 |
{ |
94 |
xstateregs = alloca (amd64bsd_xsave_len); |
95 |
- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), |
96 |
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), |
97 |
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1) |
98 |
perror_with_name (_("Couldn't get extended state status")); |
99 |
|
100 |
amd64_collect_xsave (regcache, regnum, xstateregs, 0); |
101 |
|
102 |
- if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), |
103 |
+ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid), |
104 |
(PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1) |
105 |
perror_with_name (_("Couldn't write extended state status")); |
106 |
return; |
107 |
} |
108 |
#endif |
109 |
|
110 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
111 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
112 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
113 |
perror_with_name (_("Couldn't get floating point status")); |
114 |
|
115 |
amd64_collect_fxsave (regcache, regnum, &fpregs); |
116 |
|
117 |
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), |
118 |
+ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), |
119 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
120 |
perror_with_name (_("Couldn't write floating point status")); |
121 |
} |
122 |
@@ -183,7 +194,7 @@ amd64bsd_dr_get (ptid_t ptid, int regnum |
123 |
{ |
124 |
struct dbreg dbregs; |
125 |
|
126 |
- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), |
127 |
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), |
128 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
129 |
perror_with_name (_("Couldn't read debug registers")); |
130 |
|
131 |
@@ -195,7 +206,7 @@ amd64bsd_dr_set (int regnum, unsigned lo |
132 |
{ |
133 |
struct dbreg dbregs; |
134 |
|
135 |
- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), |
136 |
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), |
137 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
138 |
perror_with_name (_("Couldn't get debug registers")); |
139 |
|
140 |
@@ -195,7 +206,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) |
141 |
|
142 |
DBREG_DRX ((&dbregs), regnum) = value; |
143 |
|
144 |
- if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid), |
145 |
+ if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid), |
146 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
147 |
perror_with_name (_("Couldn't write debug registers")); |
148 |
} |
149 |
diff --git gdb/config.in gdb/config.in |
150 |
index 9ef53b3..0e3166b 100644 |
151 |
--- gdb/config.in |
152 |
+++ gdb/config.in |
153 |
@@ -450,6 +450,9 @@ |
154 |
/* Define to 1 if your system has struct lwp. */ |
155 |
#undef HAVE_STRUCT_LWP |
156 |
|
157 |
+/* Define to 1 if `struct ptrace_lwpinfo' is a member of `pl_tdname'. */ |
158 |
+#undef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME |
159 |
+ |
160 |
/* Define to 1 if your system has struct reg in <machine/reg.h>. */ |
161 |
#undef HAVE_STRUCT_REG |
162 |
|
163 |
diff --git gdb/configure gdb/configure |
164 |
index e8979f0..62f8886 100755 |
165 |
--- gdb/configure |
166 |
+++ gdb/configure |
167 |
@@ -12502,6 +12502,22 @@ $as_echo "#define HAVE_PT_GETXMMREGS 1" >>confdefs.h |
168 |
|
169 |
fi |
170 |
|
171 |
+# See if <sys/ptrace.h> supports LWP names on FreeBSD |
172 |
+# Older FreeBSD versions don't have the pl_tdname member of |
173 |
+# `struct ptrace_lwpinfo'. |
174 |
+ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_tdname" "ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" "#include <sys/ptrace.h> |
175 |
+" |
176 |
+if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" = x""yes; then : |
177 |
+ |
178 |
+cat >>confdefs.h <<_ACEOF |
179 |
+#define HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 1 |
180 |
+_ACEOF |
181 |
+ |
182 |
+ |
183 |
+fi |
184 |
+ |
185 |
+ |
186 |
+ |
187 |
# Detect which type of /proc is in use, such as for Solaris. |
188 |
|
189 |
if test "${target}" = "${host}"; then |
190 |
diff --git gdb/configure.ac gdb/configure.ac |
191 |
index a40860a..6664355 100644 |
192 |
--- gdb/configure.ac |
193 |
+++ gdb/configure.ac |
194 |
@@ -1564,6 +1564,13 @@ if test $gdb_cv_have_pt_getxmmregs = yes; then |
195 |
[Define if sys/ptrace.h defines the PT_GETXMMREGS request.]) |
196 |
fi |
197 |
|
198 |
+# See if <sys/ptrace.h> supports LWP names on FreeBSD |
199 |
+# Older FreeBSD versions don't have the pl_tdname member of |
200 |
+# `struct ptrace_lwpinfo'. |
201 |
+AC_CHECK_MEMBERS([struct ptrace_lwpinfo.pl_tdname], [], [], |
202 |
+ [#include <sys/ptrace.h>]) |
203 |
+ |
204 |
+ |
205 |
# Detect which type of /proc is in use, such as for Solaris. |
206 |
|
207 |
if test "${target}" = "${host}"; then |
208 |
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c |
209 |
index 9705d45..6210dcf 100644 |
210 |
--- gdb/fbsd-nat.c |
211 |
+++ gdb/fbsd-nat.c |
212 |
@@ -22,6 +22,7 @@ |
213 |
#include "inferior.h" |
214 |
#include "regcache.h" |
215 |
#include "regset.h" |
216 |
+#include "gdbcmd.h" |
217 |
#include "gdbthread.h" |
218 |
#include "gdb_wait.h" |
219 |
#include <sys/types.h> |
220 |
@@ -204,11 +205,340 @@ fbsd_find_memory_regions (struct target_ops *self, |
221 |
#endif |
222 |
|
223 |
#ifdef PT_LWPINFO |
224 |
+static int debug_fbsd_lwp; |
225 |
+ |
226 |
static ptid_t (*super_wait) (struct target_ops *, |
227 |
ptid_t, |
228 |
struct target_waitstatus *, |
229 |
int); |
230 |
|
231 |
+#if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME) |
232 |
+/* Fetch the external variant of the kernel's internal process |
233 |
+ structure for the process PID into KP. */ |
234 |
+ |
235 |
+static void |
236 |
+fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) |
237 |
+{ |
238 |
+ size_t len; |
239 |
+ int mib[4]; |
240 |
+ |
241 |
+ len = sizeof *kp; |
242 |
+ mib[0] = CTL_KERN; |
243 |
+ mib[1] = KERN_PROC; |
244 |
+ mib[2] = KERN_PROC_PID; |
245 |
+ mib[3] = pid; |
246 |
+ if (sysctl (mib, 4, kp, &len, NULL, 0) == -1) |
247 |
+ perror_with_name (("sysctl")); |
248 |
+} |
249 |
+#endif |
250 |
+ |
251 |
+/* |
252 |
+ FreeBSD's first thread support was via a "reentrant" version of libc |
253 |
+ (libc_r) that first shipped in 2.2.7. This library multiplexed all |
254 |
+ of the threads in a process onto a single kernel thread. This |
255 |
+ library is supported via the bsd-uthread target. |
256 |
+ |
257 |
+ FreeBSD 5.1 introduced two new threading libraries that made use of |
258 |
+ multiple kernel threads. The first (libkse) scheduled M user |
259 |
+ threads onto N (<= M) kernel threads (LWPs). The second (libthr) |
260 |
+ bound each user thread to a dedicated kernel thread. libkse shipped |
261 |
+ as the default threading library (libpthread). |
262 |
+ |
263 |
+ FreeBSD 5.3 added a libthread_db to abstract the interface across |
264 |
+ the various thread libraries (libc_r, libkse, and libthr). |
265 |
+ |
266 |
+ FreeBSD 7.0 switched the default threading library from from libkse |
267 |
+ to libpthread and removed libc_r. |
268 |
+ |
269 |
+ FreeBSD 8.0 removed libkse and the in-kernel support for it. The |
270 |
+ only threading library supported by 8.0 and later is libthr which |
271 |
+ ties each user thread directly to an LWP. To simplify the |
272 |
+ implementation, this target only supports LWP-backed threads using |
273 |
+ ptrace directly rather than libthread_db. |
274 |
+*/ |
275 |
+ |
276 |
+/* Return true if PTID is still active in the inferior. */ |
277 |
+ |
278 |
+static int |
279 |
+fbsd_thread_alive (struct target_ops *ops, ptid_t ptid) |
280 |
+{ |
281 |
+ if (ptid_lwp_p (ptid)) |
282 |
+ { |
283 |
+ struct ptrace_lwpinfo pl; |
284 |
+ |
285 |
+ if (ptrace (PT_LWPINFO, ptid_get_lwp (ptid), (caddr_t)&pl, sizeof pl) |
286 |
+ == -1) |
287 |
+ return 0; |
288 |
+#ifdef PL_FLAG_EXITED |
289 |
+ if (pl.pl_flags & PL_FLAG_EXITED) |
290 |
+ return 0; |
291 |
+#endif |
292 |
+ } |
293 |
+ |
294 |
+ return 1; |
295 |
+} |
296 |
+ |
297 |
+/* Convert PTID to a string. Returns the string in a static |
298 |
+ buffer. */ |
299 |
+ |
300 |
+static char * |
301 |
+fbsd_pid_to_str (struct target_ops *ops, ptid_t ptid) |
302 |
+{ |
303 |
+ lwpid_t lwp; |
304 |
+ |
305 |
+ lwp = ptid_get_lwp (ptid); |
306 |
+ if (lwp != 0) |
307 |
+ { |
308 |
+ static char buf[64]; |
309 |
+ int pid = ptid_get_pid (ptid); |
310 |
+ |
311 |
+ xsnprintf (buf, sizeof buf, "process %d, LWP %d", pid, lwp); |
312 |
+ return buf; |
313 |
+ } |
314 |
+ |
315 |
+ return normal_pid_to_str (ptid); |
316 |
+} |
317 |
+ |
318 |
+#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME |
319 |
+static char * |
320 |
+fbsd_thread_name (struct target_ops *self, struct thread_info *thr) |
321 |
+{ |
322 |
+ struct ptrace_lwpinfo pl; |
323 |
+ struct kinfo_proc kp; |
324 |
+ int pid = ptid_get_pid (thr->ptid); |
325 |
+ long lwp = ptid_get_lwp (thr->ptid); |
326 |
+ static char buf[64]; |
327 |
+ |
328 |
+ if (!ptid_lwp_p (thr->ptid)) |
329 |
+ return NULL; |
330 |
+ fbsd_fetch_kinfo_proc (pid, &kp); |
331 |
+ if (ptrace (PT_LWPINFO, lwp, (caddr_t)&pl, sizeof pl) == -1) |
332 |
+ perror_with_name (("ptrace")); |
333 |
+ if (strcmp (kp.ki_comm, pl.pl_tdname) == 0) |
334 |
+ return NULL; |
335 |
+ xsnprintf (buf, sizeof buf, "%s", pl.pl_tdname); |
336 |
+ return buf; |
337 |
+} |
338 |
+#endif |
339 |
+ |
340 |
+#ifdef PT_LWP_EVENTS |
341 |
+static void |
342 |
+fbsd_switch_to_threaded (pid_t pid) |
343 |
+{ |
344 |
+ struct cleanup *cleanup; |
345 |
+ lwpid_t *lwps; |
346 |
+ struct ptrace_lwpinfo *pl; |
347 |
+ int i, nlwps; |
348 |
+ |
349 |
+ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); |
350 |
+ if (nlwps == -1) |
351 |
+ perror_with_name (("ptrace")); |
352 |
+ |
353 |
+ lwps = xcalloc (nlwps, sizeof *lwps); |
354 |
+ cleanup = make_cleanup (xfree, lwps); |
355 |
+ |
356 |
+ nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t)lwps, nlwps); |
357 |
+ if (nlwps == -1) |
358 |
+ perror_with_name (("ptrace")); |
359 |
+ pl = xcalloc (nlwps, sizeof *pl); |
360 |
+ make_cleanup (xfree, pl); |
361 |
+ for (i = 0; i < nlwps; i++) |
362 |
+ { |
363 |
+ if (ptrace (PT_LWPINFO, lwps[i], (caddr_t)&pl[i], sizeof pl[i]) == -1) |
364 |
+ perror_with_name (("ptrace")); |
365 |
+ } |
366 |
+ |
367 |
+ /* Choose a candidate thread for the main thread. Prefer the first |
368 |
+ non-BORN and non-EXITED thread. If all threads are newborns, use |
369 |
+ the first non-EXITED thread. */ |
370 |
+ for (i = 0; i < nlwps; i++) |
371 |
+ { |
372 |
+ ptid_t ptid = ptid_build (pid, lwps[i], 0); |
373 |
+ |
374 |
+ if ((pl[i].pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) != 0) |
375 |
+ continue; |
376 |
+ |
377 |
+ if (debug_fbsd_lwp) |
378 |
+ fprintf_unfiltered (gdb_stdlog, |
379 |
+ "FLWP: using LWP %u as main thread\n", |
380 |
+ lwps[i]); |
381 |
+ gdb_assert (!in_thread_list (ptid)); |
382 |
+ thread_change_ptid (inferior_ptid, ptid); |
383 |
+ break; |
384 |
+ } |
385 |
+ for (i = 0; i < nlwps; i++) |
386 |
+ { |
387 |
+ ptid_t ptid = ptid_build (pid, lwps[i], 0); |
388 |
+ |
389 |
+ if (pl[i].pl_flags & PL_FLAG_EXITED) |
390 |
+ continue; |
391 |
+ |
392 |
+ if (!ptid_lwp_p (inferior_ptid)) |
393 |
+ { |
394 |
+ if (debug_fbsd_lwp) |
395 |
+ fprintf_unfiltered (gdb_stdlog, |
396 |
+ "FLWP: using LWP %u as main thread\n", |
397 |
+ lwps[i]); |
398 |
+ gdb_assert (!in_thread_list (ptid)); |
399 |
+ thread_change_ptid (inferior_ptid, ptid); |
400 |
+ } |
401 |
+ else if (!in_thread_list (ptid)) |
402 |
+ { |
403 |
+ if (debug_fbsd_lwp) |
404 |
+ fprintf_unfiltered (gdb_stdlog, |
405 |
+ "FLWP: adding thread for LWP %u\n", |
406 |
+ lwps[i]); |
407 |
+ add_thread (ptid); |
408 |
+ } |
409 |
+ } |
410 |
+ |
411 |
+ do_cleanups (cleanup); |
412 |
+} |
413 |
+ |
414 |
+static void |
415 |
+fbsd_enable_lwp_events (pid_t pid) |
416 |
+{ |
417 |
+ if (ptrace (PT_LWP_EVENTS, pid, (PTRACE_TYPE_ARG3)0, 1) == -1) |
418 |
+ perror_with_name (("ptrace")); |
419 |
+} |
420 |
+#else |
421 |
+static void |
422 |
+fbsd_add_threads (pid_t pid, int nlwps) |
423 |
+{ |
424 |
+ struct cleanup *cleanup; |
425 |
+ lwpid_t *lwps; |
426 |
+ int i; |
427 |
+ |
428 |
+ lwps = xcalloc (nlwps, sizeof *lwps); |
429 |
+ cleanup = make_cleanup (xfree, lwps); |
430 |
+ |
431 |
+ nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t)lwps, nlwps); |
432 |
+ if (nlwps == -1) |
433 |
+ perror_with_name (("ptrace")); |
434 |
+ |
435 |
+ for (i = 0; i < nlwps; i++) |
436 |
+ { |
437 |
+ ptid_t ptid = ptid_build (pid, lwps[i], 0); |
438 |
+ |
439 |
+ /* If this inferior is not using LWP ptids, use the first LWP as |
440 |
+ the main thread. */ |
441 |
+ if (!ptid_lwp_p (inferior_ptid)) |
442 |
+ { |
443 |
+ if (debug_fbsd_lwp) |
444 |
+ fprintf_unfiltered (gdb_stdlog, |
445 |
+ "FLWP: using LWP %u as main thread\n", |
446 |
+ lwps[i]); |
447 |
+ gdb_assert (!in_thread_list (ptid)); |
448 |
+ thread_change_ptid (inferior_ptid, ptid); |
449 |
+ } |
450 |
+ else if (!in_thread_list (ptid)) |
451 |
+ { |
452 |
+ if (debug_fbsd_lwp) |
453 |
+ fprintf_unfiltered (gdb_stdlog, |
454 |
+ "FLWP: adding thread for LWP %u\n", |
455 |
+ lwps[i]); |
456 |
+ gdb_assert (ptid_lwp_p (inferior_ptid)); |
457 |
+ add_thread (ptid); |
458 |
+ } |
459 |
+ } |
460 |
+ do_cleanups (cleanup); |
461 |
+} |
462 |
+#endif |
463 |
+ |
464 |
+/* Implement the to_update_thread_list target method for this |
465 |
+ target. */ |
466 |
+ |
467 |
+static void |
468 |
+fbsd_update_thread_list (struct target_ops *ops) |
469 |
+{ |
470 |
+#ifdef PT_LWP_EVENTS |
471 |
+ /* With support for thread events, threads are added/deleted from the |
472 |
+ list as events are reported, so just try deleting exited threads. */ |
473 |
+ delete_exited_threads (); |
474 |
+#else |
475 |
+ int nlwps; |
476 |
+ int pid = ptid_get_pid (inferior_ptid); |
477 |
+ |
478 |
+ prune_threads(); |
479 |
+ |
480 |
+ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); |
481 |
+ if (nlwps == -1) |
482 |
+ perror_with_name (("ptrace")); |
483 |
+ |
484 |
+ /* Leave single-threaded processes with a non-threaded ptid alone. */ |
485 |
+ if (nlwps == 1 && !ptid_lwp_p (inferior_ptid)) |
486 |
+ return; |
487 |
+ |
488 |
+ fbsd_add_threads (pid, nlwps); |
489 |
+#endif |
490 |
+} |
491 |
+ |
492 |
+static void (*super_resume) (struct target_ops *, |
493 |
+ ptid_t, |
494 |
+ int, |
495 |
+ enum gdb_signal); |
496 |
+ |
497 |
+static int |
498 |
+resume_one_thread_cb(struct thread_info *tp, void *data) |
499 |
+{ |
500 |
+ ptid_t *ptid = data; |
501 |
+ int request; |
502 |
+ |
503 |
+ if (ptid_get_pid (tp->ptid) != ptid_get_pid (*ptid)) |
504 |
+ return 0; |
505 |
+ |
506 |
+ if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (*ptid)) |
507 |
+ request = PT_RESUME; |
508 |
+ else |
509 |
+ request = PT_SUSPEND; |
510 |
+ |
511 |
+ if (ptrace (request, ptid_get_lwp (tp->ptid), (caddr_t)0, 0) == -1) |
512 |
+ perror_with_name (("ptrace")); |
513 |
+ return 0; |
514 |
+} |
515 |
+ |
516 |
+static int |
517 |
+resume_all_threads_cb(struct thread_info *tp, void *data) |
518 |
+{ |
519 |
+ ptid_t *filter = data; |
520 |
+ |
521 |
+ if (!ptid_match (tp->ptid, *filter)) |
522 |
+ return 0; |
523 |
+ |
524 |
+ /* Ignore single-threaded processes. */ |
525 |
+ if (!ptid_lwp_p (tp->ptid)) |
526 |
+ return 0; |
527 |
+ |
528 |
+ if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), (caddr_t)0, 0) == -1) |
529 |
+ perror_with_name (("ptrace")); |
530 |
+ return 0; |
531 |
+} |
532 |
+ |
533 |
+static void |
534 |
+fbsd_resume (struct target_ops *ops, |
535 |
+ ptid_t ptid, int step, enum gdb_signal signo) |
536 |
+{ |
537 |
+ |
538 |
+ if (debug_fbsd_lwp) |
539 |
+ fprintf_unfiltered (gdb_stdlog, |
540 |
+ "FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n", |
541 |
+ ptid_get_pid (ptid), ptid_get_lwp (ptid), |
542 |
+ ptid_get_tid (ptid)); |
543 |
+ if (ptid_lwp_p (ptid)) |
544 |
+ { |
545 |
+ /* If ptid is a specific LWP, suspend all other LWPs in the process. */ |
546 |
+ iterate_over_threads (resume_one_thread_cb, &ptid); |
547 |
+ } |
548 |
+ else |
549 |
+ { |
550 |
+ /* If ptid is a wildcard, resume all matching threads (they won't run |
551 |
+ until the process is continued however). */ |
552 |
+ iterate_over_threads (resume_all_threads_cb, &ptid); |
553 |
+ ptid = inferior_ptid; |
554 |
+ } |
555 |
+ super_resume (ops, ptid, step, signo); |
556 |
+} |
557 |
+ |
558 |
#ifdef TDP_RFPPWAIT |
559 |
/* |
560 |
To catch fork events, PT_FOLLOW_FORK is set on every traced process |
561 |
@@ -289,24 +619,6 @@ fbsd_is_child_pending (pid_t pid) |
562 |
} |
563 |
return 0; |
564 |
} |
565 |
- |
566 |
-/* Fetch the external variant of the kernel's internal process |
567 |
- structure for the process PID into KP. */ |
568 |
- |
569 |
-static void |
570 |
-fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) |
571 |
-{ |
572 |
- size_t len; |
573 |
- int mib[4]; |
574 |
- |
575 |
- len = sizeof *kp; |
576 |
- mib[0] = CTL_KERN; |
577 |
- mib[1] = KERN_PROC; |
578 |
- mib[2] = KERN_PROC_PID; |
579 |
- mib[3] = pid; |
580 |
- if (sysctl (mib, 4, kp, &len, NULL, 0) == -1) |
581 |
- perror_with_name (("sysctl")); |
582 |
-} |
583 |
#endif |
584 |
|
585 |
/* Wait for the child specified by PTID to do something. Return the |
586 |
@@ -332,6 +644,8 @@ fbsd_wait (struct target_ops *ops, |
587 |
pid = ptid_get_pid (wptid); |
588 |
if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof pl) == -1) |
589 |
perror_with_name (("ptrace")); |
590 |
+ if (!in_thread_list (wptid)) |
591 |
+ wptid = ptid_build (pid, pl.pl_lwpid, 0); |
592 |
|
593 |
#ifdef TDP_RFPPWAIT |
594 |
if (pl.pl_flags & PL_FLAG_FORKED) |
595 |
@@ -386,6 +700,52 @@ fbsd_wait (struct target_ops *ops, |
596 |
return wptid; |
597 |
} |
598 |
#endif |
599 |
+ |
600 |
+#ifdef PT_LWP_EVENTS |
601 |
+ if (pl.pl_flags & PL_FLAG_BORN) |
602 |
+ { |
603 |
+ if (ptid_lwp_p (inferior_ptid)) |
604 |
+ { |
605 |
+ ptid_t ptid = ptid_build (pid, pl.pl_lwpid, 0); |
606 |
+ |
607 |
+ /* If a process stops with multiple newborn threads, |
608 |
+ the first thread birth event will add all of the |
609 |
+ pending threads in fbsd_switch_to_threaded. |
610 |
+ However, each thread will still report a newborn |
611 |
+ stop. */ |
612 |
+ if (!in_thread_list (ptid)) |
613 |
+ { |
614 |
+ if (debug_fbsd_lwp) |
615 |
+ fprintf_unfiltered (gdb_stdlog, |
616 |
+ "FLWP: adding thread for LWP %u\n", |
617 |
+ pl.pl_lwpid); |
618 |
+ gdb_assert(!in_thread_list (ptid)); |
619 |
+ add_thread (ptid); |
620 |
+ } |
621 |
+ } |
622 |
+ else |
623 |
+ fbsd_switch_to_threaded (pid); |
624 |
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS; |
625 |
+ return ptid_build (pid, pl.pl_lwpid, 0); |
626 |
+ } |
627 |
+ if (pl.pl_flags & PL_FLAG_EXITED) |
628 |
+ { |
629 |
+ ptid_t ptid = ptid_build (pid, pl.pl_lwpid, 0); |
630 |
+ |
631 |
+ gdb_assert (in_thread_list (ptid)); |
632 |
+ if (debug_fbsd_lwp) |
633 |
+ fprintf_unfiltered (gdb_stdlog, |
634 |
+ "FLWP: deleting thread for LWP %u\n", |
635 |
+ pl.pl_lwpid); |
636 |
+ if (print_thread_events) |
637 |
+ printf_unfiltered (_("[%s exited]\n"), target_pid_to_str |
638 |
+ (ptid)); |
639 |
+ delete_thread (ptid); |
640 |
+ if (ptrace (PT_CONTINUE, pid, (PTRACE_TYPE_ARG3)1, 0) == -1) |
641 |
+ perror_with_name (("ptrace")); |
642 |
+ continue; |
643 |
+ } |
644 |
+#endif |
645 |
} |
646 |
return wptid; |
647 |
} |
648 |
@@ -451,13 +811,19 @@ fbsd_enable_follow_fork (pid_t pid) |
649 |
if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3)0, 1) == -1) |
650 |
perror_with_name (("ptrace")); |
651 |
} |
652 |
+#endif |
653 |
|
654 |
/* Implement the "to_post_startup_inferior" target_ops method. */ |
655 |
|
656 |
static void |
657 |
fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid) |
658 |
{ |
659 |
+#ifdef TDP_RFPPWAIT |
660 |
fbsd_enable_follow_fork (ptid_get_pid (pid)); |
661 |
+#endif |
662 |
+#ifdef PT_LWP_EVENTS |
663 |
+ fbsd_enable_lwp_events (ptid_get_pid (pid)); |
664 |
+#endif |
665 |
} |
666 |
|
667 |
/* Implement the "to_post_attach" target_ops method. */ |
668 |
@@ -465,9 +831,28 @@ fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid) |
669 |
static void |
670 |
fbsd_post_attach (struct target_ops *self, int pid) |
671 |
{ |
672 |
+ int nlwps; |
673 |
+ |
674 |
+#ifdef TDP_RFPPWAIT |
675 |
fbsd_enable_follow_fork (pid); |
676 |
-} |
677 |
#endif |
678 |
+#ifdef PT_LWP_EVENTS |
679 |
+ fbsd_enable_lwp_events (pid); |
680 |
+#endif |
681 |
+ |
682 |
+ /* Add threads for other LWPs when attaching to a threaded process. */ |
683 |
+ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); |
684 |
+ if (nlwps == -1) |
685 |
+ perror_with_name (("ptrace")); |
686 |
+ if (nlwps > 1) |
687 |
+ { |
688 |
+#ifdef PT_LWP_EVENTS |
689 |
+ fbsd_switch_to_threaded (pid); |
690 |
+#else |
691 |
+ fbsd_add_threads (pid, nlwps); |
692 |
+#endif |
693 |
+ } |
694 |
+} |
695 |
|
696 |
#ifdef PL_FLAG_EXEC |
697 |
/* If the FreeBSD kernel supports PL_FLAG_EXEC, then traced processes |
698 |
@@ -493,16 +878,25 @@ fbsd_nat_add_target (struct target_ops *t) |
699 |
t->to_pid_to_exec_file = fbsd_pid_to_exec_file; |
700 |
t->to_find_memory_regions = fbsd_find_memory_regions; |
701 |
#ifdef PT_LWPINFO |
702 |
+ t->to_thread_alive = fbsd_thread_alive; |
703 |
+ t->to_pid_to_str = fbsd_pid_to_str; |
704 |
+#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME |
705 |
+ t->to_thread_name = fbsd_thread_name; |
706 |
+#endif |
707 |
+ t->to_update_thread_list = fbsd_update_thread_list; |
708 |
+ t->to_has_thread_control = tc_schedlock; |
709 |
+ super_resume = t->to_resume; |
710 |
+ t->to_resume = fbsd_resume; |
711 |
super_wait = t->to_wait; |
712 |
t->to_wait = fbsd_wait; |
713 |
+ t->to_post_startup_inferior = fbsd_post_startup_inferior; |
714 |
+ t->to_post_attach = fbsd_post_attach; |
715 |
#ifdef TDP_RFPPWAIT |
716 |
t->to_follow_fork = fbsd_follow_fork; |
717 |
t->to_insert_fork_catchpoint = fbsd_insert_fork_catchpoint; |
718 |
t->to_remove_fork_catchpoint = fbsd_remove_fork_catchpoint; |
719 |
t->to_insert_vfork_catchpoint = fbsd_insert_vfork_catchpoint; |
720 |
t->to_remove_vfork_catchpoint = fbsd_remove_vfork_catchpoint; |
721 |
- t->to_post_startup_inferior = fbsd_post_startup_inferior; |
722 |
- t->to_post_attach = fbsd_post_attach; |
723 |
#endif |
724 |
#ifdef PL_FLAG_EXEC |
725 |
t->to_insert_exec_catchpoint = fbsd_insert_exec_catchpoint; |
726 |
@@ -511,3 +905,21 @@ fbsd_nat_add_target (struct target_ops *t) |
727 |
#endif |
728 |
add_target (t); |
729 |
} |
730 |
+ |
731 |
+/* Provide a prototype to silence -Wmissing-prototypes. */ |
732 |
+extern initialize_file_ftype _initialize_fbsd_nat; |
733 |
+ |
734 |
+void |
735 |
+_initialize_fbsd_nat (void) |
736 |
+{ |
737 |
+#ifdef PT_LWPINFO |
738 |
+ add_setshow_boolean_cmd ("fbsd-lwp", class_maintenance, |
739 |
+ &debug_fbsd_lwp, _("\ |
740 |
+Set debugging of FreeBSD lwp module."), _("\ |
741 |
+Show debugging of FreeBSD lwp module."), _("\ |
742 |
+Enables printf debugging output."), |
743 |
+ NULL, |
744 |
+ NULL, |
745 |
+ &setdebuglist, &showdebuglist); |
746 |
+#endif |
747 |
+} |
748 |
diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c |
749 |
index 9609cd8..51d1bdc 100644 |
750 |
--- gdb/fbsd-tdep.c |
751 |
+++ gdb/fbsd-tdep.c |
752 |
@@ -28,6 +28,46 @@ |
753 |
#include "fbsd-tdep.h" |
754 |
|
755 |
|
756 |
+/* This is how we want PTIDs from core files to be printed. */ |
757 |
+ |
758 |
+static char * |
759 |
+fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid) |
760 |
+{ |
761 |
+ static char buf[80], name[64]; |
762 |
+ struct bfd_section *section; |
763 |
+ bfd_size_type size; |
764 |
+ char sectionstr[32]; |
765 |
+ |
766 |
+ if (ptid_get_lwp (ptid) != 0) |
767 |
+ { |
768 |
+ snprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld", |
769 |
+ ptid_get_lwp (ptid)); |
770 |
+ section = bfd_get_section_by_name (core_bfd, sectionstr); |
771 |
+ if (section != NULL) |
772 |
+ { |
773 |
+ char *name; |
774 |
+ |
775 |
+ size = bfd_section_size (core_bfd, section); |
776 |
+ name = alloca (size + 1); |
777 |
+ if (bfd_get_section_contents (core_bfd, section, name, (file_ptr) 0, |
778 |
+ size) && name[0] != '\0') |
779 |
+ { |
780 |
+ name[size] = '\0'; |
781 |
+ if (strcmp(name, elf_tdata (core_bfd)->core->program) != 0) |
782 |
+ { |
783 |
+ snprintf (buf, sizeof buf, "LWP %ld \"%s\"", |
784 |
+ ptid_get_lwp (ptid), name); |
785 |
+ return buf; |
786 |
+ } |
787 |
+ } |
788 |
+ } |
789 |
+ snprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid)); |
790 |
+ return buf; |
791 |
+ } |
792 |
+ |
793 |
+ return normal_pid_to_str (ptid); |
794 |
+} |
795 |
+ |
796 |
static int |
797 |
find_signalled_thread (struct thread_info *info, void *data) |
798 |
{ |
799 |
@@ -38,24 +78,20 @@ find_signalled_thread (struct thread_info *info, void *data) |
800 |
return 0; |
801 |
} |
802 |
|
803 |
-static enum gdb_signal |
804 |
-find_stop_signal (void) |
805 |
-{ |
806 |
- struct thread_info *info = |
807 |
- iterate_over_threads (find_signalled_thread, NULL); |
808 |
- |
809 |
- if (info) |
810 |
- return info->suspend.stop_signal; |
811 |
- else |
812 |
- return GDB_SIGNAL_0; |
813 |
-} |
814 |
+/* Structure for passing information from |
815 |
+ fbsd_collect_thread_registers via an iterator to |
816 |
+ fbsd_collect_regset_section_cb. */ |
817 |
|
818 |
struct fbsd_collect_regset_section_cb_data |
819 |
{ |
820 |
+ struct gdbarch *gdbarch; |
821 |
const struct regcache *regcache; |
822 |
bfd *obfd; |
823 |
char *note_data; |
824 |
int *note_size; |
825 |
+ unsigned long lwp; |
826 |
+ enum gdb_signal stop_signal; |
827 |
+ int abort_iteration; |
828 |
}; |
829 |
|
830 |
static void |
831 |
@@ -66,6 +102,9 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, |
832 |
char *buf; |
833 |
struct fbsd_collect_regset_section_cb_data *data = cb_data; |
834 |
|
835 |
+ if (data->abort_iteration) |
836 |
+ return; |
837 |
+ |
838 |
gdb_assert (regset->collect_regset); |
839 |
|
840 |
buf = xmalloc (size); |
841 |
@@ -74,13 +113,74 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, |
842 |
/* PRSTATUS still needs to be treated specially. */ |
843 |
if (strcmp (sect_name, ".reg") == 0) |
844 |
data->note_data = (char *) elfcore_write_prstatus |
845 |
- (data->obfd, data->note_data, data->note_size, |
846 |
- ptid_get_pid (inferior_ptid), find_stop_signal (), buf); |
847 |
+ (data->obfd, data->note_data, data->note_size, data->lwp, |
848 |
+ gdb_signal_to_host (data->stop_signal), buf); |
849 |
else |
850 |
data->note_data = (char *) elfcore_write_register_note |
851 |
(data->obfd, data->note_data, data->note_size, |
852 |
sect_name, buf, size); |
853 |
xfree (buf); |
854 |
+ |
855 |
+ if (data->note_data == NULL) |
856 |
+ data->abort_iteration = 1; |
857 |
+} |
858 |
+ |
859 |
+/* Records the thread's register state for the corefile note |
860 |
+ section. */ |
861 |
+ |
862 |
+static char * |
863 |
+fbsd_collect_thread_registers (const struct regcache *regcache, |
864 |
+ ptid_t ptid, bfd *obfd, |
865 |
+ char *note_data, int *note_size, |
866 |
+ enum gdb_signal stop_signal) |
867 |
+{ |
868 |
+ struct gdbarch *gdbarch = get_regcache_arch (regcache); |
869 |
+ struct fbsd_collect_regset_section_cb_data data; |
870 |
+ |
871 |
+ data.gdbarch = gdbarch; |
872 |
+ data.regcache = regcache; |
873 |
+ data.obfd = obfd; |
874 |
+ data.note_data = note_data; |
875 |
+ data.note_size = note_size; |
876 |
+ data.stop_signal = stop_signal; |
877 |
+ data.abort_iteration = 0; |
878 |
+ data.lwp = ptid_get_lwp (ptid); |
879 |
+ |
880 |
+ gdbarch_iterate_over_regset_sections (gdbarch, |
881 |
+ fbsd_collect_regset_section_cb, |
882 |
+ &data, regcache); |
883 |
+ return data.note_data; |
884 |
+} |
885 |
+ |
886 |
+struct fbsd_corefile_thread_data |
887 |
+{ |
888 |
+ struct gdbarch *gdbarch; |
889 |
+ bfd *obfd; |
890 |
+ char *note_data; |
891 |
+ int *note_size; |
892 |
+ enum gdb_signal stop_signal; |
893 |
+}; |
894 |
+ |
895 |
+/* Records the thread's register state for the corefile note |
896 |
+ section. */ |
897 |
+ |
898 |
+static void |
899 |
+fbsd_corefile_thread (struct thread_info *info, |
900 |
+ struct fbsd_corefile_thread_data *args) |
901 |
+{ |
902 |
+ struct cleanup *old_chain; |
903 |
+ struct regcache *regcache; |
904 |
+ |
905 |
+ regcache = get_thread_arch_regcache (info->ptid, args->gdbarch); |
906 |
+ |
907 |
+ old_chain = save_inferior_ptid (); |
908 |
+ inferior_ptid = info->ptid; |
909 |
+ target_fetch_registers (regcache, -1); |
910 |
+ do_cleanups (old_chain); |
911 |
+ |
912 |
+ args->note_data = fbsd_collect_thread_registers |
913 |
+ (regcache, info->ptid, args->obfd, args->note_data, |
914 |
+ args->note_size, args->stop_signal); |
915 |
} |
916 |
|
917 |
/* Create appropriate note sections for a corefile, returning them in |
918 |
@@ -89,10 +189,10 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, |
919 |
static char * |
920 |
fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) |
921 |
{ |
922 |
- struct regcache *regcache = get_current_regcache (); |
923 |
- char *note_data; |
924 |
+ struct fbsd_corefile_thread_data thread_args; |
925 |
+ char *note_data = NULL; |
926 |
Elf_Internal_Ehdr *i_ehdrp; |
927 |
- struct fbsd_collect_regset_section_cb_data data; |
928 |
+ struct thread_info *curr_thr, *signalled_thr, *thr; |
929 |
|
930 |
/* Put a "FreeBSD" label in the ELF header. */ |
931 |
i_ehdrp = elf_elfheader (obfd); |
932 |
@@ -100,16 +200,6 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) |
933 |
|
934 |
gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch)); |
935 |
|
936 |
- data.regcache = regcache; |
937 |
- data.obfd = obfd; |
938 |
- data.note_data = NULL; |
939 |
- data.note_size = note_size; |
940 |
- target_fetch_registers (regcache, -1); |
941 |
- gdbarch_iterate_over_regset_sections (gdbarch, |
942 |
- fbsd_collect_regset_section_cb, |
943 |
- &data, regcache); |
944 |
- note_data = data.note_data; |
945 |
- |
946 |
if (get_exec_file (0)) |
947 |
{ |
948 |
const char *fname = lbasename (get_exec_file (0)); |
949 |
@@ -123,6 +213,50 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) |
950 |
fname, psargs); |
951 |
} |
952 |
|
953 |
+ /* Thread register information. */ |
954 |
+ TRY |
955 |
+ { |
956 |
+ update_thread_list (); |
957 |
+ } |
958 |
+ CATCH (e, RETURN_MASK_ERROR) |
959 |
+ { |
960 |
+ exception_print (gdb_stderr, e); |
961 |
+ } |
962 |
+ END_CATCH |
963 |
+ |
964 |
+ /* Like the kernel, prefer dumping the signalled thread first. |
965 |
+ "First thread" is what tools use to infer the signalled thread. |
966 |
+ In case there's more than one signalled thread, prefer the |
967 |
+ current thread, if it is signalled. */ |
968 |
+ curr_thr = inferior_thread (); |
969 |
+ if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0) |
970 |
+ signalled_thr = curr_thr; |
971 |
+ else |
972 |
+ { |
973 |
+ signalled_thr = iterate_over_threads (find_signalled_thread, NULL); |
974 |
+ if (signalled_thr == NULL) |
975 |
+ signalled_thr = curr_thr; |
976 |
+ } |
977 |
+ |
978 |
+ thread_args.gdbarch = gdbarch; |
979 |
+ thread_args.obfd = obfd; |
980 |
+ thread_args.note_data = note_data; |
981 |
+ thread_args.note_size = note_size; |
982 |
+ thread_args.stop_signal = signalled_thr->suspend.stop_signal; |
983 |
+ |
984 |
+ fbsd_corefile_thread (signalled_thr, &thread_args); |
985 |
+ ALL_NON_EXITED_THREADS (thr) |
986 |
+ { |
987 |
+ if (thr == signalled_thr) |
988 |
+ continue; |
989 |
+ if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid)) |
990 |
+ continue; |
991 |
+ |
992 |
+ fbsd_corefile_thread (thr, &thread_args); |
993 |
+ } |
994 |
+ |
995 |
+ note_data = thread_args.note_data; |
996 |
+ |
997 |
return note_data; |
998 |
} |
999 |
|
1000 |
@@ -131,5 +265,6 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) |
1001 |
void |
1002 |
fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) |
1003 |
{ |
1004 |
+ set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str); |
1005 |
set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); |
1006 |
} |
1007 |
diff --git gdb/i386bsd-nat.c gdb/i386bsd-nat.c |
1008 |
index ac8a19b..90426fe 100644 |
1009 |
--- gdb/i386bsd-nat.c |
1010 |
+++ gdb/i386bsd-nat.c |
1011 |
@@ -87,6 +87,17 @@ size_t i386bsd_xsave_len; |
1012 |
#endif |
1013 |
|
1014 |
|
1015 |
+static pid_t |
1016 |
+get_ptrace_pid (ptid_t ptid) |
1017 |
+{ |
1018 |
+ pid_t pid; |
1019 |
+ |
1020 |
+ pid = ptid_get_lwp (ptid); |
1021 |
+ if (pid == 0) |
1022 |
+ pid = ptid_get_pid (ptid); |
1023 |
+ return pid; |
1024 |
+} |
1025 |
+ |
1026 |
/* Supply the general-purpose registers in GREGS, to REGCACHE. */ |
1027 |
|
1028 |
static void |
1029 |
@@ -138,7 +149,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, |
1030 |
{ |
1031 |
struct reg regs; |
1032 |
|
1033 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
1034 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
1035 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1036 |
perror_with_name (_("Couldn't get registers")); |
1037 |
|
1038 |
@@ -160,7 +171,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, |
1039 |
char *xstateregs; |
1040 |
|
1041 |
xstateregs = alloca (i386bsd_xsave_len); |
1042 |
- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), |
1043 |
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), |
1044 |
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1) |
1045 |
perror_with_name (_("Couldn't get extended state status")); |
1046 |
|
1047 |
@@ -171,7 +182,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, |
1048 |
|
1049 |
#ifdef HAVE_PT_GETXMMREGS |
1050 |
if (have_ptrace_xmmregs != 0 |
1051 |
- && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), |
1052 |
+ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid), |
1053 |
(PTRACE_TYPE_ARG3) xmmregs, 0) == 0) |
1054 |
{ |
1055 |
have_ptrace_xmmregs = 1; |
1056 |
@@ -181,7 +192,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, |
1057 |
{ |
1058 |
have_ptrace_xmmregs = 0; |
1059 |
#endif |
1060 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
1061 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
1062 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1063 |
perror_with_name (_("Couldn't get floating point status")); |
1064 |
|
1065 |
@@ -203,13 +214,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, |
1066 |
{ |
1067 |
struct reg regs; |
1068 |
|
1069 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
1070 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
1071 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1072 |
perror_with_name (_("Couldn't get registers")); |
1073 |
|
1074 |
i386bsd_collect_gregset (regcache, ®s, regnum); |
1075 |
|
1076 |
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), |
1077 |
+ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), |
1078 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1079 |
perror_with_name (_("Couldn't write registers")); |
1080 |
|
1081 |
@@ -230,13 +241,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, |
1082 |
char *xstateregs; |
1083 |
|
1084 |
xstateregs = alloca (i386bsd_xsave_len); |
1085 |
- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), |
1086 |
+ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), |
1087 |
(PTRACE_TYPE_ARG3) xstateregs, 0) == -1) |
1088 |
perror_with_name (_("Couldn't get extended state status")); |
1089 |
|
1090 |
i387_collect_xsave (regcache, -1, xstateregs, 0); |
1091 |
|
1092 |
- if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), |
1093 |
+ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid), |
1094 |
(PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1) |
1095 |
perror_with_name (_("Couldn't write extended state status")); |
1096 |
return; |
1097 |
@@ -245,14 +256,14 @@ i386bsd_store_inferior_registers (struct target_ops *ops, |
1098 |
|
1099 |
#ifdef HAVE_PT_GETXMMREGS |
1100 |
if (have_ptrace_xmmregs != 0 |
1101 |
- && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), |
1102 |
+ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid), |
1103 |
(PTRACE_TYPE_ARG3) xmmregs, 0) == 0) |
1104 |
{ |
1105 |
have_ptrace_xmmregs = 1; |
1106 |
|
1107 |
i387_collect_fxsave (regcache, regnum, xmmregs); |
1108 |
|
1109 |
- if (ptrace (PT_SETXMMREGS, ptid_get_pid (inferior_ptid), |
1110 |
+ if (ptrace (PT_SETXMMREGS, get_ptrace_pid (inferior_ptid), |
1111 |
(PTRACE_TYPE_ARG3) xmmregs, 0) == -1) |
1112 |
perror_with_name (_("Couldn't write XMM registers")); |
1113 |
} |
1114 |
@@ -260,13 +271,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, |
1115 |
{ |
1116 |
have_ptrace_xmmregs = 0; |
1117 |
#endif |
1118 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
1119 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
1120 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1121 |
perror_with_name (_("Couldn't get floating point status")); |
1122 |
|
1123 |
i387_collect_fsave (regcache, regnum, &fpregs); |
1124 |
|
1125 |
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), |
1126 |
+ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), |
1127 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1128 |
perror_with_name (_("Couldn't write floating point status")); |
1129 |
#ifdef HAVE_PT_GETXMMREGS |
1130 |
@@ -305,7 +316,7 @@ i386bsd_dr_get (ptid_t ptid, int regnum) |
1131 |
{ |
1132 |
struct dbreg dbregs; |
1133 |
|
1134 |
- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), |
1135 |
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), |
1136 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
1137 |
perror_with_name (_("Couldn't read debug registers")); |
1138 |
|
1139 |
@@ -317,7 +328,7 @@ i386bsd_dr_set (int regnum, unsigned int value) |
1140 |
{ |
1141 |
struct dbreg dbregs; |
1142 |
|
1143 |
- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), |
1144 |
+ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), |
1145 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
1146 |
perror_with_name (_("Couldn't get debug registers")); |
1147 |
|
1148 |
@@ -328,7 +339,7 @@ i386bsd_dr_set (int regnum, unsigned int value) |
1149 |
|
1150 |
DBREG_DRX ((&dbregs), regnum) = value; |
1151 |
|
1152 |
- if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid), |
1153 |
+ if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid), |
1154 |
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1) |
1155 |
perror_with_name (_("Couldn't write debug registers")); |
1156 |
} |
1157 |
diff --git gdb/ppcfbsd-nat.c gdb/ppcfbsd-nat.c |
1158 |
index 778e19a..75654af 100644 |
1159 |
--- gdb/ppcfbsd-nat.c |
1160 |
+++ gdb/ppcfbsd-nat.c |
1161 |
@@ -37,6 +37,17 @@ |
1162 |
#include "inf-ptrace.h" |
1163 |
#include "bsd-kvm.h" |
1164 |
|
1165 |
+static pid_t |
1166 |
+get_ptrace_pid (ptid_t ptid) |
1167 |
+{ |
1168 |
+ pid_t pid; |
1169 |
+ |
1170 |
+ pid = ptid_get_lwp (ptid); |
1171 |
+ if (pid == 0) |
1172 |
+ pid = ptid_get_pid (ptid); |
1173 |
+ return pid; |
1174 |
+} |
1175 |
+ |
1176 |
/* Fill GDB's register array with the general-purpose register values |
1177 |
in *GREGSETP. */ |
1178 |
|
1179 |
@@ -121,7 +132,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, |
1180 |
{ |
1181 |
gdb_gregset_t regs; |
1182 |
|
1183 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
1184 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
1185 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1186 |
perror_with_name (_("Couldn't get registers")); |
1187 |
|
1188 |
@@ -132,7 +143,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, |
1189 |
const struct regset *fpregset = ppc_fbsd_fpregset (); |
1190 |
gdb_fpregset_t fpregs; |
1191 |
|
1192 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
1193 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
1194 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1195 |
perror_with_name (_("Couldn't get FP registers")); |
1196 |
|
1197 |
@@ -149,13 +160,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, |
1198 |
{ |
1199 |
gdb_gregset_t regs; |
1200 |
|
1201 |
- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), |
1202 |
+ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), |
1203 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1204 |
perror_with_name (_("Couldn't get registers")); |
1205 |
|
1206 |
fill_gregset (regcache, ®s, regno); |
1207 |
|
1208 |
- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), |
1209 |
+ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), |
1210 |
(PTRACE_TYPE_ARG3) ®s, 0) == -1) |
1211 |
perror_with_name (_("Couldn't write registers")); |
1212 |
|
1213 |
@@ -163,13 +174,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, |
1214 |
{ |
1215 |
gdb_fpregset_t fpregs; |
1216 |
|
1217 |
- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), |
1218 |
+ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), |
1219 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1220 |
perror_with_name (_("Couldn't get FP registers")); |
1221 |
|
1222 |
fill_fpregset (regcache, &fpregs, regno); |
1223 |
|
1224 |
- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), |
1225 |
+ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), |
1226 |
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1) |
1227 |
perror_with_name (_("Couldn't set FP registers")); |
1228 |
} |
1229 |
diff --git include/elf/common.h include/elf/common.h |
1230 |
index e6d8c14..39582df 100644 |
1231 |
--- include/elf/common.h |
1232 |
+++ include/elf/common.h |
1233 |
@@ -594,6 +594,20 @@ |
1234 |
/* Note segment for SystemTap probes. */ |
1235 |
#define NT_STAPSDT 3 |
1236 |
|
1237 |
+/* Note segments for core files on FreeBSD systems. Note name is |
1238 |
+ "FreeBSD". */ |
1239 |
+ |
1240 |
+#define NT_FREEBSD_THRMISC 7 /* Thread miscellaneous info. */ |
1241 |
+#define NT_FREEBSD_PROCSTAT_PROC 8 /* Procstat proc data. */ |
1242 |
+#define NT_FREEBSD_PROCSTAT_FILES 9 /* Procstat files data. */ |
1243 |
+#define NT_FREEBSD_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ |
1244 |
+#define NT_FREEBSD_PROCSTAT_GROUPS 11 /* Procstat groups data. */ |
1245 |
+#define NT_FREEBSD_PROCSTAT_UMASK 12 /* Procstat umask data. */ |
1246 |
+#define NT_FREEBSD_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ |
1247 |
+#define NT_FREEBSD_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ |
1248 |
+#define NT_FREEBSD_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ |
1249 |
+#define NT_FREEBSD_PROCSTAT_AUXV 16 /* Procstat auxv data. */ |
1250 |
+ |
1251 |
/* Note segments for core files on NetBSD systems. Note name |
1252 |
must start with "NetBSD-CORE". */ |
1253 |
|