1 /* Target-dependent code for FreeBSD, architecture-independent.
3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
25 #include "gdbthread.h"
28 #include "fbsd-tdep.h"
31 /* This is how we want PTIDs from core files to be printed. */
34 fbsd_core_pid_to_str (struct gdbarch
*gdbarch
, ptid_t ptid
)
38 if (ptid_get_lwp (ptid
) != 0)
40 xsnprintf (buf
, sizeof buf
, "LWP %ld", ptid_get_lwp (ptid
));
44 return normal_pid_to_str (ptid
);
47 /* Extract the name assigned to a thread from a core. Returns the
48 string in a static buffer. */
51 fbsd_core_thread_name (struct gdbarch
*gdbarch
, struct thread_info
*thr
)
54 struct bfd_section
*section
;
58 if (ptid_get_lwp (thr
->ptid
) != 0)
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
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)
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,
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
86 if (strcmp (buf
, elf_tdata (core_bfd
)->core
->program
) != 0)
96 find_signalled_thread (struct thread_info
*info
, void *data
)
98 if (info
->suspend
.stop_signal
!= GDB_SIGNAL_0
99 && ptid_get_pid (info
->ptid
) == ptid_get_pid (inferior_ptid
))
105 static enum gdb_signal
106 find_stop_signal (void)
108 struct thread_info
*info
=
109 iterate_over_threads (find_signalled_thread
, NULL
);
112 return info
->suspend
.stop_signal
;
117 struct fbsd_collect_regset_section_cb_data
119 const struct regcache
*regcache
;
126 fbsd_collect_regset_section_cb (const char *sect_name
, int size
,
127 const struct regset
*regset
,
128 const char *human_name
, void *cb_data
)
131 struct fbsd_collect_regset_section_cb_data
*data
132 = (struct fbsd_collect_regset_section_cb_data
*) cb_data
;
134 gdb_assert (regset
->collect_regset
);
136 buf
= (char *) xmalloc (size
);
137 regset
->collect_regset (regset
, data
->regcache
, -1, buf
, size
);
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
,
143 ptid_get_pid (inferior_ptid
), find_stop_signal (), buf
);
145 data
->note_data
= (char *) elfcore_write_register_note
146 (data
->obfd
, data
->note_data
, data
->note_size
,
147 sect_name
, buf
, size
);
151 /* Create appropriate note sections for a corefile, returning them in
155 fbsd_make_corefile_notes (struct gdbarch
*gdbarch
, bfd
*obfd
, int *note_size
)
157 struct regcache
*regcache
= get_current_regcache ();
159 Elf_Internal_Ehdr
*i_ehdrp
;
160 struct fbsd_collect_regset_section_cb_data data
;
162 /* Put a "FreeBSD" label in the ELF header. */
163 i_ehdrp
= elf_elfheader (obfd
);
164 i_ehdrp
->e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
166 gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch
));
168 data
.regcache
= regcache
;
170 data
.note_data
= NULL
;
171 data
.note_size
= note_size
;
172 target_fetch_registers (regcache
, -1);
173 gdbarch_iterate_over_regset_sections (gdbarch
,
174 fbsd_collect_regset_section_cb
,
176 note_data
= data
.note_data
;
178 if (get_exec_file (0))
180 const char *fname
= lbasename (get_exec_file (0));
181 char *psargs
= xstrdup (fname
);
183 if (get_inferior_args ())
184 psargs
= reconcat (psargs
, psargs
, " ", get_inferior_args (),
187 note_data
= elfcore_write_prpsinfo (obfd
, note_data
, note_size
,
194 /* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
197 fbsd_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
199 set_gdbarch_core_pid_to_str (gdbarch
, fbsd_core_pid_to_str
);
200 set_gdbarch_core_thread_name (gdbarch
, fbsd_core_thread_name
);
201 set_gdbarch_make_corefile_notes (gdbarch
, fbsd_make_corefile_notes
);