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/>. */
26 #include "gdbthread.h"
29 #include "fbsd-tdep.h"
32 /* This is how we want PTIDs from core files to be printed. */
35 fbsd_core_pid_to_str (struct gdbarch
*gdbarch
, ptid_t ptid
)
39 if (ptid_get_lwp (ptid
) != 0)
41 xsnprintf (buf
, sizeof buf
, "LWP %ld", ptid_get_lwp (ptid
));
45 return normal_pid_to_str (ptid
);
48 /* Extract the name assigned to a thread from a core. Returns the
49 string in a static buffer. */
52 fbsd_core_thread_name (struct gdbarch
*gdbarch
, struct thread_info
*thr
)
55 struct bfd_section
*section
;
59 if (ptid_get_lwp (thr
->ptid
) != 0)
61 /* FreeBSD includes a NT_FREEBSD_THRMISC note for each thread
62 whose contents are defined by a "struct thrmisc" declared in
63 <sys/procfs.h> on FreeBSD. The per-thread name is stored as
64 a null-terminated string as the first member of the
65 structure. Rather than define the full structure here, just
66 extract the null-terminated name from the start of the
68 xsnprintf (sectionstr
, sizeof sectionstr
, ".thrmisc/%ld",
69 ptid_get_lwp (thr
->ptid
));
70 section
= bfd_get_section_by_name (core_bfd
, sectionstr
);
71 if (section
!= NULL
&& bfd_section_size (core_bfd
, section
) > 0)
73 /* Truncate the name if it is longer than "buf". */
74 size
= bfd_section_size (core_bfd
, section
);
75 if (size
> sizeof buf
- 1)
76 size
= sizeof buf
- 1;
77 if (bfd_get_section_contents (core_bfd
, section
, buf
, (file_ptr
) 0,
83 /* Note that each thread will report the process command
84 as its thread name instead of an empty name if a name
85 has not been set explicitly. Return a NULL name in
87 if (strcmp (buf
, elf_tdata (core_bfd
)->core
->program
) != 0)
97 find_signalled_thread (struct thread_info
*info
, void *data
)
99 if (info
->suspend
.stop_signal
!= GDB_SIGNAL_0
100 && ptid_get_pid (info
->ptid
) == ptid_get_pid (inferior_ptid
))
106 /* Structure for passing information from
107 fbsd_collect_thread_registers via an iterator to
108 fbsd_collect_regset_section_cb. */
110 struct fbsd_collect_regset_section_cb_data
112 const struct regcache
*regcache
;
117 enum gdb_signal stop_signal
;
122 fbsd_collect_regset_section_cb (const char *sect_name
, int size
,
123 const struct regset
*regset
,
124 const char *human_name
, void *cb_data
)
127 struct fbsd_collect_regset_section_cb_data
*data
128 = (struct fbsd_collect_regset_section_cb_data
*) cb_data
;
130 if (data
->abort_iteration
)
133 gdb_assert (regset
->collect_regset
);
135 buf
= (char *) xmalloc (size
);
136 regset
->collect_regset (regset
, data
->regcache
, -1, buf
, size
);
138 /* PRSTATUS still needs to be treated specially. */
139 if (strcmp (sect_name
, ".reg") == 0)
140 data
->note_data
= (char *) elfcore_write_prstatus
141 (data
->obfd
, data
->note_data
, data
->note_size
, data
->lwp
,
142 gdb_signal_to_host (data
->stop_signal
), buf
);
144 data
->note_data
= (char *) elfcore_write_register_note
145 (data
->obfd
, data
->note_data
, data
->note_size
,
146 sect_name
, buf
, size
);
149 if (data
->note_data
== NULL
)
150 data
->abort_iteration
= 1;
153 /* Records the thread's register state for the corefile note
157 fbsd_collect_thread_registers (const struct regcache
*regcache
,
158 ptid_t ptid
, bfd
*obfd
,
159 char *note_data
, int *note_size
,
160 enum gdb_signal stop_signal
)
162 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
163 struct fbsd_collect_regset_section_cb_data data
;
165 data
.regcache
= regcache
;
167 data
.note_data
= note_data
;
168 data
.note_size
= note_size
;
169 data
.stop_signal
= stop_signal
;
170 data
.abort_iteration
= 0;
171 data
.lwp
= ptid_get_lwp (ptid
);
173 gdbarch_iterate_over_regset_sections (gdbarch
,
174 fbsd_collect_regset_section_cb
,
176 return data
.note_data
;
179 struct fbsd_corefile_thread_data
181 struct gdbarch
*gdbarch
;
185 enum gdb_signal stop_signal
;
188 /* Records the thread's register state for the corefile note
192 fbsd_corefile_thread (struct thread_info
*info
,
193 struct fbsd_corefile_thread_data
*args
)
195 struct cleanup
*old_chain
;
196 struct regcache
*regcache
;
198 regcache
= get_thread_arch_regcache (info
->ptid
, args
->gdbarch
);
200 old_chain
= save_inferior_ptid ();
201 inferior_ptid
= info
->ptid
;
202 target_fetch_registers (regcache
, -1);
203 do_cleanups (old_chain
);
205 args
->note_data
= fbsd_collect_thread_registers
206 (regcache
, info
->ptid
, args
->obfd
, args
->note_data
,
207 args
->note_size
, args
->stop_signal
);
210 /* Create appropriate note sections for a corefile, returning them in
214 fbsd_make_corefile_notes (struct gdbarch
*gdbarch
, bfd
*obfd
, int *note_size
)
216 struct fbsd_corefile_thread_data thread_args
;
217 char *note_data
= NULL
;
218 Elf_Internal_Ehdr
*i_ehdrp
;
219 struct thread_info
*curr_thr
, *signalled_thr
, *thr
;
221 /* Put a "FreeBSD" label in the ELF header. */
222 i_ehdrp
= elf_elfheader (obfd
);
223 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
225 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch
));
227 if (get_exec_file (0))
229 const char *fname
= lbasename (get_exec_file (0));
230 char *psargs
= xstrdup (fname
);
232 if (get_inferior_args ())
233 psargs
= reconcat (psargs
, psargs
, " ", get_inferior_args (),
236 note_data
= elfcore_write_prpsinfo (obfd
, note_data
, note_size
,
240 /* Thread register information. */
243 update_thread_list ();
245 CATCH (e
, RETURN_MASK_ERROR
)
247 exception_print (gdb_stderr
, e
);
251 /* Like the kernel, prefer dumping the signalled thread first.
252 "First thread" is what tools use to infer the signalled thread.
253 In case there's more than one signalled thread, prefer the
254 current thread, if it is signalled. */
255 curr_thr
= inferior_thread ();
256 if (curr_thr
->suspend
.stop_signal
!= GDB_SIGNAL_0
)
257 signalled_thr
= curr_thr
;
260 signalled_thr
= iterate_over_threads (find_signalled_thread
, NULL
);
261 if (signalled_thr
== NULL
)
262 signalled_thr
= curr_thr
;
265 thread_args
.gdbarch
= gdbarch
;
266 thread_args
.obfd
= obfd
;
267 thread_args
.note_data
= note_data
;
268 thread_args
.note_size
= note_size
;
269 thread_args
.stop_signal
= signalled_thr
->suspend
.stop_signal
;
271 fbsd_corefile_thread (signalled_thr
, &thread_args
);
272 ALL_NON_EXITED_THREADS (thr
)
274 if (thr
== signalled_thr
)
276 if (ptid_get_pid (thr
->ptid
) != ptid_get_pid (inferior_ptid
))
279 fbsd_corefile_thread (thr
, &thread_args
);
282 note_data
= thread_args
.note_data
;
287 /* Print descriptions of FreeBSD-specific AUXV entries to FILE. */
290 fbsd_print_auxv_entry (struct gdbarch
*gdbarch
, struct ui_file
*file
,
291 CORE_ADDR type
, CORE_ADDR val
)
294 const char *description
;
295 enum auxv_format format
;
299 #define _TAGNAME(tag) #tag
300 #define TAGNAME(tag) _TAGNAME(AT_##tag)
301 #define TAG(tag, text, kind) \
302 case AT_FREEBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break
303 TAG (EXECPATH
, _("Executable path"), AUXV_FORMAT_STR
);
304 TAG (CANARY
, _("Canary for SSP"), AUXV_FORMAT_HEX
);
305 TAG (CANARYLEN
, ("Length of the SSP canary"), AUXV_FORMAT_DEC
);
306 TAG (OSRELDATE
, _("OSRELDATE"), AUXV_FORMAT_DEC
);
307 TAG (NCPUS
, _("Number of CPUs"), AUXV_FORMAT_DEC
);
308 TAG (PAGESIZES
, _("Pagesizes"), AUXV_FORMAT_HEX
);
309 TAG (PAGESIZESLEN
, _("Number of pagesizes"), AUXV_FORMAT_DEC
);
310 TAG (TIMEKEEP
, _("Pointer to timehands"), AUXV_FORMAT_HEX
);
311 TAG (STACKPROT
, _("Initial stack protection"), AUXV_FORMAT_HEX
);
313 default_print_auxv_entry (gdbarch
, file
, type
, val
);
317 fprint_auxv_entry (file
, name
, description
, format
, type
, val
);
320 /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
323 fbsd_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
325 set_gdbarch_core_pid_to_str (gdbarch
, fbsd_core_pid_to_str
);
326 set_gdbarch_core_thread_name (gdbarch
, fbsd_core_thread_name
);
327 set_gdbarch_make_corefile_notes (gdbarch
, fbsd_make_corefile_notes
);
328 set_gdbarch_print_auxv_entry (gdbarch
, fbsd_print_auxv_entry
);