Add a new gdbarch method to print a single AUXV entry.
[deliverable/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"
21#include "gdbcore.h"
22#include "inferior.h"
23#include "regcache.h"
24#include "regset.h"
25#include "gdbthread.h"
26
a904c024
AA
27#include "elf-bfd.h"
28#include "fbsd-tdep.h"
29
30
79117428
JB
31/* This is how we want PTIDs from core files to be printed. */
32
33static char *
34fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
35{
36 static char buf[80];
37
38 if (ptid_get_lwp (ptid) != 0)
39 {
40 xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
41 return buf;
42 }
43
44 return normal_pid_to_str (ptid);
45}
46
47/* Extract the name assigned to a thread from a core. Returns the
48 string in a static buffer. */
49
50static const char *
51fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
52{
53 static char buf[80];
54 struct bfd_section *section;
55 bfd_size_type size;
56 char sectionstr[32];
57
58 if (ptid_get_lwp (thr->ptid) != 0)
59 {
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
66 note. */
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)
71 {
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,
77 size)
78 && buf[0] != '\0')
79 {
80 buf[size] = '\0';
81
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
85 that case. */
86 if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0)
87 return buf;
88 }
89 }
90 }
91
92 return NULL;
93}
94
a904c024
AA
95static int
96find_signalled_thread (struct thread_info *info, void *data)
97{
98 if (info->suspend.stop_signal != GDB_SIGNAL_0
99 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
100 return 1;
101
102 return 0;
103}
104
20a0aab3
JB
105/* Structure for passing information from
106 fbsd_collect_thread_registers via an iterator to
107 fbsd_collect_regset_section_cb. */
a904c024
AA
108
109struct fbsd_collect_regset_section_cb_data
110{
111 const struct regcache *regcache;
112 bfd *obfd;
113 char *note_data;
114 int *note_size;
20a0aab3
JB
115 unsigned long lwp;
116 enum gdb_signal stop_signal;
117 int abort_iteration;
a904c024
AA
118};
119
120static void
121fbsd_collect_regset_section_cb (const char *sect_name, int size,
122 const struct regset *regset,
123 const char *human_name, void *cb_data)
124{
125 char *buf;
7567e115
SM
126 struct fbsd_collect_regset_section_cb_data *data
127 = (struct fbsd_collect_regset_section_cb_data *) cb_data;
a904c024 128
20a0aab3
JB
129 if (data->abort_iteration)
130 return;
131
a904c024
AA
132 gdb_assert (regset->collect_regset);
133
224c3ddb 134 buf = (char *) xmalloc (size);
a904c024
AA
135 regset->collect_regset (regset, data->regcache, -1, buf, size);
136
137 /* PRSTATUS still needs to be treated specially. */
138 if (strcmp (sect_name, ".reg") == 0)
139 data->note_data = (char *) elfcore_write_prstatus
20a0aab3
JB
140 (data->obfd, data->note_data, data->note_size, data->lwp,
141 gdb_signal_to_host (data->stop_signal), buf);
a904c024
AA
142 else
143 data->note_data = (char *) elfcore_write_register_note
144 (data->obfd, data->note_data, data->note_size,
145 sect_name, buf, size);
146 xfree (buf);
20a0aab3
JB
147
148 if (data->note_data == NULL)
149 data->abort_iteration = 1;
150}
151
152/* Records the thread's register state for the corefile note
153 section. */
154
155static char *
156fbsd_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)
160{
161 struct gdbarch *gdbarch = get_regcache_arch (regcache);
162 struct fbsd_collect_regset_section_cb_data data;
163
164 data.regcache = regcache;
165 data.obfd = obfd;
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);
171
172 gdbarch_iterate_over_regset_sections (gdbarch,
173 fbsd_collect_regset_section_cb,
174 &data, regcache);
175 return data.note_data;
176}
177
178struct fbsd_corefile_thread_data
179{
180 struct gdbarch *gdbarch;
181 bfd *obfd;
182 char *note_data;
183 int *note_size;
184 enum gdb_signal stop_signal;
185};
186
187/* Records the thread's register state for the corefile note
188 section. */
189
190static void
191fbsd_corefile_thread (struct thread_info *info,
192 struct fbsd_corefile_thread_data *args)
193{
194 struct cleanup *old_chain;
195 struct regcache *regcache;
196
197 regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
198
199 old_chain = save_inferior_ptid ();
200 inferior_ptid = info->ptid;
201 target_fetch_registers (regcache, -1);
202 do_cleanups (old_chain);
203
204 args->note_data = fbsd_collect_thread_registers
205 (regcache, info->ptid, args->obfd, args->note_data,
206 args->note_size, args->stop_signal);
a904c024
AA
207}
208
209/* Create appropriate note sections for a corefile, returning them in
210 allocated memory. */
211
212static char *
213fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
214{
20a0aab3
JB
215 struct fbsd_corefile_thread_data thread_args;
216 char *note_data = NULL;
a904c024 217 Elf_Internal_Ehdr *i_ehdrp;
20a0aab3 218 struct thread_info *curr_thr, *signalled_thr, *thr;
a904c024
AA
219
220 /* Put a "FreeBSD" label in the ELF header. */
221 i_ehdrp = elf_elfheader (obfd);
222 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
223
224 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
225
a904c024
AA
226 if (get_exec_file (0))
227 {
228 const char *fname = lbasename (get_exec_file (0));
229 char *psargs = xstrdup (fname);
230
231 if (get_inferior_args ())
232 psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
233 (char *) NULL);
234
235 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
236 fname, psargs);
237 }
238
20a0aab3
JB
239 /* Thread register information. */
240 TRY
241 {
242 update_thread_list ();
243 }
244 CATCH (e, RETURN_MASK_ERROR)
245 {
246 exception_print (gdb_stderr, e);
247 }
248 END_CATCH
249
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;
257 else
258 {
259 signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
260 if (signalled_thr == NULL)
261 signalled_thr = curr_thr;
262 }
263
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;
269
270 fbsd_corefile_thread (signalled_thr, &thread_args);
271 ALL_NON_EXITED_THREADS (thr)
272 {
273 if (thr == signalled_thr)
274 continue;
275 if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
276 continue;
277
278 fbsd_corefile_thread (thr, &thread_args);
279 }
280
281 note_data = thread_args.note_data;
282
a904c024
AA
283 return note_data;
284}
285
286/* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
287
288void
289fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
290{
79117428
JB
291 set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
292 set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
a904c024
AA
293 set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
294}
This page took 0.173268 seconds and 4 git commands to generate.