]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - libctf/ctf-open-bfd.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / libctf / ctf-open-bfd.c
CommitLineData
143dce84 1/* Opening CTF files with BFD.
250d07de 2 Copyright (C) 2019-2021 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
9698cf9b 102#ifdef HAVE_BFD_ELF
143dce84 103 ctf_sect_t symsect, strsect;
3d16b64e 104 Elf_Internal_Shdr *symhdr;
d50c0802 105 size_t symcount;
6d5944fc 106 Elf_Internal_Sym *isymbuf;
d50c0802 107 bfd_byte *symtab = NULL;
3d16b64e 108 const char *symtab_name;
6d5944fc 109 const char *strtab = NULL;
3d16b64e 110 const char *strtab_name;
d50c0802 111 size_t strsize;
3d16b64e
NA
112 const ctf_preamble_t *preamble;
113
114 if (ctfsect->cts_data == NULL)
115 {
116 bfderrstr = N_("CTF section is NULL");
117 goto err;
118 }
119 preamble = ctf_arc_bufpreamble (ctfsect);
120
121 if (preamble->ctp_flags & CTF_F_DYNSTR)
122 {
123 symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
124 strtab_name = ".dynstr";
125 symtab_name = ".dynsym";
126 }
127 else
128 {
129 symhdr = &elf_tdata (abfd)->symtab_hdr;
130 strtab_name = ".strtab";
131 symtab_name = ".symtab";
132 }
133
143dce84
NA
134 /* TODO: handle SYMTAB_SHNDX. */
135
d50c0802
NA
136 /* Get the symtab, and the strtab associated with it. */
137 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
143dce84 138 {
d50c0802
NA
139 symcount = symhdr->sh_size / symhdr->sh_entsize;
140 if ((symtab = malloc (symhdr->sh_size)) == NULL)
141 {
926c9e76 142 bfderrstr = N_("cannot malloc symbol table");
d50c0802
NA
143 goto err;
144 }
143dce84 145
d50c0802
NA
146 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
147 NULL, symtab, NULL);
148 free (isymbuf);
149 if (isymbuf == NULL)
150 {
926c9e76 151 bfderrstr = N_("cannot read symbol table");
d50c0802
NA
152 goto err_free_sym;
153 }
154
155 if (elf_elfsections (abfd) != NULL
156 && symhdr->sh_link < elf_numsections (abfd))
157 {
158 Elf_Internal_Shdr *strhdr = elf_elfsections (abfd)[symhdr->sh_link];
143dce84 159
d50c0802
NA
160 strsize = strhdr->sh_size;
161 if (strhdr->contents == NULL)
162 {
163 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
164 {
926c9e76 165 bfderrstr = N_("cannot read string table");
d50c0802
NA
166 goto err_free_sym;
167 }
168 }
169 else
170 strtab = (const char *) strhdr->contents;
171 }
172 }
3d16b64e 173 else /* No symtab: just try getting .strtab or .dynstr by name. */
6d5944fc 174 {
d50c0802
NA
175 bfd_byte *str_bcontents;
176 asection *str_asect;
177
3d16b64e 178 if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
143dce84 179 {
d50c0802 180 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
143dce84 181 {
d50c0802
NA
182 strtab = (const char *) str_bcontents;
183 strtab_alloc = (char *) str_bcontents;
184 strsize = str_asect->size;
143dce84 185 }
143dce84 186 }
6d5944fc
NA
187 }
188
189 if (strtab)
190 {
191 /* The names here are more or less arbitrary, but there is no point
192 thrashing around digging the name out of the shstrtab given that we don't
193 use it for anything but debugging. */
194
195 strsect.cts_data = strtab;
3d16b64e 196 strsect.cts_name = strtab_name;
d50c0802 197 strsect.cts_size = strsize;
6d5944fc 198 strsectp = &strsect;
d50c0802 199 }
6d5944fc 200
d50c0802
NA
201 if (symtab)
202 {
6d5944fc 203 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
3d16b64e 204 symsect.cts_name = symtab_name;
6d5944fc
NA
205 symsect.cts_entsize = symhdr->sh_entsize;
206 symsect.cts_size = symhdr->sh_size;
207 symsect.cts_data = symtab;
208 symsectp = &symsect;
143dce84 209 }
53651de8
NA
210
211 symsect_endianness = bfd_little_endian (abfd);
9698cf9b 212#endif
143dce84 213
2f6ecaed
NA
214 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
215 if (arci)
143dce84 216 {
d50c0802 217 /* Request freeing of the symsect and possibly the strsect. */
2f6ecaed 218 arci->ctfi_free_symsect = 1;
d50c0802
NA
219 if (strtab_alloc)
220 arci->ctfi_free_strsect = 1;
53651de8
NA
221
222 /* Get the endianness right. */
223 if (symsect_endianness > -1)
224 ctf_arc_symsect_endianness (arci, symsect_endianness);
2f6ecaed 225 return arci;
143dce84 226 }
9698cf9b 227#ifdef HAVE_BFD_ELF
6d5944fc
NA
228 err_free_sym:
229 free (symtab);
d50c0802 230 free (strtab_alloc);
9698cf9b 231#endif
143dce84
NA
232err: _libctf_unused_;
233 if (bfderrstr)
234 {
926c9e76 235 ctf_err_warn (NULL, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr),
143dce84
NA
236 bfd_errmsg (bfd_get_error()));
237 ctf_set_open_errno (errp, ECTF_FMT);
238 }
239 return NULL;
240}
241
242/* Open the specified file descriptor and return a pointer to a CTF archive that
139633c3
NA
243 contains one or more CTF dicts. The file can be an ELF file, a file
244 containing raw CTF, or a CTF archive. The caller is responsible for closing
245 the file descriptor when it is no longer needed. If this is an ELF file,
246 TARGET, if non-NULL, should be the name of a suitable BFD target. */
143dce84
NA
247
248ctf_archive_t *
249ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
250{
251 ctf_archive_t *arci;
252 bfd *abfd;
253 int nfd;
254
255 struct stat st;
256 ssize_t nbytes;
257
258 ctf_preamble_t ctfhdr;
259 uint64_t arc_magic;
260
261 memset (&ctfhdr, 0, sizeof (ctfhdr));
262
263 libctf_init_debug();
264
265 if (fstat (fd, &st) == -1)
266 return (ctf_set_open_errno (errp, errno));
267
268 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
269 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
270
cf02c44d
NA
271 /* If we have read enough bytes to form a CTF header and the magic string
272 matches, in either endianness, attempt to interpret the file as raw
273 CTF. */
143dce84 274
cf02c44d
NA
275 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
276 && (ctfhdr.ctp_magic == CTF_MAGIC
277 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
143dce84 278 {
139633c3 279 ctf_dict_t *fp = NULL;
143dce84
NA
280 void *data;
281
143dce84
NA
282 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
283 return (ctf_set_open_errno (errp, errno));
284
285 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
286 NULL, 0, errp)) == NULL)
cf02c44d
NA
287 {
288 ctf_munmap (data, (size_t) st.st_size);
289 return NULL; /* errno is set for us. */
290 }
291
143dce84
NA
292 fp->ctf_data_mmapped = data;
293 fp->ctf_data_mmapped_len = (size_t) st.st_size;
294
601e455b 295 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
143dce84
NA
296 }
297
298 if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
299 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
300
cf02c44d 301 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
143dce84
NA
302 {
303 struct ctf_archive *arc;
304
305 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
306 return NULL; /* errno is set for us. */
307
601e455b 308 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
143dce84
NA
309 }
310
311 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
312 takes ownership of the passed fd. */
313
314 if ((nfd = dup (fd)) < 0)
315 return (ctf_set_open_errno (errp, errno));
316
317 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
318 {
926c9e76
NA
319 ctf_err_warn (NULL, 0, 0, _("cannot open BFD from %s: %s"),
320 filename ? filename : _("(unknown file)"),
321 bfd_errmsg (bfd_get_error ()));
143dce84
NA
322 return (ctf_set_open_errno (errp, ECTF_FMT));
323 }
edc8bbe9 324 bfd_set_cacheable (abfd, 1);
143dce84
NA
325
326 if (!bfd_check_format (abfd, bfd_object))
327 {
926c9e76
NA
328 ctf_err_warn (NULL, 0, 0, _("BFD format problem in %s: %s"),
329 filename ? filename : _("(unknown file)"),
330 bfd_errmsg (bfd_get_error ()));
143dce84
NA
331 if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
332 return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
333 else
334 return (ctf_set_open_errno (errp, ECTF_FMT));
335 }
336
337 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
338 {
339 if (!bfd_close_all_done (abfd))
926c9e76
NA
340 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
341 bfd_errmsg (bfd_get_error ()));
143dce84
NA
342 return NULL; /* errno is set for us. */
343 }
344 arci->ctfi_bfd_close = ctf_bfdclose;
345 arci->ctfi_abfd = abfd;
346
347 return arci;
348}
349
139633c3 350/* Open the specified file and return a pointer to a CTF dict. The file
143dce84
NA
351 can be either an ELF file or raw CTF file. This is just a convenient
352 wrapper around ctf_fdopen() for callers. */
353
354ctf_archive_t *
355ctf_open (const char *filename, const char *target, int *errp)
356{
357 ctf_archive_t *arc;
358 int fd;
359
360 if ((fd = open (filename, O_RDONLY)) == -1)
361 {
362 if (errp != NULL)
363 *errp = errno;
364 return NULL;
365 }
366
367 arc = ctf_fdopen (fd, filename, target, errp);
368 (void) close (fd);
369 return arc;
370}
371
372/* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
373 NULL and an error in *err. Despite the fact that this uses CTF archives, it
374 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
375ctf_archive_t *
376ctf_arc_open (const char *filename, int *errp)
377{
378 return ctf_open (filename, NULL, errp);
379}