Add a gdbarch 'print_auxv_entry' method for FreeBSD ABIs.
[external/binutils.git] / gdb / fbsd-tdep.c
1 /* Target-dependent code for FreeBSD, architecture-independent.
2
3    Copyright (C) 2002-2016 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
28 #include "elf-bfd.h"
29 #include "fbsd-tdep.h"
30
31
32 /* This is how we want PTIDs from core files to be printed.  */
33
34 static char *
35 fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
36 {
37   static char buf[80];
38
39   if (ptid_get_lwp (ptid) != 0)
40     {
41       xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
42       return buf;
43     }
44
45   return normal_pid_to_str (ptid);
46 }
47
48 /* Extract the name assigned to a thread from a core.  Returns the
49    string in a static buffer.  */
50
51 static const char *
52 fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
53 {
54   static char buf[80];
55   struct bfd_section *section;
56   bfd_size_type size;
57   char sectionstr[32];
58
59   if (ptid_get_lwp (thr->ptid) != 0)
60     {
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
67          note.  */
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)
72         {
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,
78                                         size)
79               && buf[0] != '\0')
80             {
81               buf[size] = '\0';
82
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
86                  that case.  */
87               if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0)
88                 return buf;
89             }
90         }
91     }
92
93   return NULL;
94 }
95
96 static int
97 find_signalled_thread (struct thread_info *info, void *data)
98 {
99   if (info->suspend.stop_signal != GDB_SIGNAL_0
100       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
101     return 1;
102
103   return 0;
104 }
105
106 /* Structure for passing information from
107    fbsd_collect_thread_registers via an iterator to
108    fbsd_collect_regset_section_cb. */
109
110 struct fbsd_collect_regset_section_cb_data
111 {
112   const struct regcache *regcache;
113   bfd *obfd;
114   char *note_data;
115   int *note_size;
116   unsigned long lwp;
117   enum gdb_signal stop_signal;
118   int abort_iteration;
119 };
120
121 static void
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)
125 {
126   char *buf;
127   struct fbsd_collect_regset_section_cb_data *data
128     = (struct fbsd_collect_regset_section_cb_data *) cb_data;
129
130   if (data->abort_iteration)
131     return;
132
133   gdb_assert (regset->collect_regset);
134
135   buf = (char *) xmalloc (size);
136   regset->collect_regset (regset, data->regcache, -1, buf, size);
137
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);
143   else
144     data->note_data = (char *) elfcore_write_register_note
145       (data->obfd, data->note_data, data->note_size,
146        sect_name, buf, size);
147   xfree (buf);
148
149   if (data->note_data == NULL)
150     data->abort_iteration = 1;
151 }
152
153 /* Records the thread's register state for the corefile note
154    section.  */
155
156 static char *
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)
161 {
162   struct gdbarch *gdbarch = get_regcache_arch (regcache);
163   struct fbsd_collect_regset_section_cb_data data;
164
165   data.regcache = regcache;
166   data.obfd = obfd;
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);
172
173   gdbarch_iterate_over_regset_sections (gdbarch,
174                                         fbsd_collect_regset_section_cb,
175                                         &data, regcache);
176   return data.note_data;
177 }
178
179 struct fbsd_corefile_thread_data
180 {
181   struct gdbarch *gdbarch;
182   bfd *obfd;
183   char *note_data;
184   int *note_size;
185   enum gdb_signal stop_signal;
186 };
187
188 /* Records the thread's register state for the corefile note
189    section.  */
190
191 static void
192 fbsd_corefile_thread (struct thread_info *info,
193                       struct fbsd_corefile_thread_data *args)
194 {
195   struct cleanup *old_chain;
196   struct regcache *regcache;
197
198   regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
199
200   old_chain = save_inferior_ptid ();
201   inferior_ptid = info->ptid;
202   target_fetch_registers (regcache, -1);
203   do_cleanups (old_chain);
204
205   args->note_data = fbsd_collect_thread_registers
206     (regcache, info->ptid, args->obfd, args->note_data,
207      args->note_size, args->stop_signal);
208 }
209
210 /* Create appropriate note sections for a corefile, returning them in
211    allocated memory.  */
212
213 static char *
214 fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
215 {
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;
220
221   /* Put a "FreeBSD" label in the ELF header.  */
222   i_ehdrp = elf_elfheader (obfd);
223   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
224
225   gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
226
227   if (get_exec_file (0))
228     {
229       const char *fname = lbasename (get_exec_file (0));
230       char *psargs = xstrdup (fname);
231
232       if (get_inferior_args ())
233         psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
234                            (char *) NULL);
235
236       note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
237                                           fname, psargs);
238     }
239
240   /* Thread register information.  */
241   TRY
242     {
243       update_thread_list ();
244     }
245   CATCH (e, RETURN_MASK_ERROR)
246     {
247       exception_print (gdb_stderr, e);
248     }
249   END_CATCH
250
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;
258   else
259     {
260       signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
261       if (signalled_thr == NULL)
262         signalled_thr = curr_thr;
263     }
264
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;
270
271   fbsd_corefile_thread (signalled_thr, &thread_args);
272   ALL_NON_EXITED_THREADS (thr)
273     {
274       if (thr == signalled_thr)
275         continue;
276       if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
277         continue;
278
279       fbsd_corefile_thread (thr, &thread_args);
280     }
281
282   note_data = thread_args.note_data;
283
284   return note_data;
285 }
286
287 /* Print descriptions of FreeBSD-specific AUXV entries to FILE.  */
288
289 static void
290 fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
291                        CORE_ADDR type, CORE_ADDR val)
292 {
293   const char *name;
294   const char *description;
295   enum auxv_format format;
296
297   switch (type)
298     {
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);
312     default:
313       default_print_auxv_entry (gdbarch, file, type, val);
314       return;
315     }
316
317   fprint_auxv_entry (file, name, description, format, type, val);
318 }
319
320 /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
321
322 void
323 fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
324 {
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);
329 }