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