1 /* Target-dependent code for FreeBSD, architecture-independent. 2 3 Copyright (C) 2002-2015 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 "gdbcore.h" 22 #include "inferior.h" 23 #include "regcache.h" 24 #include "regset.h" 25 #include "gdbthread.h" 26 27 #include "elf-bfd.h" 28 #include "fbsd-tdep.h" 29 30 31 static int 32 find_signalled_thread (struct thread_info *info, void *data) 33 { 34 if (info->suspend.stop_signal != GDB_SIGNAL_0 35 && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid)) 36 return 1; 37 38 return 0; 39 } 40 41 static enum gdb_signal 42 find_stop_signal (void) 43 { 44 struct thread_info *info = 45 iterate_over_threads (find_signalled_thread, NULL); 46 47 if (info) 48 return info->suspend.stop_signal; 49 else 50 return GDB_SIGNAL_0; 51 } 52 53 struct fbsd_collect_regset_section_cb_data 54 { 55 const struct regcache *regcache; 56 bfd *obfd; 57 char *note_data; 58 int *note_size; 59 }; 60 61 static void 62 fbsd_collect_regset_section_cb (const char *sect_name, int size, 63 const struct regset *regset, 64 const char *human_name, void *cb_data) 65 { 66 char *buf; 67 struct fbsd_collect_regset_section_cb_data *data = cb_data; 68 69 gdb_assert (regset->collect_regset); 70 71 buf = xmalloc (size); 72 regset->collect_regset (regset, data->regcache, -1, buf, size); 73 74 /* PRSTATUS still needs to be treated specially. */ 75 if (strcmp (sect_name, ".reg") == 0) 76 data->note_data = (char *) elfcore_write_prstatus 77 (data->obfd, data->note_data, data->note_size, 78 ptid_get_pid (inferior_ptid), find_stop_signal (), buf); 79 else 80 data->note_data = (char *) elfcore_write_register_note 81 (data->obfd, data->note_data, data->note_size, 82 sect_name, buf, size); 83 xfree (buf); 84 } 85 86 /* Create appropriate note sections for a corefile, returning them in 87 allocated memory. */ 88 89 static char * 90 fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) 91 { 92 struct regcache *regcache = get_current_regcache (); 93 char *note_data; 94 Elf_Internal_Ehdr *i_ehdrp; 95 struct fbsd_collect_regset_section_cb_data data; 96 97 /* Put a "FreeBSD" label in the ELF header. */ 98 i_ehdrp = elf_elfheader (obfd); 99 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 100 101 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch)); 102 103 data.regcache = regcache; 104 data.obfd = obfd; 105 data.note_data = NULL; 106 data.note_size = note_size; 107 target_fetch_registers (regcache, -1); 108 gdbarch_iterate_over_regset_sections (gdbarch, 109 fbsd_collect_regset_section_cb, 110 &data, regcache); 111 note_data = data.note_data; 112 113 if (get_exec_file (0)) 114 { 115 const char *fname = lbasename (get_exec_file (0)); 116 char *psargs = xstrdup (fname); 117 118 if (get_inferior_args ()) 119 psargs = reconcat (psargs, psargs, " ", get_inferior_args (), 120 (char *) NULL); 121 122 note_data = elfcore_write_prpsinfo (obfd, note_data, note_size, 123 fname, psargs); 124 } 125 126 return note_data; 127 } 128 129 /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */ 130 131 void 132 fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 133 { 134 set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); 135 } 136