Home | History | Annotate | Line # | Download | only in gdb
fbsd-tdep.c revision 1.5
      1  1.1  christos /* Target-dependent code for FreeBSD, architecture-independent.
      2  1.1  christos 
      3  1.5  christos    Copyright (C) 2002-2017 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.4  christos #include "auxv.h"
     22  1.1  christos #include "gdbcore.h"
     23  1.1  christos #include "inferior.h"
     24  1.1  christos #include "regcache.h"
     25  1.1  christos #include "regset.h"
     26  1.1  christos #include "gdbthread.h"
     27  1.4  christos #include "xml-syscall.h"
     28  1.1  christos 
     29  1.1  christos #include "elf-bfd.h"
     30  1.1  christos #include "fbsd-tdep.h"
     31  1.1  christos 
     32  1.1  christos 
     33  1.4  christos /* This is how we want PTIDs from core files to be printed.  */
     34  1.4  christos 
     35  1.5  christos static const char *
     36  1.4  christos fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
     37  1.4  christos {
     38  1.4  christos   static char buf[80];
     39  1.4  christos 
     40  1.4  christos   if (ptid_get_lwp (ptid) != 0)
     41  1.4  christos     {
     42  1.4  christos       xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
     43  1.4  christos       return buf;
     44  1.4  christos     }
     45  1.4  christos 
     46  1.4  christos   return normal_pid_to_str (ptid);
     47  1.4  christos }
     48  1.4  christos 
     49  1.4  christos /* Extract the name assigned to a thread from a core.  Returns the
     50  1.4  christos    string in a static buffer.  */
     51  1.4  christos 
     52  1.4  christos static const char *
     53  1.4  christos fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
     54  1.4  christos {
     55  1.4  christos   static char buf[80];
     56  1.4  christos   struct bfd_section *section;
     57  1.4  christos   bfd_size_type size;
     58  1.4  christos   char sectionstr[32];
     59  1.4  christos 
     60  1.4  christos   if (ptid_get_lwp (thr->ptid) != 0)
     61  1.4  christos     {
     62  1.4  christos       /* FreeBSD includes a NT_FREEBSD_THRMISC note for each thread
     63  1.4  christos 	 whose contents are defined by a "struct thrmisc" declared in
     64  1.4  christos 	 <sys/procfs.h> on FreeBSD.  The per-thread name is stored as
     65  1.4  christos 	 a null-terminated string as the first member of the
     66  1.4  christos 	 structure.  Rather than define the full structure here, just
     67  1.4  christos 	 extract the null-terminated name from the start of the
     68  1.4  christos 	 note.  */
     69  1.4  christos       xsnprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld",
     70  1.4  christos 		ptid_get_lwp (thr->ptid));
     71  1.4  christos       section = bfd_get_section_by_name (core_bfd, sectionstr);
     72  1.4  christos       if (section != NULL && bfd_section_size (core_bfd, section) > 0)
     73  1.4  christos 	{
     74  1.4  christos 	  /* Truncate the name if it is longer than "buf".  */
     75  1.4  christos 	  size = bfd_section_size (core_bfd, section);
     76  1.4  christos 	  if (size > sizeof buf - 1)
     77  1.4  christos 	    size = sizeof buf - 1;
     78  1.4  christos 	  if (bfd_get_section_contents (core_bfd, section, buf, (file_ptr) 0,
     79  1.4  christos 					size)
     80  1.4  christos 	      && buf[0] != '\0')
     81  1.4  christos 	    {
     82  1.4  christos 	      buf[size] = '\0';
     83  1.4  christos 
     84  1.4  christos 	      /* Note that each thread will report the process command
     85  1.4  christos 		 as its thread name instead of an empty name if a name
     86  1.4  christos 		 has not been set explicitly.  Return a NULL name in
     87  1.4  christos 		 that case.  */
     88  1.4  christos 	      if (strcmp (buf, elf_tdata (core_bfd)->core->program) != 0)
     89  1.4  christos 		return buf;
     90  1.4  christos 	    }
     91  1.4  christos 	}
     92  1.4  christos     }
     93  1.4  christos 
     94  1.4  christos   return NULL;
     95  1.4  christos }
     96  1.4  christos 
     97  1.1  christos static int
     98  1.1  christos find_signalled_thread (struct thread_info *info, void *data)
     99  1.1  christos {
    100  1.1  christos   if (info->suspend.stop_signal != GDB_SIGNAL_0
    101  1.1  christos       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
    102  1.1  christos     return 1;
    103  1.1  christos 
    104  1.1  christos   return 0;
    105  1.1  christos }
    106  1.1  christos 
    107  1.4  christos /* Structure for passing information from
    108  1.4  christos    fbsd_collect_thread_registers via an iterator to
    109  1.4  christos    fbsd_collect_regset_section_cb. */
    110  1.1  christos 
    111  1.1  christos struct fbsd_collect_regset_section_cb_data
    112  1.1  christos {
    113  1.1  christos   const struct regcache *regcache;
    114  1.1  christos   bfd *obfd;
    115  1.1  christos   char *note_data;
    116  1.1  christos   int *note_size;
    117  1.4  christos   unsigned long lwp;
    118  1.4  christos   enum gdb_signal stop_signal;
    119  1.4  christos   int abort_iteration;
    120  1.1  christos };
    121  1.1  christos 
    122  1.1  christos static void
    123  1.1  christos fbsd_collect_regset_section_cb (const char *sect_name, int size,
    124  1.1  christos 				const struct regset *regset,
    125  1.1  christos 				const char *human_name, void *cb_data)
    126  1.1  christos {
    127  1.1  christos   char *buf;
    128  1.4  christos   struct fbsd_collect_regset_section_cb_data *data
    129  1.4  christos     = (struct fbsd_collect_regset_section_cb_data *) cb_data;
    130  1.4  christos 
    131  1.4  christos   if (data->abort_iteration)
    132  1.4  christos     return;
    133  1.1  christos 
    134  1.1  christos   gdb_assert (regset->collect_regset);
    135  1.1  christos 
    136  1.4  christos   buf = (char *) xmalloc (size);
    137  1.1  christos   regset->collect_regset (regset, data->regcache, -1, buf, size);
    138  1.1  christos 
    139  1.1  christos   /* PRSTATUS still needs to be treated specially.  */
    140  1.1  christos   if (strcmp (sect_name, ".reg") == 0)
    141  1.1  christos     data->note_data = (char *) elfcore_write_prstatus
    142  1.4  christos       (data->obfd, data->note_data, data->note_size, data->lwp,
    143  1.4  christos        gdb_signal_to_host (data->stop_signal), buf);
    144  1.1  christos   else
    145  1.1  christos     data->note_data = (char *) elfcore_write_register_note
    146  1.1  christos       (data->obfd, data->note_data, data->note_size,
    147  1.1  christos        sect_name, buf, size);
    148  1.1  christos   xfree (buf);
    149  1.4  christos 
    150  1.4  christos   if (data->note_data == NULL)
    151  1.4  christos     data->abort_iteration = 1;
    152  1.4  christos }
    153  1.4  christos 
    154  1.4  christos /* Records the thread's register state for the corefile note
    155  1.4  christos    section.  */
    156  1.4  christos 
    157  1.4  christos static char *
    158  1.4  christos fbsd_collect_thread_registers (const struct regcache *regcache,
    159  1.4  christos 			       ptid_t ptid, bfd *obfd,
    160  1.4  christos 			       char *note_data, int *note_size,
    161  1.4  christos 			       enum gdb_signal stop_signal)
    162  1.4  christos {
    163  1.4  christos   struct gdbarch *gdbarch = get_regcache_arch (regcache);
    164  1.4  christos   struct fbsd_collect_regset_section_cb_data data;
    165  1.4  christos 
    166  1.4  christos   data.regcache = regcache;
    167  1.4  christos   data.obfd = obfd;
    168  1.4  christos   data.note_data = note_data;
    169  1.4  christos   data.note_size = note_size;
    170  1.4  christos   data.stop_signal = stop_signal;
    171  1.4  christos   data.abort_iteration = 0;
    172  1.4  christos   data.lwp = ptid_get_lwp (ptid);
    173  1.4  christos 
    174  1.4  christos   gdbarch_iterate_over_regset_sections (gdbarch,
    175  1.4  christos 					fbsd_collect_regset_section_cb,
    176  1.4  christos 					&data, regcache);
    177  1.4  christos   return data.note_data;
    178  1.4  christos }
    179  1.4  christos 
    180  1.4  christos struct fbsd_corefile_thread_data
    181  1.4  christos {
    182  1.4  christos   struct gdbarch *gdbarch;
    183  1.4  christos   bfd *obfd;
    184  1.4  christos   char *note_data;
    185  1.4  christos   int *note_size;
    186  1.4  christos   enum gdb_signal stop_signal;
    187  1.4  christos };
    188  1.4  christos 
    189  1.4  christos /* Records the thread's register state for the corefile note
    190  1.4  christos    section.  */
    191  1.4  christos 
    192  1.4  christos static void
    193  1.4  christos fbsd_corefile_thread (struct thread_info *info,
    194  1.4  christos 		      struct fbsd_corefile_thread_data *args)
    195  1.4  christos {
    196  1.4  christos   struct regcache *regcache;
    197  1.4  christos 
    198  1.4  christos   regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
    199  1.4  christos 
    200  1.4  christos   target_fetch_registers (regcache, -1);
    201  1.4  christos 
    202  1.4  christos   args->note_data = fbsd_collect_thread_registers
    203  1.4  christos     (regcache, info->ptid, args->obfd, args->note_data,
    204  1.4  christos      args->note_size, args->stop_signal);
    205  1.1  christos }
    206  1.1  christos 
    207  1.1  christos /* Create appropriate note sections for a corefile, returning them in
    208  1.1  christos    allocated memory.  */
    209  1.1  christos 
    210  1.1  christos static char *
    211  1.1  christos fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
    212  1.1  christos {
    213  1.4  christos   struct fbsd_corefile_thread_data thread_args;
    214  1.4  christos   char *note_data = NULL;
    215  1.1  christos   Elf_Internal_Ehdr *i_ehdrp;
    216  1.4  christos   struct thread_info *curr_thr, *signalled_thr, *thr;
    217  1.1  christos 
    218  1.1  christos   /* Put a "FreeBSD" label in the ELF header.  */
    219  1.1  christos   i_ehdrp = elf_elfheader (obfd);
    220  1.1  christos   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
    221  1.1  christos 
    222  1.1  christos   gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
    223  1.1  christos 
    224  1.1  christos   if (get_exec_file (0))
    225  1.1  christos     {
    226  1.1  christos       const char *fname = lbasename (get_exec_file (0));
    227  1.1  christos       char *psargs = xstrdup (fname);
    228  1.1  christos 
    229  1.1  christos       if (get_inferior_args ())
    230  1.1  christos 	psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
    231  1.1  christos 			   (char *) NULL);
    232  1.1  christos 
    233  1.1  christos       note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
    234  1.1  christos 					  fname, psargs);
    235  1.1  christos     }
    236  1.1  christos 
    237  1.4  christos   /* Thread register information.  */
    238  1.4  christos   TRY
    239  1.4  christos     {
    240  1.4  christos       update_thread_list ();
    241  1.4  christos     }
    242  1.4  christos   CATCH (e, RETURN_MASK_ERROR)
    243  1.4  christos     {
    244  1.4  christos       exception_print (gdb_stderr, e);
    245  1.4  christos     }
    246  1.4  christos   END_CATCH
    247  1.4  christos 
    248  1.4  christos   /* Like the kernel, prefer dumping the signalled thread first.
    249  1.4  christos      "First thread" is what tools use to infer the signalled thread.
    250  1.4  christos      In case there's more than one signalled thread, prefer the
    251  1.4  christos      current thread, if it is signalled.  */
    252  1.4  christos   curr_thr = inferior_thread ();
    253  1.4  christos   if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
    254  1.4  christos     signalled_thr = curr_thr;
    255  1.4  christos   else
    256  1.4  christos     {
    257  1.4  christos       signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
    258  1.4  christos       if (signalled_thr == NULL)
    259  1.4  christos 	signalled_thr = curr_thr;
    260  1.4  christos     }
    261  1.4  christos 
    262  1.4  christos   thread_args.gdbarch = gdbarch;
    263  1.4  christos   thread_args.obfd = obfd;
    264  1.4  christos   thread_args.note_data = note_data;
    265  1.4  christos   thread_args.note_size = note_size;
    266  1.4  christos   thread_args.stop_signal = signalled_thr->suspend.stop_signal;
    267  1.4  christos 
    268  1.4  christos   fbsd_corefile_thread (signalled_thr, &thread_args);
    269  1.4  christos   ALL_NON_EXITED_THREADS (thr)
    270  1.4  christos     {
    271  1.4  christos       if (thr == signalled_thr)
    272  1.4  christos 	continue;
    273  1.4  christos       if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
    274  1.4  christos 	continue;
    275  1.4  christos 
    276  1.4  christos       fbsd_corefile_thread (thr, &thread_args);
    277  1.4  christos     }
    278  1.4  christos 
    279  1.4  christos   note_data = thread_args.note_data;
    280  1.4  christos 
    281  1.1  christos   return note_data;
    282  1.1  christos }
    283  1.1  christos 
    284  1.4  christos /* Print descriptions of FreeBSD-specific AUXV entries to FILE.  */
    285  1.4  christos 
    286  1.4  christos static void
    287  1.4  christos fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
    288  1.4  christos 		       CORE_ADDR type, CORE_ADDR val)
    289  1.4  christos {
    290  1.4  christos   const char *name;
    291  1.4  christos   const char *description;
    292  1.4  christos   enum auxv_format format;
    293  1.4  christos 
    294  1.4  christos   switch (type)
    295  1.4  christos     {
    296  1.4  christos #define _TAGNAME(tag) #tag
    297  1.4  christos #define TAGNAME(tag) _TAGNAME(AT_##tag)
    298  1.4  christos #define TAG(tag, text, kind) \
    299  1.4  christos       case AT_FREEBSD_##tag: name = TAGNAME(tag); description = text; format = kind; break
    300  1.4  christos       TAG (EXECPATH, _("Executable path"), AUXV_FORMAT_STR);
    301  1.4  christos       TAG (CANARY, _("Canary for SSP"), AUXV_FORMAT_HEX);
    302  1.4  christos       TAG (CANARYLEN, ("Length of the SSP canary"), AUXV_FORMAT_DEC);
    303  1.4  christos       TAG (OSRELDATE, _("OSRELDATE"), AUXV_FORMAT_DEC);
    304  1.4  christos       TAG (NCPUS, _("Number of CPUs"), AUXV_FORMAT_DEC);
    305  1.4  christos       TAG (PAGESIZES, _("Pagesizes"), AUXV_FORMAT_HEX);
    306  1.4  christos       TAG (PAGESIZESLEN, _("Number of pagesizes"), AUXV_FORMAT_DEC);
    307  1.4  christos       TAG (TIMEKEEP, _("Pointer to timehands"), AUXV_FORMAT_HEX);
    308  1.4  christos       TAG (STACKPROT, _("Initial stack protection"), AUXV_FORMAT_HEX);
    309  1.4  christos     default:
    310  1.4  christos       default_print_auxv_entry (gdbarch, file, type, val);
    311  1.4  christos       return;
    312  1.4  christos     }
    313  1.4  christos 
    314  1.4  christos   fprint_auxv_entry (file, name, description, format, type, val);
    315  1.4  christos }
    316  1.4  christos 
    317  1.4  christos /* Implement the "get_syscall_number" gdbarch method.  */
    318  1.4  christos 
    319  1.4  christos static LONGEST
    320  1.4  christos fbsd_get_syscall_number (struct gdbarch *gdbarch,
    321  1.4  christos 			 ptid_t ptid)
    322  1.4  christos {
    323  1.4  christos 
    324  1.4  christos   /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD
    325  1.4  christos      native targets fetch the system call number from the
    326  1.4  christos      'pl_syscall_code' member of struct ptrace_lwpinfo in fbsd_wait.
    327  1.4  christos      However, system call catching requires this function to be
    328  1.4  christos      set.  */
    329  1.4  christos 
    330  1.4  christos   internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called"));
    331  1.4  christos }
    332  1.4  christos 
    333  1.5  christos /* To be called from GDB_OSABI_FREEBSD handlers. */
    334  1.1  christos 
    335  1.1  christos void
    336  1.1  christos fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
    337  1.1  christos {
    338  1.4  christos   set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
    339  1.4  christos   set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
    340  1.1  christos   set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
    341  1.4  christos   set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
    342  1.4  christos 
    343  1.4  christos   /* `catch syscall' */
    344  1.4  christos   set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");
    345  1.4  christos   set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number);
    346  1.1  christos }
    347