]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libctf/ctf-open-bfd.c
[Morello] Teach gdb about additional CHERI auxv entries
[thirdparty/binutils-gdb.git] / libctf / ctf-open-bfd.c
1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <ctf-impl.h>
21 #include <stddef.h>
22 #include <assert.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <elf.h>
30 #include <bfd.h>
31 #include "swap.h"
32 #include "ctf-endian.h"
33
34 #include "elf-bfd.h"
35
36 /* Free the BFD bits of a CTF file on ctf_arc_close(). */
37
38 static void
39 ctf_bfdclose (struct ctf_archive_internal *arci)
40 {
41 if (arci->ctfi_abfd != NULL)
42 if (!bfd_close_all_done (arci->ctfi_abfd))
43 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
44 bfd_errmsg (bfd_get_error ()));
45 }
46
47 /* Open a CTF file given the specified BFD. */
48
49 ctf_archive_t *
50 ctf_bfdopen (struct bfd *abfd, int *errp)
51 {
52 ctf_archive_t *arc;
53 asection *ctf_asect;
54 bfd_byte *contents;
55 ctf_sect_t ctfsect;
56
57 libctf_init_debug();
58
59 if ((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL)
60 {
61 return (ctf_set_open_errno (errp, ECTF_NOCTFDATA));
62 }
63
64 if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents))
65 {
66 ctf_err_warn (NULL, 0, 0, _("ctf_bfdopen(): cannot malloc "
67 "CTF section: %s"),
68 bfd_errmsg (bfd_get_error ()));
69 return (ctf_set_open_errno (errp, ECTF_FMT));
70 }
71
72 ctfsect.cts_name = _CTF_SECTION;
73 ctfsect.cts_entsize = 1;
74 ctfsect.cts_size = bfd_section_size (ctf_asect);
75 ctfsect.cts_data = contents;
76
77 if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
78 {
79 /* This frees the cts_data later. */
80 arc->ctfi_data = (void *) ctfsect.cts_data;
81 return arc;
82 }
83
84 free (contents);
85 return NULL; /* errno is set for us. */
86 }
87
88 /* Open a CTF file given the specified BFD and CTF section (which may contain a
89 CTF archive or a file). */
90
91 ctf_archive_t *
92 ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
93 const ctf_sect_t *ctfsect, int *errp)
94 {
95 ctf_archive_t *arci;
96 ctf_sect_t *symsectp = NULL;
97 ctf_sect_t *strsectp = NULL;
98 const char *bfderrstr = NULL;
99 char *strtab_alloc = NULL;
100
101 #ifdef HAVE_BFD_ELF
102 ctf_sect_t symsect, strsect;
103 Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);
104 size_t symcount;
105 Elf_Internal_Sym *isymbuf;
106 bfd_byte *symtab = NULL;
107 const char *strtab = NULL;
108 size_t strsize;
109 /* TODO: handle SYMTAB_SHNDX. */
110
111 /* Get the symtab, and the strtab associated with it. */
112 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
113 {
114 symcount = symhdr->sh_size / symhdr->sh_entsize;
115 if ((symtab = malloc (symhdr->sh_size)) == NULL)
116 {
117 bfderrstr = N_("cannot malloc symbol table");
118 goto err;
119 }
120
121 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
122 NULL, symtab, NULL);
123 free (isymbuf);
124 if (isymbuf == NULL)
125 {
126 bfderrstr = N_("cannot read symbol table");
127 goto err_free_sym;
128 }
129
130 if (elf_elfsections (abfd) != NULL
131 && symhdr->sh_link < elf_numsections (abfd))
132 {
133 Elf_Internal_Shdr *strhdr = elf_elfsections (abfd)[symhdr->sh_link];
134
135 strsize = strhdr->sh_size;
136 if (strhdr->contents == NULL)
137 {
138 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
139 {
140 bfderrstr = N_("cannot read string table");
141 goto err_free_sym;
142 }
143 }
144 else
145 strtab = (const char *) strhdr->contents;
146 }
147 }
148 else /* No symtab: just try getting .strtab by name. */
149 {
150 bfd_byte *str_bcontents;
151 asection *str_asect;
152
153 if ((str_asect = bfd_get_section_by_name (abfd, ".strtab")) != NULL)
154 {
155 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
156 {
157 strtab = (const char *) str_bcontents;
158 strtab_alloc = (char *) str_bcontents;
159 strsize = str_asect->size;
160 }
161 }
162 }
163
164 if (strtab)
165 {
166 /* The names here are more or less arbitrary, but there is no point
167 thrashing around digging the name out of the shstrtab given that we don't
168 use it for anything but debugging. */
169
170 strsect.cts_data = strtab;
171 strsect.cts_name = ".strtab";
172 strsect.cts_size = strsize;
173 strsectp = &strsect;
174 }
175
176 if (symtab)
177 {
178 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
179 symsect.cts_name = ".symtab";
180 symsect.cts_entsize = symhdr->sh_entsize;
181 symsect.cts_size = symhdr->sh_size;
182 symsect.cts_data = symtab;
183 symsectp = &symsect;
184 }
185 #endif
186
187 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
188 if (arci)
189 {
190 /* Request freeing of the symsect and possibly the strsect. */
191 arci->ctfi_free_symsect = 1;
192 if (strtab_alloc)
193 arci->ctfi_free_strsect = 1;
194 return arci;
195 }
196 #ifdef HAVE_BFD_ELF
197 err_free_sym:
198 free (symtab);
199 free (strtab_alloc);
200 #endif
201 err: _libctf_unused_;
202 if (bfderrstr)
203 {
204 ctf_err_warn (NULL, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr),
205 bfd_errmsg (bfd_get_error()));
206 ctf_set_open_errno (errp, ECTF_FMT);
207 }
208 return NULL;
209 }
210
211 /* Open the specified file descriptor and return a pointer to a CTF archive that
212 contains one or more CTF containers. The file can be an ELF file, a raw CTF
213 file, or a CTF archive. The caller is responsible for closing the file
214 descriptor when it is no longer needed. If this is an ELF file, TARGET, if
215 non-NULL, should be the name of a suitable BFD target. */
216
217 ctf_archive_t *
218 ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
219 {
220 ctf_archive_t *arci;
221 bfd *abfd;
222 int nfd;
223
224 struct stat st;
225 ssize_t nbytes;
226
227 ctf_preamble_t ctfhdr;
228 uint64_t arc_magic;
229
230 memset (&ctfhdr, 0, sizeof (ctfhdr));
231
232 libctf_init_debug();
233
234 if (fstat (fd, &st) == -1)
235 return (ctf_set_open_errno (errp, errno));
236
237 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
238 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
239
240 /* If we have read enough bytes to form a CTF header and the magic string
241 matches, in either endianness, attempt to interpret the file as raw
242 CTF. */
243
244 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
245 && (ctfhdr.ctp_magic == CTF_MAGIC
246 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
247 {
248 ctf_file_t *fp = NULL;
249 void *data;
250
251 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
252 return (ctf_set_open_errno (errp, errno));
253
254 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
255 NULL, 0, errp)) == NULL)
256 {
257 ctf_munmap (data, (size_t) st.st_size);
258 return NULL; /* errno is set for us. */
259 }
260
261 fp->ctf_data_mmapped = data;
262 fp->ctf_data_mmapped_len = (size_t) st.st_size;
263
264 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
265 }
266
267 if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
268 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
269
270 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
271 {
272 struct ctf_archive *arc;
273
274 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
275 return NULL; /* errno is set for us. */
276
277 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
278 }
279
280 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
281 takes ownership of the passed fd. */
282
283 if ((nfd = dup (fd)) < 0)
284 return (ctf_set_open_errno (errp, errno));
285
286 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
287 {
288 ctf_err_warn (NULL, 0, 0, _("cannot open BFD from %s: %s"),
289 filename ? filename : _("(unknown file)"),
290 bfd_errmsg (bfd_get_error ()));
291 return (ctf_set_open_errno (errp, ECTF_FMT));
292 }
293 bfd_set_cacheable (abfd, 1);
294
295 if (!bfd_check_format (abfd, bfd_object))
296 {
297 ctf_err_warn (NULL, 0, 0, _("BFD format problem in %s: %s"),
298 filename ? filename : _("(unknown file)"),
299 bfd_errmsg (bfd_get_error ()));
300 if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
301 return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
302 else
303 return (ctf_set_open_errno (errp, ECTF_FMT));
304 }
305
306 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
307 {
308 if (!bfd_close_all_done (abfd))
309 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
310 bfd_errmsg (bfd_get_error ()));
311 return NULL; /* errno is set for us. */
312 }
313 arci->ctfi_bfd_close = ctf_bfdclose;
314 arci->ctfi_abfd = abfd;
315
316 return arci;
317 }
318
319 /* Open the specified file and return a pointer to a CTF container. The file
320 can be either an ELF file or raw CTF file. This is just a convenient
321 wrapper around ctf_fdopen() for callers. */
322
323 ctf_archive_t *
324 ctf_open (const char *filename, const char *target, int *errp)
325 {
326 ctf_archive_t *arc;
327 int fd;
328
329 if ((fd = open (filename, O_RDONLY)) == -1)
330 {
331 if (errp != NULL)
332 *errp = errno;
333 return NULL;
334 }
335
336 arc = ctf_fdopen (fd, filename, target, errp);
337 (void) close (fd);
338 return arc;
339 }
340
341 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
342 NULL and an error in *err. Despite the fact that this uses CTF archives, it
343 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
344 ctf_archive_t *
345 ctf_arc_open (const char *filename, int *errp)
346 {
347 return ctf_open (filename, NULL, errp);
348 }