]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/fbsd-tdep.c
Add ChangeLog entries
[thirdparty/binutils-gdb.git] / gdb / fbsd-tdep.c
CommitLineData
a904c024
AA
1/* Target-dependent code for FreeBSD, architecture-independent.
2
618f726f 3 Copyright (C) 2002-2016 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
79117428
JB
33/* This is how we want PTIDs from core files to be printed. */
34
35static char *
36fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
37{
38 static char buf[80];
39
40 if (ptid_get_lwp (ptid) != 0)
41 {
42 xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
43 return buf;
44 }
45
46 return normal_pid_to_str (ptid);
47}
48
49/* Extract the name assigned to a thread from a core. Returns the
50 string in a static buffer. */
51
52static const char *
53fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
54{
55 static char buf[80];
56 struct bfd_section *section;
57 bfd_size_type size;
58 char sectionstr[32];
59
60 if (ptid_get_lwp (thr->ptid) != 0)
61 {
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
68 note. */
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)
73 {
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,
79 size)
80 && buf[0] != '\0')
81 {
82 buf[size] = '\0';
83
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
87 that case. */
88 if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0)
89 return buf;
90 }
91 }
92 }
93
94 return NULL;
95}
96
a904c024
AA
97static int
98find_signalled_thread (struct thread_info *info, void *data)
99{
100 if (info->suspend.stop_signal != GDB_SIGNAL_0
101 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
102 return 1;
103
104 return 0;
105}
106
20a0aab3
JB
107/* Structure for passing information from
108 fbsd_collect_thread_registers via an iterator to
109 fbsd_collect_regset_section_cb. */
a904c024
AA
110
111struct fbsd_collect_regset_section_cb_data
112{
113 const struct regcache *regcache;
114 bfd *obfd;
115 char *note_data;
116 int *note_size;
20a0aab3
JB
117 unsigned long lwp;
118 enum gdb_signal stop_signal;
119 int abort_iteration;
a904c024
AA
120};
121
122static void
123fbsd_collect_regset_section_cb (const char *sect_name, int size,
124 const struct regset *regset,
125 const char *human_name, void *cb_data)
126{
127 char *buf;
7567e115
SM
128 struct fbsd_collect_regset_section_cb_data *data
129 = (struct fbsd_collect_regset_section_cb_data *) cb_data;
a904c024 130
20a0aab3
JB
131 if (data->abort_iteration)
132 return;
133
a904c024
AA
134 gdb_assert (regset->collect_regset);
135
224c3ddb 136 buf = (char *) xmalloc (size);
a904c024
AA
137 regset->collect_regset (regset, data->regcache, -1, buf, size);
138
139 /* PRSTATUS still needs to be treated specially. */
140 if (strcmp (sect_name, ".reg") == 0)
141 data->note_data = (char *) elfcore_write_prstatus
20a0aab3
JB
142 (data->obfd, data->note_data, data->note_size, data->lwp,
143 gdb_signal_to_host (data->stop_signal), buf);
a904c024
AA
144 else
145 data->note_data = (char *) elfcore_write_register_note
146 (data->obfd, data->note_data, data->note_size,
147 sect_name, buf, size);
148 xfree (buf);
20a0aab3
JB
149
150 if (data->note_data == NULL)
151 data->abort_iteration = 1;
152}
153
154/* Records the thread's register state for the corefile note
155 section. */
156
157static char *
158fbsd_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)
162{
163 struct gdbarch *gdbarch = get_regcache_arch (regcache);
164 struct fbsd_collect_regset_section_cb_data data;
165
166 data.regcache = regcache;
167 data.obfd = obfd;
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);
173
174 gdbarch_iterate_over_regset_sections (gdbarch,
175 fbsd_collect_regset_section_cb,
176 &data, regcache);
177 return data.note_data;
178}
179
180struct fbsd_corefile_thread_data
181{
182 struct gdbarch *gdbarch;
183 bfd *obfd;
184 char *note_data;
185 int *note_size;
186 enum gdb_signal stop_signal;
187};
188
189/* Records the thread's register state for the corefile note
190 section. */
191
192static void
193fbsd_corefile_thread (struct thread_info *info,
194 struct fbsd_corefile_thread_data *args)
195{
196 struct cleanup *old_chain;
197 struct regcache *regcache;
198
199 regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
200
201 old_chain = save_inferior_ptid ();
202 inferior_ptid = info->ptid;
203 target_fetch_registers (regcache, -1);
204 do_cleanups (old_chain);
205
206 args->note_data = fbsd_collect_thread_registers
207 (regcache, info->ptid, args->obfd, args->note_data,
208 args->note_size, args->stop_signal);
a904c024
AA
209}
210
211/* Create appropriate note sections for a corefile, returning them in
212 allocated memory. */
213
214static char *
215fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
216{
20a0aab3
JB
217 struct fbsd_corefile_thread_data thread_args;
218 char *note_data = NULL;
a904c024 219 Elf_Internal_Ehdr *i_ehdrp;
20a0aab3 220 struct thread_info *curr_thr, *signalled_thr, *thr;
a904c024
AA
221
222 /* Put a "FreeBSD" label in the ELF header. */
223 i_ehdrp = elf_elfheader (obfd);
224 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
225
226 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
227
a904c024
AA
228 if (get_exec_file (0))
229 {
230 const char *fname = lbasename (get_exec_file (0));
231 char *psargs = xstrdup (fname);
232
233 if (get_inferior_args ())
234 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
235 (char *) NULL);
236
237 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
238 fname, psargs);
239 }
240
20a0aab3
JB
241 /* Thread register information. */
242 TRY
243 {
244 update_thread_list ();
245 }
246 CATCH (e, RETURN_MASK_ERROR)
247 {
248 exception_print (gdb_stderr, e);
249 }
250 END_CATCH
251
252 /* Like the kernel, prefer dumping the signalled thread first.
253 "First thread" is what tools use to infer the signalled thread.
254 In case there's more than one signalled thread, prefer the
255 current thread, if it is signalled. */
256 curr_thr = inferior_thread ();
257 if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
258 signalled_thr = curr_thr;
259 else
260 {
261 signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
262 if (signalled_thr == NULL)
263 signalled_thr = curr_thr;
264 }
265
266 thread_args.gdbarch = gdbarch;
267 thread_args.obfd = obfd;
268 thread_args.note_data = note_data;
269 thread_args.note_size = note_size;
270 thread_args.stop_signal = signalled_thr->suspend.stop_signal;
271
272 fbsd_corefile_thread (signalled_thr, &thread_args);
273 ALL_NON_EXITED_THREADS (thr)
274 {
275 if (thr == signalled_thr)
276 continue;
277 if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
278 continue;
279
280 fbsd_corefile_thread (thr, &thread_args);
281 }
282
283 note_data = thread_args.note_data;
284
a904c024
AA
285 return note_data;
286}
287
82372b2f
JB
288/* Print descriptions of FreeBSD-specific AUXV entries to FILE. */
289
290static void
291fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
292 CORE_ADDR type, CORE_ADDR val)
293{
294 const char *name;
295 const char *description;
296 enum auxv_format format;
297
298 switch (type)
299 {
300#define _TAGNAME(tag) #tag
301#define TAGNAME(tag) _TAGNAME(AT_##tag)
302#define TAG(tag, text, kind) \
303 case AT_FREEBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break
304 TAG (EXECPATH, _("Executable path"), AUXV_FORMAT_STR);
305 TAG (CANARY, _("Canary for SSP"), AUXV_FORMAT_HEX);
306 TAG (CANARYLEN, ("Length of the SSP canary"), AUXV_FORMAT_DEC);
307 TAG (OSRELDATE, _("OSRELDATE"), AUXV_FORMAT_DEC);
308 TAG (NCPUS, _("Number of CPUs"), AUXV_FORMAT_DEC);
309 TAG (PAGESIZES, _("Pagesizes"), AUXV_FORMAT_HEX);
310 TAG (PAGESIZESLEN, _("Number of pagesizes"), AUXV_FORMAT_DEC);
311 TAG (TIMEKEEP, _("Pointer to timehands"), AUXV_FORMAT_HEX);
312 TAG (STACKPROT, _("Initial stack protection"), AUXV_FORMAT_HEX);
313 default:
314 default_print_auxv_entry (gdbarch, file, type, val);
315 return;
316 }
317
318 fprint_auxv_entry (file, name, description, format, type, val);
319}
320
e6cdd38e
JB
321/* Implement the "get_syscall_number" gdbarch method. */
322
323static LONGEST
324fbsd_get_syscall_number (struct gdbarch *gdbarch,
325 ptid_t ptid)
326{
327
328 /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD
329 native targets fetch the system call number from the
330 'pl_syscall_code' member of struct ptrace_lwpinfo in fbsd_wait.
331 However, system call catching requires this function to be
332 set. */
333
334 internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called"));
335}
336
a904c024
AA
337/* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
338
339void
340fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
341{
79117428
JB
342 set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
343 set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
a904c024 344 set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
82372b2f 345 set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
e6cdd38e
JB
346
347 /* `catch syscall' */
348 set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");
349 set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number);
a904c024 350}