1 /* Target-dependent code for FreeBSD, architecture-independent.
3 Copyright (C) 2002-2017 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
26 #include "gdbthread.h"
27 #include "xml-syscall.h"
30 #include "fbsd-tdep.h"
33 /* This is how we want PTIDs from core files to be printed. */
36 fbsd_core_pid_to_str (struct gdbarch
*gdbarch
, ptid_t ptid
)
40 if (ptid_get_lwp (ptid
) != 0)
42 xsnprintf (buf
, sizeof buf
, "LWP %ld", ptid_get_lwp (ptid
));
46 return normal_pid_to_str (ptid
);
49 /* Extract the name assigned to a thread from a core. Returns the
50 string in a static buffer. */
53 fbsd_core_thread_name (struct gdbarch
*gdbarch
, struct thread_info
*thr
)
56 struct bfd_section
*section
;
60 if (ptid_get_lwp (thr
->ptid
) != 0)
62 /* FreeBSD includes a NT_FREEBSD_THRMISC note for each thread
63 whose contents are defined by a "struct thrmisc" declared in
64 <sys/procfs.h> on FreeBSD. The per-thread name is stored as
65 a null-terminated string as the first member of the
66 structure. Rather than define the full structure here, just
67 extract the null-terminated name from the start of the
69 xsnprintf (sectionstr
, sizeof sectionstr
, ".thrmisc/%ld",
70 ptid_get_lwp (thr
->ptid
));
71 section
= bfd_get_section_by_name (core_bfd
, sectionstr
);
72 if (section
!= NULL
&& bfd_section_size (core_bfd
, section
) > 0)
74 /* Truncate the name if it is longer than "buf". */
75 size
= bfd_section_size (core_bfd
, section
);
76 if (size
> sizeof buf
- 1)
77 size
= sizeof buf
- 1;
78 if (bfd_get_section_contents (core_bfd
, section
, buf
, (file_ptr
) 0,
84 /* Note that each thread will report the process command
85 as its thread name instead of an empty name if a name
86 has not been set explicitly. Return a NULL name in
88 if (strcmp (buf
, elf_tdata (core_bfd
)->core
->program
) != 0)
98 find_signalled_thread (struct thread_info
*info
, void *data
)
100 if (info
->suspend
.stop_signal
!= GDB_SIGNAL_0
101 && ptid_get_pid (info
->ptid
) == ptid_get_pid (inferior_ptid
))
107 /* Structure for passing information from
108 fbsd_collect_thread_registers via an iterator to
109 fbsd_collect_regset_section_cb. */
111 struct fbsd_collect_regset_section_cb_data
113 const struct regcache
*regcache
;
118 enum gdb_signal stop_signal
;
123 fbsd_collect_regset_section_cb (const char *sect_name
, int size
,
124 const struct regset
*regset
,
125 const char *human_name
, void *cb_data
)
128 struct fbsd_collect_regset_section_cb_data
*data
129 = (struct fbsd_collect_regset_section_cb_data
*) cb_data
;
131 if (data
->abort_iteration
)
134 gdb_assert (regset
->collect_regset
);
136 buf
= (char *) xmalloc (size
);
137 regset
->collect_regset (regset
, data
->regcache
, -1, buf
, size
);
139 /* PRSTATUS still needs to be treated specially. */
140 if (strcmp (sect_name
, ".reg") == 0)
141 data
->note_data
= (char *) elfcore_write_prstatus
142 (data
->obfd
, data
->note_data
, data
->note_size
, data
->lwp
,
143 gdb_signal_to_host (data
->stop_signal
), buf
);
145 data
->note_data
= (char *) elfcore_write_register_note
146 (data
->obfd
, data
->note_data
, data
->note_size
,
147 sect_name
, buf
, size
);
150 if (data
->note_data
== NULL
)
151 data
->abort_iteration
= 1;
154 /* Records the thread's register state for the corefile note
158 fbsd_collect_thread_registers (const struct regcache
*regcache
,
159 ptid_t ptid
, bfd
*obfd
,
160 char *note_data
, int *note_size
,
161 enum gdb_signal stop_signal
)
163 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
164 struct fbsd_collect_regset_section_cb_data data
;
166 data
.regcache
= regcache
;
168 data
.note_data
= note_data
;
169 data
.note_size
= note_size
;
170 data
.stop_signal
= stop_signal
;
171 data
.abort_iteration
= 0;
172 data
.lwp
= ptid_get_lwp (ptid
);
174 gdbarch_iterate_over_regset_sections (gdbarch
,
175 fbsd_collect_regset_section_cb
,
177 return data
.note_data
;
180 struct fbsd_corefile_thread_data
182 struct gdbarch
*gdbarch
;
186 enum gdb_signal stop_signal
;
189 /* Records the thread's register state for the corefile note
193 fbsd_corefile_thread (struct thread_info
*info
,
194 struct fbsd_corefile_thread_data
*args
)
196 struct regcache
*regcache
;
198 regcache
= get_thread_arch_regcache (info
->ptid
, args
->gdbarch
);
200 target_fetch_registers (regcache
, -1);
202 args
->note_data
= fbsd_collect_thread_registers
203 (regcache
, info
->ptid
, args
->obfd
, args
->note_data
,
204 args
->note_size
, args
->stop_signal
);
207 /* Create appropriate note sections for a corefile, returning them in
211 fbsd_make_corefile_notes (struct gdbarch
*gdbarch
, bfd
*obfd
, int *note_size
)
213 struct fbsd_corefile_thread_data thread_args
;
214 char *note_data
= NULL
;
215 Elf_Internal_Ehdr
*i_ehdrp
;
216 struct thread_info
*curr_thr
, *signalled_thr
, *thr
;
218 /* Put a "FreeBSD" label in the ELF header. */
219 i_ehdrp
= elf_elfheader (obfd
);
220 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
222 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch
));
224 if (get_exec_file (0))
226 const char *fname
= lbasename (get_exec_file (0));
227 char *psargs
= xstrdup (fname
);
229 if (get_inferior_args ())
230 psargs
= reconcat (psargs
, psargs
, " ", get_inferior_args (),
233 note_data
= elfcore_write_prpsinfo (obfd
, note_data
, note_size
,
237 /* Thread register information. */
240 update_thread_list ();
242 CATCH (e
, RETURN_MASK_ERROR
)
244 exception_print (gdb_stderr
, e
);
248 /* Like the kernel, prefer dumping the signalled thread first.
249 "First thread" is what tools use to infer the signalled thread.
250 In case there's more than one signalled thread, prefer the
251 current thread, if it is signalled. */
252 curr_thr
= inferior_thread ();
253 if (curr_thr
->suspend
.stop_signal
!= GDB_SIGNAL_0
)
254 signalled_thr
= curr_thr
;
257 signalled_thr
= iterate_over_threads (find_signalled_thread
, NULL
);
258 if (signalled_thr
== NULL
)
259 signalled_thr
= curr_thr
;
262 thread_args
.gdbarch
= gdbarch
;
263 thread_args
.obfd
= obfd
;
264 thread_args
.note_data
= note_data
;
265 thread_args
.note_size
= note_size
;
266 thread_args
.stop_signal
= signalled_thr
->suspend
.stop_signal
;
268 fbsd_corefile_thread (signalled_thr
, &thread_args
);
269 ALL_NON_EXITED_THREADS (thr
)
271 if (thr
== signalled_thr
)
273 if (ptid_get_pid (thr
->ptid
) != ptid_get_pid (inferior_ptid
))
276 fbsd_corefile_thread (thr
, &thread_args
);
279 note_data
= thread_args
.note_data
;
284 /* Print descriptions of FreeBSD-specific AUXV entries to FILE. */
287 fbsd_print_auxv_entry (struct gdbarch
*gdbarch
, struct ui_file
*file
,
288 CORE_ADDR type
, CORE_ADDR val
)
291 const char *description
;
292 enum auxv_format format
;
296 #define _TAGNAME(tag) #tag
297 #define TAGNAME(tag) _TAGNAME(AT_##tag)
298 #define TAG(tag, text, kind) \
299 case AT_FREEBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break
300 TAG (EXECPATH
, _("Executable path"), AUXV_FORMAT_STR
);
301 TAG (CANARY
, _("Canary for SSP"), AUXV_FORMAT_HEX
);
302 TAG (CANARYLEN
, ("Length of the SSP canary"), AUXV_FORMAT_DEC
);
303 TAG (OSRELDATE
, _("OSRELDATE"), AUXV_FORMAT_DEC
);
304 TAG (NCPUS
, _("Number of CPUs"), AUXV_FORMAT_DEC
);
305 TAG (PAGESIZES
, _("Pagesizes"), AUXV_FORMAT_HEX
);
306 TAG (PAGESIZESLEN
, _("Number of pagesizes"), AUXV_FORMAT_DEC
);
307 TAG (TIMEKEEP
, _("Pointer to timehands"), AUXV_FORMAT_HEX
);
308 TAG (STACKPROT
, _("Initial stack protection"), AUXV_FORMAT_HEX
);
310 default_print_auxv_entry (gdbarch
, file
, type
, val
);
314 fprint_auxv_entry (file
, name
, description
, format
, type
, val
);
317 /* Implement the "get_syscall_number" gdbarch method. */
320 fbsd_get_syscall_number (struct gdbarch
*gdbarch
,
324 /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD
325 native targets fetch the system call number from the
326 'pl_syscall_code' member of struct ptrace_lwpinfo in fbsd_wait.
327 However, system call catching requires this function to be
330 internal_error (__FILE__
, __LINE__
, _("fbsd_get_sycall_number called"));
333 /* To be called from GDB_OSABI_FREEBSD handlers. */
336 fbsd_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
338 set_gdbarch_core_pid_to_str (gdbarch
, fbsd_core_pid_to_str
);
339 set_gdbarch_core_thread_name (gdbarch
, fbsd_core_thread_name
);
340 set_gdbarch_make_corefile_notes (gdbarch
, fbsd_make_corefile_notes
);
341 set_gdbarch_print_auxv_entry (gdbarch
, fbsd_print_auxv_entry
);
343 /* `catch syscall' */
344 set_xml_syscall_file_name (gdbarch
, "syscalls/freebsd.xml");
345 set_gdbarch_get_syscall_number (gdbarch
, fbsd_get_syscall_number
);