]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-open-bfd.c
aarch64, testsuite: avoid regexes in opcode field
[thirdparty/binutils-gdb.git] / libctf / ctf-open-bfd.c
CommitLineData
143dce84 1/* Opening CTF files with BFD.
fd67aa11 2 Copyright (C) 2019-2024 Free Software Foundation, Inc.
143dce84
NA
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>
6d5944fc 22#include <assert.h>
143dce84
NA
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <errno.h>
26#include <string.h>
27#include <fcntl.h>
c1401ecc 28#include <unistd.h>
143dce84
NA
29#include <elf.h>
30#include <bfd.h>
cf02c44d
NA
31#include "swap.h"
32#include "ctf-endian.h"
143dce84
NA
33
34#include "elf-bfd.h"
35
f046147d 36/* Free the BFD bits of a CTF file on ctf_arc_close(). */
143dce84
NA
37
38static void
39ctf_bfdclose (struct ctf_archive_internal *arci)
40{
41 if (arci->ctfi_abfd != NULL)
42 if (!bfd_close_all_done (arci->ctfi_abfd))
926c9e76
NA
43 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
44 bfd_errmsg (bfd_get_error ()));
143dce84
NA
45}
46
47/* Open a CTF file given the specified BFD. */
48
49ctf_archive_t *
50ctf_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 {
926c9e76
NA
66 ctf_err_warn (NULL, 0, 0, _("ctf_bfdopen(): cannot malloc "
67 "CTF section: %s"),
68 bfd_errmsg (bfd_get_error ()));
143dce84
NA
69 return (ctf_set_open_errno (errp, ECTF_FMT));
70 }
71
72 ctfsect.cts_name = _CTF_SECTION;
143dce84 73 ctfsect.cts_entsize = 1;
fd361982 74 ctfsect.cts_size = bfd_section_size (ctf_asect);
143dce84
NA
75 ctfsect.cts_data = contents;
76
77 if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
78 {
2f6ecaed 79 /* This frees the cts_data later. */
143dce84
NA
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
2f6ecaed 89 CTF archive or a file). */
143dce84
NA
90
91ctf_archive_t *
9698cf9b
NA
92ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
93 const ctf_sect_t *ctfsect, int *errp)
143dce84 94{
143dce84 95 ctf_archive_t *arci;
143dce84
NA
96 ctf_sect_t *symsectp = NULL;
97 ctf_sect_t *strsectp = NULL;
98 const char *bfderrstr = NULL;
d50c0802 99 char *strtab_alloc = NULL;
53651de8 100 int symsect_endianness = -1;
143dce84 101
5226ef61
NA
102 libctf_init_debug();
103
9698cf9b 104#ifdef HAVE_BFD_ELF
143dce84 105 ctf_sect_t symsect, strsect;
3d16b64e 106 Elf_Internal_Shdr *symhdr;
d50c0802 107 size_t symcount;
6d5944fc 108 Elf_Internal_Sym *isymbuf;
d50c0802 109 bfd_byte *symtab = NULL;
3d16b64e 110 const char *symtab_name;
6d5944fc 111 const char *strtab = NULL;
3d16b64e 112 const char *strtab_name;
d50c0802 113 size_t strsize;
3d16b64e
NA
114 const ctf_preamble_t *preamble;
115
116 if (ctfsect->cts_data == NULL)
117 {
118 bfderrstr = N_("CTF section is NULL");
119 goto err;
120 }
121 preamble = ctf_arc_bufpreamble (ctfsect);
122
123 if (preamble->ctp_flags & CTF_F_DYNSTR)
124 {
125 symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
126 strtab_name = ".dynstr";
127 symtab_name = ".dynsym";
128 }
129 else
130 {
131 symhdr = &elf_tdata (abfd)->symtab_hdr;
132 strtab_name = ".strtab";
133 symtab_name = ".symtab";
134 }
135
143dce84
NA
136 /* TODO: handle SYMTAB_SHNDX. */
137
d50c0802
NA
138 /* Get the symtab, and the strtab associated with it. */
139 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
143dce84 140 {
d50c0802
NA
141 symcount = symhdr->sh_size / symhdr->sh_entsize;
142 if ((symtab = malloc (symhdr->sh_size)) == NULL)
143 {
926c9e76 144 bfderrstr = N_("cannot malloc symbol table");
d50c0802
NA
145 goto err;
146 }
143dce84 147
d50c0802
NA
148 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
149 NULL, symtab, NULL);
150 free (isymbuf);
151 if (isymbuf == NULL)
152 {
926c9e76 153 bfderrstr = N_("cannot read symbol table");
d50c0802
NA
154 goto err_free_sym;
155 }
156
157 if (elf_elfsections (abfd) != NULL
158 && symhdr->sh_link < elf_numsections (abfd))
159 {
160 Elf_Internal_Shdr *strhdr = elf_elfsections (abfd)[symhdr->sh_link];
143dce84 161
d50c0802
NA
162 strsize = strhdr->sh_size;
163 if (strhdr->contents == NULL)
164 {
165 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
166 {
926c9e76 167 bfderrstr = N_("cannot read string table");
d50c0802
NA
168 goto err_free_sym;
169 }
170 }
171 else
172 strtab = (const char *) strhdr->contents;
173 }
174 }
3d16b64e 175 else /* No symtab: just try getting .strtab or .dynstr by name. */
6d5944fc 176 {
d50c0802
NA
177 bfd_byte *str_bcontents;
178 asection *str_asect;
179
3d16b64e 180 if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
143dce84 181 {
d50c0802 182 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
143dce84 183 {
d50c0802
NA
184 strtab = (const char *) str_bcontents;
185 strtab_alloc = (char *) str_bcontents;
186 strsize = str_asect->size;
143dce84 187 }
143dce84 188 }
6d5944fc
NA
189 }
190
191 if (strtab)
192 {
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. */
196
197 strsect.cts_data = strtab;
3d16b64e 198 strsect.cts_name = strtab_name;
d50c0802 199 strsect.cts_size = strsize;
6d5944fc 200 strsectp = &strsect;
d50c0802 201 }
6d5944fc 202
d50c0802
NA
203 if (symtab)
204 {
6d5944fc 205 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
3d16b64e 206 symsect.cts_name = symtab_name;
6d5944fc
NA
207 symsect.cts_entsize = symhdr->sh_entsize;
208 symsect.cts_size = symhdr->sh_size;
209 symsect.cts_data = symtab;
210 symsectp = &symsect;
143dce84 211 }
53651de8
NA
212
213 symsect_endianness = bfd_little_endian (abfd);
9698cf9b 214#endif
143dce84 215
2f6ecaed
NA
216 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
217 if (arci)
143dce84 218 {
d50c0802 219 /* Request freeing of the symsect and possibly the strsect. */
2f6ecaed 220 arci->ctfi_free_symsect = 1;
d50c0802
NA
221 if (strtab_alloc)
222 arci->ctfi_free_strsect = 1;
53651de8
NA
223
224 /* Get the endianness right. */
225 if (symsect_endianness > -1)
226 ctf_arc_symsect_endianness (arci, symsect_endianness);
2f6ecaed 227 return arci;
143dce84 228 }
9698cf9b 229#ifdef HAVE_BFD_ELF
6d5944fc
NA
230 err_free_sym:
231 free (symtab);
d50c0802 232 free (strtab_alloc);
9698cf9b 233#endif
143dce84
NA
234err: _libctf_unused_;
235 if (bfderrstr)
236 {
926c9e76 237 ctf_err_warn (NULL, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr),
143dce84
NA
238 bfd_errmsg (bfd_get_error()));
239 ctf_set_open_errno (errp, ECTF_FMT);
240 }
241 return NULL;
242}
243
244/* Open the specified file descriptor and return a pointer to a CTF archive that
139633c3
NA
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. */
143dce84
NA
249
250ctf_archive_t *
251ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
252{
253 ctf_archive_t *arci;
254 bfd *abfd;
255 int nfd;
256
257 struct stat st;
258 ssize_t nbytes;
259
260 ctf_preamble_t ctfhdr;
261 uint64_t arc_magic;
262
263 memset (&ctfhdr, 0, sizeof (ctfhdr));
264
265 libctf_init_debug();
266
267 if (fstat (fd, &st) == -1)
268 return (ctf_set_open_errno (errp, errno));
269
270 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
271 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
272
cf02c44d
NA
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. */
143dce84 276
cf02c44d
NA
277 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
278 && (ctfhdr.ctp_magic == CTF_MAGIC
279 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
143dce84 280 {
139633c3 281 ctf_dict_t *fp = NULL;
143dce84
NA
282 void *data;
283
143dce84
NA
284 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
285 return (ctf_set_open_errno (errp, errno));
286
287 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
288 NULL, 0, errp)) == NULL)
cf02c44d
NA
289 {
290 ctf_munmap (data, (size_t) st.st_size);
291 return NULL; /* errno is set for us. */
292 }
293
143dce84
NA
294 fp->ctf_data_mmapped = data;
295 fp->ctf_data_mmapped_len = (size_t) st.st_size;
296
601e455b 297 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
143dce84
NA
298 }
299
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));
302
cf02c44d 303 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
143dce84
NA
304 {
305 struct ctf_archive *arc;
306
307 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
308 return NULL; /* errno is set for us. */
309
601e455b 310 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
143dce84
NA
311 }
312
313 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
314 takes ownership of the passed fd. */
315
316 if ((nfd = dup (fd)) < 0)
317 return (ctf_set_open_errno (errp, errno));
318
319 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
320 {
926c9e76
NA
321 ctf_err_warn (NULL, 0, 0, _("cannot open BFD from %s: %s"),
322 filename ? filename : _("(unknown file)"),
323 bfd_errmsg (bfd_get_error ()));
143dce84
NA
324 return (ctf_set_open_errno (errp, ECTF_FMT));
325 }
edc8bbe9 326 bfd_set_cacheable (abfd, 1);
143dce84
NA
327
328 if (!bfd_check_format (abfd, bfd_object))
329 {
926c9e76
NA
330 ctf_err_warn (NULL, 0, 0, _("BFD format problem in %s: %s"),
331 filename ? filename : _("(unknown file)"),
332 bfd_errmsg (bfd_get_error ()));
143dce84
NA
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));
337 }
338
339 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
340 {
341 if (!bfd_close_all_done (abfd))
926c9e76
NA
342 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
343 bfd_errmsg (bfd_get_error ()));
143dce84
NA
344 return NULL; /* errno is set for us. */
345 }
346 arci->ctfi_bfd_close = ctf_bfdclose;
347 arci->ctfi_abfd = abfd;
348
349 return arci;
350}
351
139633c3 352/* Open the specified file and return a pointer to a CTF dict. The file
143dce84
NA
353 can be either an ELF file or raw CTF file. This is just a convenient
354 wrapper around ctf_fdopen() for callers. */
355
356ctf_archive_t *
357ctf_open (const char *filename, const char *target, int *errp)
358{
359 ctf_archive_t *arc;
360 int fd;
361
362 if ((fd = open (filename, O_RDONLY)) == -1)
363 {
364 if (errp != NULL)
365 *errp = errno;
366 return NULL;
367 }
368
369 arc = ctf_fdopen (fd, filename, target, errp);
370 (void) close (fd);
371 return arc;
372}
373
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. */
377ctf_archive_t *
378ctf_arc_open (const char *filename, int *errp)
379{
380 return ctf_open (filename, NULL, errp);
381}