Home | History | Annotate | Line # | Download | only in gdb
fbsd-tdep.c revision 1.5
      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 }
    347