arm, objdump: Make objdump use bfd's machine detection to drive disassembly
[binutils-gdb.git] / libctf / ctf-open-bfd.c
blobb81df012fdc0774e55d644bff5057a7884a7e9e3
1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
4 This file is part of libctf.
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.
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.
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/>. */
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"
34 #include "elf-bfd.h"
36 /* Free the BFD bits of a CTF file on ctf_arc_close(). */
38 static void
39 ctf_bfdclose (struct ctf_archive_internal *arci)
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 ()));
47 /* Open a CTF file given the specified BFD. */
49 ctf_archive_t *
50 ctf_bfdopen (struct bfd *abfd, int *errp)
52 ctf_archive_t *arc;
53 asection *ctf_asect;
54 bfd_byte *contents;
55 ctf_sect_t ctfsect;
57 libctf_init_debug();
59 if ((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL)
61 return (ctf_set_open_errno (errp, ECTF_NOCTFDATA));
64 if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents))
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));
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;
77 if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
79 /* This frees the cts_data later. */
80 arc->ctfi_data = (void *) ctfsect.cts_data;
81 return arc;
84 free (contents);
85 return NULL; /* errno is set for us. */
88 /* Open a CTF file given the specified BFD and CTF section (which may contain a
89 CTF archive or a file). */
91 ctf_archive_t *
92 ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
93 const ctf_sect_t *ctfsect, int *errp)
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 int symsect_endianness = -1;
102 libctf_init_debug();
104 #ifdef HAVE_BFD_ELF
105 ctf_sect_t symsect, strsect;
106 Elf_Internal_Shdr *symhdr;
107 size_t symcount;
108 Elf_Internal_Sym *isymbuf;
109 bfd_byte *symtab = NULL;
110 const char *symtab_name;
111 const char *strtab = NULL;
112 const char *strtab_name;
113 size_t strsize;
114 const ctf_preamble_t *preamble;
116 if (ctfsect->cts_data == NULL)
118 bfderrstr = N_("CTF section is NULL");
119 goto err;
121 preamble = ctf_arc_bufpreamble (ctfsect);
123 if (preamble->ctp_flags & CTF_F_DYNSTR)
125 symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
126 strtab_name = ".dynstr";
127 symtab_name = ".dynsym";
129 else
131 symhdr = &elf_tdata (abfd)->symtab_hdr;
132 strtab_name = ".strtab";
133 symtab_name = ".symtab";
136 /* TODO: handle SYMTAB_SHNDX. */
138 /* Get the symtab, and the strtab associated with it. */
139 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
141 symcount = symhdr->sh_size / symhdr->sh_entsize;
142 if ((symtab = malloc (symhdr->sh_size)) == NULL)
144 bfderrstr = N_("cannot malloc symbol table");
145 goto err;
148 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
149 NULL, symtab, NULL);
150 free (isymbuf);
151 if (isymbuf == NULL)
153 bfderrstr = N_("cannot read symbol table");
154 goto err_free_sym;
157 if (elf_elfsections (abfd) != NULL
158 && symhdr->sh_link < elf_numsections (abfd))
160 Elf_Internal_Shdr *strhdr = elf_elfsections (abfd)[symhdr->sh_link];
162 strsize = strhdr->sh_size;
163 if (strhdr->contents == NULL)
165 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
167 bfderrstr = N_("cannot read string table");
168 goto err_free_sym;
171 else
172 strtab = (const char *) strhdr->contents;
175 else /* No symtab: just try getting .strtab or .dynstr by name. */
177 bfd_byte *str_bcontents;
178 asection *str_asect;
180 if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
182 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
184 strtab = (const char *) str_bcontents;
185 strtab_alloc = (char *) str_bcontents;
186 strsize = str_asect->size;
191 if (strtab)
193 /* The names here are more or less arbitrary, but there is no point
194 thrashing around digging the name out of the shstrtab given that we don't
195 use it for anything but debugging. */
197 strsect.cts_data = strtab;
198 strsect.cts_name = strtab_name;
199 strsect.cts_size = strsize;
200 strsectp = &strsect;
203 if (symtab)
205 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
206 symsect.cts_name = symtab_name;
207 symsect.cts_entsize = symhdr->sh_entsize;
208 symsect.cts_size = symhdr->sh_size;
209 symsect.cts_data = symtab;
210 symsectp = &symsect;
213 symsect_endianness = bfd_little_endian (abfd);
214 #endif
216 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
217 if (arci)
219 /* Request freeing of the symsect and possibly the strsect. */
220 arci->ctfi_free_symsect = 1;
221 if (strtab_alloc)
222 arci->ctfi_free_strsect = 1;
224 /* Get the endianness right. */
225 if (symsect_endianness > -1)
226 ctf_arc_symsect_endianness (arci, symsect_endianness);
227 return arci;
229 #ifdef HAVE_BFD_ELF
230 err_free_sym:
231 free (symtab);
232 free (strtab_alloc);
233 #endif
234 err: _libctf_unused_;
235 if (bfderrstr)
237 ctf_err_warn (NULL, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr),
238 bfd_errmsg (bfd_get_error()));
239 ctf_set_open_errno (errp, ECTF_FMT);
241 return NULL;
244 /* Open the specified file descriptor and return a pointer to a CTF archive that
245 contains one or more CTF dicts. The file can be an ELF file, a file
246 containing raw CTF, or a CTF archive. The caller is responsible for closing
247 the file descriptor when it is no longer needed. If this is an ELF file,
248 TARGET, if non-NULL, should be the name of a suitable BFD target. */
250 ctf_archive_t *
251 ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
253 ctf_archive_t *arci;
254 bfd *abfd;
255 int nfd;
257 struct stat st;
258 ssize_t nbytes;
260 ctf_preamble_t ctfhdr;
261 uint64_t arc_magic;
263 memset (&ctfhdr, 0, sizeof (ctfhdr));
265 libctf_init_debug();
267 if (fstat (fd, &st) == -1)
268 return (ctf_set_open_errno (errp, errno));
270 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
271 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
273 /* If we have read enough bytes to form a CTF header and the magic string
274 matches, in either endianness, attempt to interpret the file as raw
275 CTF. */
277 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
278 && (ctfhdr.ctp_magic == CTF_MAGIC
279 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
281 ctf_dict_t *fp = NULL;
282 void *data;
284 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
285 return (ctf_set_open_errno (errp, errno));
287 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
288 NULL, 0, errp)) == NULL)
290 ctf_munmap (data, (size_t) st.st_size);
291 return NULL; /* errno is set for us. */
294 fp->ctf_data_mmapped = data;
295 fp->ctf_data_mmapped_len = (size_t) st.st_size;
297 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
300 if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
301 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
303 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
305 struct ctf_archive *arc;
307 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
308 return NULL; /* errno is set for us. */
310 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
313 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
314 takes ownership of the passed fd. */
316 if ((nfd = dup (fd)) < 0)
317 return (ctf_set_open_errno (errp, errno));
319 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
321 ctf_err_warn (NULL, 0, 0, _("cannot open BFD from %s: %s"),
322 filename ? filename : _("(unknown file)"),
323 bfd_errmsg (bfd_get_error ()));
324 return (ctf_set_open_errno (errp, ECTF_FMT));
326 bfd_set_cacheable (abfd, 1);
328 if (!bfd_check_format (abfd, bfd_object))
330 ctf_err_warn (NULL, 0, 0, _("BFD format problem in %s: %s"),
331 filename ? filename : _("(unknown file)"),
332 bfd_errmsg (bfd_get_error ()));
333 if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
334 return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
335 else
336 return (ctf_set_open_errno (errp, ECTF_FMT));
339 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
341 if (!bfd_close_all_done (abfd))
342 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
343 bfd_errmsg (bfd_get_error ()));
344 return NULL; /* errno is set for us. */
346 arci->ctfi_bfd_close = ctf_bfdclose;
347 arci->ctfi_abfd = abfd;
349 return arci;
352 /* Open the specified file and return a pointer to a CTF dict. The file
353 can be either an ELF file or raw CTF file. This is just a convenient
354 wrapper around ctf_fdopen() for callers. */
356 ctf_archive_t *
357 ctf_open (const char *filename, const char *target, int *errp)
359 ctf_archive_t *arc;
360 int fd;
362 if ((fd = open (filename, O_RDONLY)) == -1)
364 if (errp != NULL)
365 *errp = errno;
366 return NULL;
369 arc = ctf_fdopen (fd, filename, target, errp);
370 (void) close (fd);
371 return arc;
374 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
375 NULL and an error in *err. Despite the fact that this uses CTF archives, it
376 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
377 ctf_archive_t *
378 ctf_arc_open (const char *filename, int *errp)
380 return ctf_open (filename, NULL, errp);