1 /* Target-dependent code for FreeBSD, architecture-independent.
3 Copyright (C) 2002-2016 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/>. */
25 #include "gdbthread.h"
28 #include "fbsd-tdep.h"
31 /* This is how we want PTIDs from core files to be printed. */
34 fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
38 if (ptid_get_lwp (ptid) != 0)
40 xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
44 return normal_pid_to_str (ptid);
47 /* Extract the name assigned to a thread from a core. Returns the
48 string in a static buffer. */
51 fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
54 struct bfd_section *section;
58 if (ptid_get_lwp (thr->ptid) != 0)
60 /* FreeBSD includes a NT_FREEBSD_THRMISC note for each thread
61 whose contents are defined by a "struct thrmisc" declared in
62 <sys/procfs.h> on FreeBSD. The per-thread name is stored as
63 a null-terminated string as the first member of the
64 structure. Rather than define the full structure here, just
65 extract the null-terminated name from the start of the
67 xsnprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld",
68 ptid_get_lwp (thr->ptid));
69 section = bfd_get_section_by_name (core_bfd, sectionstr);
70 if (section != NULL && bfd_section_size (core_bfd, section) > 0)
72 /* Truncate the name if it is longer than "buf". */
73 size = bfd_section_size (core_bfd, section);
74 if (size > sizeof buf - 1)
75 size = sizeof buf - 1;
76 if (bfd_get_section_contents (core_bfd, section, buf, (file_ptr) 0,
82 /* Note that each thread will report the process command
83 as its thread name instead of an empty name if a name
84 has not been set explicitly. Return a NULL name in
86 if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0)
96 find_signalled_thread (struct thread_info *info, void *data)
98 if (info->suspend.stop_signal != GDB_SIGNAL_0
99 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
105 /* Structure for passing information from
106 fbsd_collect_thread_registers via an iterator to
107 fbsd_collect_regset_section_cb. */
109 struct fbsd_collect_regset_section_cb_data
111 const struct regcache *regcache;
116 enum gdb_signal stop_signal;
121 fbsd_collect_regset_section_cb (const char *sect_name, int size,
122 const struct regset *regset,
123 const char *human_name, void *cb_data)
126 struct fbsd_collect_regset_section_cb_data *data
127 = (struct fbsd_collect_regset_section_cb_data *) cb_data;
129 if (data->abort_iteration)
132 gdb_assert (regset->collect_regset);
134 buf = (char *) xmalloc (size);
135 regset->collect_regset (regset, data->regcache, -1, buf, size);
137 /* PRSTATUS still needs to be treated specially. */
138 if (strcmp (sect_name, ".reg") == 0)
139 data->note_data = (char *) elfcore_write_prstatus
140 (data->obfd, data->note_data, data->note_size, data->lwp,
141 gdb_signal_to_host (data->stop_signal), buf);
143 data->note_data = (char *) elfcore_write_register_note
144 (data->obfd, data->note_data, data->note_size,
145 sect_name, buf, size);
148 if (data->note_data == NULL)
149 data->abort_iteration = 1;
152 /* Records the thread's register state for the corefile note
156 fbsd_collect_thread_registers (const struct regcache *regcache,
157 ptid_t ptid, bfd *obfd,
158 char *note_data, int *note_size,
159 enum gdb_signal stop_signal)
161 struct gdbarch *gdbarch = get_regcache_arch (regcache);
162 struct fbsd_collect_regset_section_cb_data data;
164 data.regcache = regcache;
166 data.note_data = note_data;
167 data.note_size = note_size;
168 data.stop_signal = stop_signal;
169 data.abort_iteration = 0;
170 data.lwp = ptid_get_lwp (ptid);
172 gdbarch_iterate_over_regset_sections (gdbarch,
173 fbsd_collect_regset_section_cb,
175 return data.note_data;
178 struct fbsd_corefile_thread_data
180 struct gdbarch *gdbarch;
184 enum gdb_signal stop_signal;
187 /* Records the thread's register state for the corefile note
191 fbsd_corefile_thread (struct thread_info *info,
192 struct fbsd_corefile_thread_data *args)
194 struct cleanup *old_chain;
195 struct regcache *regcache;
197 regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
199 old_chain = save_inferior_ptid ();
200 inferior_ptid = info->ptid;
201 target_fetch_registers (regcache, -1);
202 do_cleanups (old_chain);
204 args->note_data = fbsd_collect_thread_registers
205 (regcache, info->ptid, args->obfd, args->note_data,
206 args->note_size, args->stop_signal);
209 /* Create appropriate note sections for a corefile, returning them in
213 fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
215 struct fbsd_corefile_thread_data thread_args;
216 char *note_data = NULL;
217 Elf_Internal_Ehdr *i_ehdrp;
218 struct thread_info *curr_thr, *signalled_thr, *thr;
220 /* Put a "FreeBSD" label in the ELF header. */
221 i_ehdrp = elf_elfheader (obfd);
222 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
224 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
226 if (get_exec_file (0))
228 const char *fname = lbasename (get_exec_file (0));
229 char *psargs = xstrdup (fname);
231 if (get_inferior_args ())
232 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
235 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
239 /* Thread register information. */
242 update_thread_list ();
244 CATCH (e, RETURN_MASK_ERROR)
246 exception_print (gdb_stderr, e);
250 /* Like the kernel, prefer dumping the signalled thread first.
251 "First thread" is what tools use to infer the signalled thread.
252 In case there's more than one signalled thread, prefer the
253 current thread, if it is signalled. */
254 curr_thr = inferior_thread ();
255 if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
256 signalled_thr = curr_thr;
259 signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
260 if (signalled_thr == NULL)
261 signalled_thr = curr_thr;
264 thread_args.gdbarch = gdbarch;
265 thread_args.obfd = obfd;
266 thread_args.note_data = note_data;
267 thread_args.note_size = note_size;
268 thread_args.stop_signal = signalled_thr->suspend.stop_signal;
270 fbsd_corefile_thread (signalled_thr, &thread_args);
271 ALL_NON_EXITED_THREADS (thr)
273 if (thr == signalled_thr)
275 if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
278 fbsd_corefile_thread (thr, &thread_args);
281 note_data = thread_args.note_data;
286 /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
289 fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
291 set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
292 set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
293 set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);