Commit | Line | Data |
---|---|---|
a904c024 AA |
1 | /* Target-dependent code for FreeBSD, architecture-independent. |
2 | ||
61baf725 | 3 | Copyright (C) 2002-2017 Free Software Foundation, Inc. |
a904c024 AA |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "defs.h" | |
82372b2f | 21 | #include "auxv.h" |
a904c024 AA |
22 | #include "gdbcore.h" |
23 | #include "inferior.h" | |
24 | #include "regcache.h" | |
25 | #include "regset.h" | |
26 | #include "gdbthread.h" | |
e6cdd38e | 27 | #include "xml-syscall.h" |
a904c024 | 28 | |
a904c024 AA |
29 | #include "elf-bfd.h" |
30 | #include "fbsd-tdep.h" | |
31 | ||
32 | ||
4b654465 JB |
33 | /* FreeBSD kernels 12.0 and later include a copy of the |
34 | 'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace | |
35 | operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP. | |
36 | The constants below define the offset of field members and flags in | |
37 | this structure used by methods in this file. Note that the | |
38 | 'ptrace_lwpinfo' struct in the note is preceded by a 4 byte integer | |
39 | containing the size of the structure. */ | |
40 | ||
41 | #define LWPINFO_OFFSET 0x4 | |
42 | ||
43 | /* Offsets in ptrace_lwpinfo. */ | |
44 | #define LWPINFO_PL_FLAGS 0x8 | |
45 | #define LWPINFO64_PL_SIGINFO 0x30 | |
46 | #define LWPINFO32_PL_SIGINFO 0x2c | |
47 | ||
48 | /* Flags in pl_flags. */ | |
49 | #define PL_FLAG_SI 0x20 /* siginfo is valid */ | |
50 | ||
51 | /* Sizes of siginfo_t. */ | |
52 | #define SIZE64_SIGINFO_T 80 | |
53 | #define SIZE32_SIGINFO_T 64 | |
54 | ||
762c974a JB |
55 | static struct gdbarch_data *fbsd_gdbarch_data_handle; |
56 | ||
57 | struct fbsd_gdbarch_data | |
58 | { | |
59 | struct type *siginfo_type; | |
60 | }; | |
61 | ||
62 | static void * | |
63 | init_fbsd_gdbarch_data (struct gdbarch *gdbarch) | |
64 | { | |
65 | return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct fbsd_gdbarch_data); | |
66 | } | |
67 | ||
68 | static struct fbsd_gdbarch_data * | |
69 | get_fbsd_gdbarch_data (struct gdbarch *gdbarch) | |
70 | { | |
71 | return ((struct fbsd_gdbarch_data *) | |
72 | gdbarch_data (gdbarch, fbsd_gdbarch_data_handle)); | |
73 | } | |
74 | ||
79117428 JB |
75 | /* This is how we want PTIDs from core files to be printed. */ |
76 | ||
7a114964 | 77 | static const char * |
79117428 JB |
78 | fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid) |
79 | { | |
80 | static char buf[80]; | |
81 | ||
82 | if (ptid_get_lwp (ptid) != 0) | |
83 | { | |
84 | xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid)); | |
85 | return buf; | |
86 | } | |
87 | ||
88 | return normal_pid_to_str (ptid); | |
89 | } | |
90 | ||
91 | /* Extract the name assigned to a thread from a core. Returns the | |
92 | string in a static buffer. */ | |
93 | ||
94 | static const char * | |
95 | fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr) | |
96 | { | |
97 | static char buf[80]; | |
98 | struct bfd_section *section; | |
99 | bfd_size_type size; | |
79117428 JB |
100 | |
101 | if (ptid_get_lwp (thr->ptid) != 0) | |
102 | { | |
103 | /* FreeBSD includes a NT_FREEBSD_THRMISC note for each thread | |
104 | whose contents are defined by a "struct thrmisc" declared in | |
105 | <sys/procfs.h> on FreeBSD. The per-thread name is stored as | |
106 | a null-terminated string as the first member of the | |
107 | structure. Rather than define the full structure here, just | |
108 | extract the null-terminated name from the start of the | |
109 | note. */ | |
2af9fc44 JB |
110 | thread_section_name section_name (".thrmisc", thr->ptid); |
111 | ||
112 | section = bfd_get_section_by_name (core_bfd, section_name.c_str ()); | |
79117428 JB |
113 | if (section != NULL && bfd_section_size (core_bfd, section) > 0) |
114 | { | |
115 | /* Truncate the name if it is longer than "buf". */ | |
116 | size = bfd_section_size (core_bfd, section); | |
117 | if (size > sizeof buf - 1) | |
118 | size = sizeof buf - 1; | |
119 | if (bfd_get_section_contents (core_bfd, section, buf, (file_ptr) 0, | |
120 | size) | |
121 | && buf[0] != '\0') | |
122 | { | |
123 | buf[size] = '\0'; | |
124 | ||
125 | /* Note that each thread will report the process command | |
126 | as its thread name instead of an empty name if a name | |
127 | has not been set explicitly. Return a NULL name in | |
128 | that case. */ | |
129 | if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0) | |
130 | return buf; | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | return NULL; | |
136 | } | |
137 | ||
4b654465 JB |
138 | /* Implement the "core_xfer_siginfo" gdbarch method. */ |
139 | ||
140 | static LONGEST | |
141 | fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, | |
142 | ULONGEST offset, ULONGEST len) | |
143 | { | |
144 | size_t siginfo_size; | |
145 | ||
a181c0bf | 146 | if (gdbarch_long_bit (gdbarch) == 32) |
4b654465 JB |
147 | siginfo_size = SIZE32_SIGINFO_T; |
148 | else | |
149 | siginfo_size = SIZE64_SIGINFO_T; | |
150 | if (offset > siginfo_size) | |
151 | return -1; | |
152 | ||
153 | thread_section_name section_name (".note.freebsdcore.lwpinfo", inferior_ptid); | |
154 | asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ()); | |
155 | if (section == NULL) | |
156 | return -1; | |
157 | ||
158 | gdb_byte buf[4]; | |
159 | if (!bfd_get_section_contents (core_bfd, section, buf, | |
160 | LWPINFO_OFFSET + LWPINFO_PL_FLAGS, 4)) | |
161 | return -1; | |
162 | ||
163 | int pl_flags = extract_signed_integer (buf, 4, gdbarch_byte_order (gdbarch)); | |
164 | if (!(pl_flags & PL_FLAG_SI)) | |
165 | return -1; | |
166 | ||
167 | if (offset + len > siginfo_size) | |
168 | len = siginfo_size - offset; | |
169 | ||
170 | ULONGEST siginfo_offset; | |
a181c0bf | 171 | if (gdbarch_long_bit (gdbarch) == 32) |
4b654465 JB |
172 | siginfo_offset = LWPINFO_OFFSET + LWPINFO32_PL_SIGINFO; |
173 | else | |
174 | siginfo_offset = LWPINFO_OFFSET + LWPINFO64_PL_SIGINFO; | |
175 | ||
176 | if (!bfd_get_section_contents (core_bfd, section, readbuf, | |
177 | siginfo_offset + offset, len)) | |
178 | return -1; | |
179 | ||
180 | return len; | |
181 | } | |
182 | ||
a904c024 AA |
183 | static int |
184 | find_signalled_thread (struct thread_info *info, void *data) | |
185 | { | |
186 | if (info->suspend.stop_signal != GDB_SIGNAL_0 | |
187 | && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid)) | |
188 | return 1; | |
189 | ||
190 | return 0; | |
191 | } | |
192 | ||
20a0aab3 JB |
193 | /* Structure for passing information from |
194 | fbsd_collect_thread_registers via an iterator to | |
195 | fbsd_collect_regset_section_cb. */ | |
a904c024 AA |
196 | |
197 | struct fbsd_collect_regset_section_cb_data | |
198 | { | |
199 | const struct regcache *regcache; | |
200 | bfd *obfd; | |
201 | char *note_data; | |
202 | int *note_size; | |
20a0aab3 JB |
203 | unsigned long lwp; |
204 | enum gdb_signal stop_signal; | |
205 | int abort_iteration; | |
a904c024 AA |
206 | }; |
207 | ||
208 | static void | |
209 | fbsd_collect_regset_section_cb (const char *sect_name, int size, | |
210 | const struct regset *regset, | |
211 | const char *human_name, void *cb_data) | |
212 | { | |
213 | char *buf; | |
7567e115 SM |
214 | struct fbsd_collect_regset_section_cb_data *data |
215 | = (struct fbsd_collect_regset_section_cb_data *) cb_data; | |
a904c024 | 216 | |
20a0aab3 JB |
217 | if (data->abort_iteration) |
218 | return; | |
219 | ||
a904c024 AA |
220 | gdb_assert (regset->collect_regset); |
221 | ||
224c3ddb | 222 | buf = (char *) xmalloc (size); |
a904c024 AA |
223 | regset->collect_regset (regset, data->regcache, -1, buf, size); |
224 | ||
225 | /* PRSTATUS still needs to be treated specially. */ | |
226 | if (strcmp (sect_name, ".reg") == 0) | |
227 | data->note_data = (char *) elfcore_write_prstatus | |
20a0aab3 JB |
228 | (data->obfd, data->note_data, data->note_size, data->lwp, |
229 | gdb_signal_to_host (data->stop_signal), buf); | |
a904c024 AA |
230 | else |
231 | data->note_data = (char *) elfcore_write_register_note | |
232 | (data->obfd, data->note_data, data->note_size, | |
233 | sect_name, buf, size); | |
234 | xfree (buf); | |
20a0aab3 JB |
235 | |
236 | if (data->note_data == NULL) | |
237 | data->abort_iteration = 1; | |
238 | } | |
239 | ||
240 | /* Records the thread's register state for the corefile note | |
241 | section. */ | |
242 | ||
243 | static char * | |
244 | fbsd_collect_thread_registers (const struct regcache *regcache, | |
245 | ptid_t ptid, bfd *obfd, | |
246 | char *note_data, int *note_size, | |
247 | enum gdb_signal stop_signal) | |
248 | { | |
ac7936df | 249 | struct gdbarch *gdbarch = regcache->arch (); |
20a0aab3 JB |
250 | struct fbsd_collect_regset_section_cb_data data; |
251 | ||
252 | data.regcache = regcache; | |
253 | data.obfd = obfd; | |
254 | data.note_data = note_data; | |
255 | data.note_size = note_size; | |
256 | data.stop_signal = stop_signal; | |
257 | data.abort_iteration = 0; | |
258 | data.lwp = ptid_get_lwp (ptid); | |
259 | ||
260 | gdbarch_iterate_over_regset_sections (gdbarch, | |
261 | fbsd_collect_regset_section_cb, | |
262 | &data, regcache); | |
263 | return data.note_data; | |
264 | } | |
265 | ||
266 | struct fbsd_corefile_thread_data | |
267 | { | |
268 | struct gdbarch *gdbarch; | |
269 | bfd *obfd; | |
270 | char *note_data; | |
271 | int *note_size; | |
272 | enum gdb_signal stop_signal; | |
273 | }; | |
274 | ||
275 | /* Records the thread's register state for the corefile note | |
276 | section. */ | |
277 | ||
278 | static void | |
279 | fbsd_corefile_thread (struct thread_info *info, | |
280 | struct fbsd_corefile_thread_data *args) | |
281 | { | |
20a0aab3 JB |
282 | struct regcache *regcache; |
283 | ||
284 | regcache = get_thread_arch_regcache (info->ptid, args->gdbarch); | |
285 | ||
20a0aab3 | 286 | target_fetch_registers (regcache, -1); |
20a0aab3 JB |
287 | |
288 | args->note_data = fbsd_collect_thread_registers | |
289 | (regcache, info->ptid, args->obfd, args->note_data, | |
290 | args->note_size, args->stop_signal); | |
a904c024 AA |
291 | } |
292 | ||
293 | /* Create appropriate note sections for a corefile, returning them in | |
294 | allocated memory. */ | |
295 | ||
296 | static char * | |
297 | fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) | |
298 | { | |
20a0aab3 JB |
299 | struct fbsd_corefile_thread_data thread_args; |
300 | char *note_data = NULL; | |
a904c024 | 301 | Elf_Internal_Ehdr *i_ehdrp; |
20a0aab3 | 302 | struct thread_info *curr_thr, *signalled_thr, *thr; |
a904c024 AA |
303 | |
304 | /* Put a "FreeBSD" label in the ELF header. */ | |
305 | i_ehdrp = elf_elfheader (obfd); | |
306 | i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; | |
307 | ||
308 | gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch)); | |
309 | ||
a904c024 AA |
310 | if (get_exec_file (0)) |
311 | { | |
312 | const char *fname = lbasename (get_exec_file (0)); | |
313 | char *psargs = xstrdup (fname); | |
314 | ||
315 | if (get_inferior_args ()) | |
316 | psargs = reconcat (psargs, psargs, " ", get_inferior_args (), | |
317 | (char *) NULL); | |
318 | ||
319 | note_data = elfcore_write_prpsinfo (obfd, note_data, note_size, | |
320 | fname, psargs); | |
321 | } | |
322 | ||
20a0aab3 JB |
323 | /* Thread register information. */ |
324 | TRY | |
325 | { | |
326 | update_thread_list (); | |
327 | } | |
328 | CATCH (e, RETURN_MASK_ERROR) | |
329 | { | |
330 | exception_print (gdb_stderr, e); | |
331 | } | |
332 | END_CATCH | |
333 | ||
334 | /* Like the kernel, prefer dumping the signalled thread first. | |
335 | "First thread" is what tools use to infer the signalled thread. | |
336 | In case there's more than one signalled thread, prefer the | |
337 | current thread, if it is signalled. */ | |
338 | curr_thr = inferior_thread (); | |
339 | if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0) | |
340 | signalled_thr = curr_thr; | |
341 | else | |
342 | { | |
343 | signalled_thr = iterate_over_threads (find_signalled_thread, NULL); | |
344 | if (signalled_thr == NULL) | |
345 | signalled_thr = curr_thr; | |
346 | } | |
347 | ||
348 | thread_args.gdbarch = gdbarch; | |
349 | thread_args.obfd = obfd; | |
350 | thread_args.note_data = note_data; | |
351 | thread_args.note_size = note_size; | |
352 | thread_args.stop_signal = signalled_thr->suspend.stop_signal; | |
353 | ||
354 | fbsd_corefile_thread (signalled_thr, &thread_args); | |
355 | ALL_NON_EXITED_THREADS (thr) | |
356 | { | |
357 | if (thr == signalled_thr) | |
358 | continue; | |
359 | if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid)) | |
360 | continue; | |
361 | ||
362 | fbsd_corefile_thread (thr, &thread_args); | |
363 | } | |
364 | ||
365 | note_data = thread_args.note_data; | |
366 | ||
a904c024 AA |
367 | return note_data; |
368 | } | |
369 | ||
82372b2f JB |
370 | /* Print descriptions of FreeBSD-specific AUXV entries to FILE. */ |
371 | ||
372 | static void | |
373 | fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, | |
374 | CORE_ADDR type, CORE_ADDR val) | |
375 | { | |
376 | const char *name; | |
377 | const char *description; | |
378 | enum auxv_format format; | |
379 | ||
380 | switch (type) | |
381 | { | |
382 | #define _TAGNAME(tag) #tag | |
383 | #define TAGNAME(tag) _TAGNAME(AT_##tag) | |
384 | #define TAG(tag, text, kind) \ | |
385 | case AT_FREEBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break | |
386 | TAG (EXECPATH, _("Executable path"), AUXV_FORMAT_STR); | |
387 | TAG (CANARY, _("Canary for SSP"), AUXV_FORMAT_HEX); | |
388 | TAG (CANARYLEN, ("Length of the SSP canary"), AUXV_FORMAT_DEC); | |
389 | TAG (OSRELDATE, _("OSRELDATE"), AUXV_FORMAT_DEC); | |
390 | TAG (NCPUS, _("Number of CPUs"), AUXV_FORMAT_DEC); | |
391 | TAG (PAGESIZES, _("Pagesizes"), AUXV_FORMAT_HEX); | |
392 | TAG (PAGESIZESLEN, _("Number of pagesizes"), AUXV_FORMAT_DEC); | |
393 | TAG (TIMEKEEP, _("Pointer to timehands"), AUXV_FORMAT_HEX); | |
394 | TAG (STACKPROT, _("Initial stack protection"), AUXV_FORMAT_HEX); | |
12c4bd7f JB |
395 | TAG (EHDRFLAGS, _("ELF header e_flags"), AUXV_FORMAT_HEX); |
396 | TAG (HWCAP, _("Machine-dependent CPU capability hints"), AUXV_FORMAT_HEX); | |
82372b2f JB |
397 | default: |
398 | default_print_auxv_entry (gdbarch, file, type, val); | |
399 | return; | |
400 | } | |
401 | ||
402 | fprint_auxv_entry (file, name, description, format, type, val); | |
403 | } | |
404 | ||
762c974a JB |
405 | /* Implement the "get_siginfo_type" gdbarch method. */ |
406 | ||
407 | static struct type * | |
408 | fbsd_get_siginfo_type (struct gdbarch *gdbarch) | |
409 | { | |
410 | struct fbsd_gdbarch_data *fbsd_gdbarch_data; | |
411 | struct type *int_type, *int32_type, *uint32_type, *long_type, *void_ptr_type; | |
412 | struct type *uid_type, *pid_type; | |
413 | struct type *sigval_type, *reason_type; | |
414 | struct type *siginfo_type; | |
415 | struct type *type; | |
416 | ||
417 | fbsd_gdbarch_data = get_fbsd_gdbarch_data (gdbarch); | |
418 | if (fbsd_gdbarch_data->siginfo_type != NULL) | |
419 | return fbsd_gdbarch_data->siginfo_type; | |
420 | ||
421 | int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), | |
422 | 0, "int"); | |
423 | int32_type = arch_integer_type (gdbarch, 32, 0, "int32_t"); | |
424 | uint32_type = arch_integer_type (gdbarch, 32, 1, "uint32_t"); | |
425 | long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), | |
426 | 0, "long"); | |
427 | void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); | |
428 | ||
429 | /* union sigval */ | |
430 | sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); | |
431 | TYPE_NAME (sigval_type) = xstrdup ("sigval"); | |
432 | append_composite_type_field (sigval_type, "sival_int", int_type); | |
433 | append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type); | |
434 | ||
435 | /* __pid_t */ | |
436 | pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, | |
77b7c781 | 437 | TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "__pid_t"); |
762c974a JB |
438 | TYPE_TARGET_TYPE (pid_type) = int32_type; |
439 | TYPE_TARGET_STUB (pid_type) = 1; | |
440 | ||
441 | /* __uid_t */ | |
442 | uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, | |
77b7c781 UW |
443 | TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT, |
444 | "__uid_t"); | |
762c974a JB |
445 | TYPE_TARGET_TYPE (uid_type) = uint32_type; |
446 | TYPE_TARGET_STUB (uid_type) = 1; | |
447 | ||
448 | /* _reason */ | |
449 | reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); | |
450 | ||
451 | /* _fault */ | |
452 | type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
453 | append_composite_type_field (type, "si_trapno", int_type); | |
454 | append_composite_type_field (reason_type, "_fault", type); | |
455 | ||
456 | /* _timer */ | |
457 | type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
458 | append_composite_type_field (type, "si_timerid", int_type); | |
459 | append_composite_type_field (type, "si_overrun", int_type); | |
460 | append_composite_type_field (reason_type, "_timer", type); | |
461 | ||
462 | /* _mesgq */ | |
463 | type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
464 | append_composite_type_field (type, "si_mqd", int_type); | |
465 | append_composite_type_field (reason_type, "_mesgq", type); | |
466 | ||
467 | /* _poll */ | |
468 | type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
469 | append_composite_type_field (type, "si_band", long_type); | |
470 | append_composite_type_field (reason_type, "_poll", type); | |
471 | ||
472 | /* __spare__ */ | |
473 | type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
474 | append_composite_type_field (type, "__spare1__", long_type); | |
475 | append_composite_type_field (type, "__spare2__", | |
476 | init_vector_type (int_type, 7)); | |
477 | append_composite_type_field (reason_type, "__spare__", type); | |
478 | ||
479 | /* struct siginfo */ | |
480 | siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); | |
481 | TYPE_NAME (siginfo_type) = xstrdup ("siginfo"); | |
482 | append_composite_type_field (siginfo_type, "si_signo", int_type); | |
483 | append_composite_type_field (siginfo_type, "si_errno", int_type); | |
484 | append_composite_type_field (siginfo_type, "si_code", int_type); | |
485 | append_composite_type_field (siginfo_type, "si_pid", pid_type); | |
486 | append_composite_type_field (siginfo_type, "si_uid", uid_type); | |
487 | append_composite_type_field (siginfo_type, "si_status", int_type); | |
488 | append_composite_type_field (siginfo_type, "si_addr", void_ptr_type); | |
489 | append_composite_type_field (siginfo_type, "si_value", sigval_type); | |
490 | append_composite_type_field (siginfo_type, "_reason", reason_type); | |
491 | ||
492 | fbsd_gdbarch_data->siginfo_type = siginfo_type; | |
493 | ||
494 | return siginfo_type; | |
495 | } | |
496 | ||
e6cdd38e JB |
497 | /* Implement the "get_syscall_number" gdbarch method. */ |
498 | ||
499 | static LONGEST | |
500 | fbsd_get_syscall_number (struct gdbarch *gdbarch, | |
501 | ptid_t ptid) | |
502 | { | |
503 | ||
504 | /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD | |
505 | native targets fetch the system call number from the | |
506 | 'pl_syscall_code' member of struct ptrace_lwpinfo in fbsd_wait. | |
507 | However, system call catching requires this function to be | |
508 | set. */ | |
509 | ||
510 | internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called")); | |
511 | } | |
512 | ||
1736a7bd | 513 | /* To be called from GDB_OSABI_FREEBSD handlers. */ |
a904c024 AA |
514 | |
515 | void | |
516 | fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
517 | { | |
79117428 JB |
518 | set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str); |
519 | set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name); | |
4b654465 | 520 | set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo); |
a904c024 | 521 | set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); |
82372b2f | 522 | set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry); |
762c974a | 523 | set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type); |
e6cdd38e JB |
524 | |
525 | /* `catch syscall' */ | |
526 | set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml"); | |
527 | set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number); | |
a904c024 | 528 | } |
762c974a | 529 | |
762c974a JB |
530 | void |
531 | _initialize_fbsd_tdep (void) | |
532 | { | |
533 | fbsd_gdbarch_data_handle = | |
534 | gdbarch_data_register_post_init (init_fbsd_gdbarch_data); | |
535 | } |