-Wwrite-strings: Constify target_pid_to_str and target_thread_extra_thread_info
[deliverable/binutils-gdb.git] / gdb / fbsd-tdep.c
1 /* Target-dependent code for FreeBSD, architecture-independent.
2
3 Copyright (C) 2002-2017 Free Software Foundation, Inc.
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"
21 #include "auxv.h"
22 #include "gdbcore.h"
23 #include "inferior.h"
24 #include "regcache.h"
25 #include "regset.h"
26 #include "gdbthread.h"
27 #include "xml-syscall.h"
28
29 #include "elf-bfd.h"
30 #include "fbsd-tdep.h"
31
32
33 /* This is how we want PTIDs from core files to be printed. */
34
35 static const char *
36 fbsd_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
52 static const char *
53 fbsd_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
97 static int
98 find_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
107 /* Structure for passing information from
108 fbsd_collect_thread_registers via an iterator to
109 fbsd_collect_regset_section_cb. */
110
111 struct fbsd_collect_regset_section_cb_data
112 {
113 const struct regcache *regcache;
114 bfd *obfd;
115 char *note_data;
116 int *note_size;
117 unsigned long lwp;
118 enum gdb_signal stop_signal;
119 int abort_iteration;
120 };
121
122 static void
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)
126 {
127 char *buf;
128 struct fbsd_collect_regset_section_cb_data *data
129 = (struct fbsd_collect_regset_section_cb_data *) cb_data;
130
131 if (data->abort_iteration)
132 return;
133
134 gdb_assert (regset->collect_regset);
135
136 buf = (char *) xmalloc (size);
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
142 (data->obfd, data->note_data, data->note_size, data->lwp,
143 gdb_signal_to_host (data->stop_signal), buf);
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);
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
157 static char *
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)
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
180 struct 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
192 static void
193 fbsd_corefile_thread (struct thread_info *info,
194 struct fbsd_corefile_thread_data *args)
195 {
196 struct regcache *regcache;
197
198 regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
199
200 target_fetch_registers (regcache, -1);
201
202 args->note_data = fbsd_collect_thread_registers
203 (regcache, info->ptid, args->obfd, args->note_data,
204 args->note_size, args->stop_signal);
205 }
206
207 /* Create appropriate note sections for a corefile, returning them in
208 allocated memory. */
209
210 static char *
211 fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
212 {
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;
217
218 /* Put a "FreeBSD" label in the ELF header. */
219 i_ehdrp = elf_elfheader (obfd);
220 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
221
222 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
223
224 if (get_exec_file (0))
225 {
226 const char *fname = lbasename (get_exec_file (0));
227 char *psargs = xstrdup (fname);
228
229 if (get_inferior_args ())
230 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
231 (char *) NULL);
232
233 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
234 fname, psargs);
235 }
236
237 /* Thread register information. */
238 TRY
239 {
240 update_thread_list ();
241 }
242 CATCH (e, RETURN_MASK_ERROR)
243 {
244 exception_print (gdb_stderr, e);
245 }
246 END_CATCH
247
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;
255 else
256 {
257 signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
258 if (signalled_thr == NULL)
259 signalled_thr = curr_thr;
260 }
261
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;
267
268 fbsd_corefile_thread (signalled_thr, &thread_args);
269 ALL_NON_EXITED_THREADS (thr)
270 {
271 if (thr == signalled_thr)
272 continue;
273 if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
274 continue;
275
276 fbsd_corefile_thread (thr, &thread_args);
277 }
278
279 note_data = thread_args.note_data;
280
281 return note_data;
282 }
283
284 /* Print descriptions of FreeBSD-specific AUXV entries to FILE. */
285
286 static void
287 fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
288 CORE_ADDR type, CORE_ADDR val)
289 {
290 const char *name;
291 const char *description;
292 enum auxv_format format;
293
294 switch (type)
295 {
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);
309 default:
310 default_print_auxv_entry (gdbarch, file, type, val);
311 return;
312 }
313
314 fprint_auxv_entry (file, name, description, format, type, val);
315 }
316
317 /* Implement the "get_syscall_number" gdbarch method. */
318
319 static LONGEST
320 fbsd_get_syscall_number (struct gdbarch *gdbarch,
321 ptid_t ptid)
322 {
323
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
328 set. */
329
330 internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called"));
331 }
332
333 /* To be called from GDB_OSABI_FREEBSD handlers. */
334
335 void
336 fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
337 {
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);
342
343 /* `catch syscall' */
344 set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");
345 set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number);
346 }
This page took 0.03782 seconds and 5 git commands to generate.