]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libctf/ctf-open-bfd.c
gdb/testsuite/gdb.rocm: Check value returned by hipDeviceSynchronize
[thirdparty/binutils-gdb.git] / libctf / ctf-open-bfd.c
1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2023 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 int symsect_endianness = -1;
101
102 libctf_init_debug();
103
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;
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
136 /* TODO: handle SYMTAB_SHNDX. */
137
138 /* Get the symtab, and the strtab associated with it. */
139 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
140 {
141 symcount = symhdr->sh_size / symhdr->sh_entsize;
142 if ((symtab = malloc (symhdr->sh_size)) == NULL)
143 {
144 bfderrstr = N_("cannot malloc symbol table");
145 goto err;
146 }
147
148 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
149 NULL, symtab, NULL);
150 free (isymbuf);
151 if (isymbuf == NULL)
152 {
153 bfderrstr = N_("cannot read symbol table");
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];
161
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 {
167 bfderrstr = N_("cannot read string table");
168 goto err_free_sym;
169 }
170 }
171 else
172 strtab = (const char *) strhdr->contents;
173 }
174 }
175 else /* No symtab: just try getting .strtab or .dynstr by name. */
176 {
177 bfd_byte *str_bcontents;
178 asection *str_asect;
179
180 if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
181 {
182 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
183 {
184 strtab = (const char *) str_bcontents;
185 strtab_alloc = (char *) str_bcontents;
186 strsize = str_asect->size;
187 }
188 }
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;
198 strsect.cts_name = strtab_name;
199 strsect.cts_size = strsize;
200 strsectp = &strsect;
201 }
202
203 if (symtab)
204 {
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;
211 }
212
213 symsect_endianness = bfd_little_endian (abfd);
214 #endif
215
216 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
217 if (arci)
218 {
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;
223
224 /* Get the endianness right. */
225 if (symsect_endianness > -1)
226 ctf_arc_symsect_endianness (arci, symsect_endianness);
227 return arci;
228 }
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)
236 {
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);
240 }
241 return NULL;
242 }
243
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. */
249
250 ctf_archive_t *
251 ctf_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
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. */
276
277 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
278 && (ctfhdr.ctp_magic == CTF_MAGIC
279 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
280 {
281 ctf_dict_t *fp = NULL;
282 void *data;
283
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)
289 {
290 ctf_munmap (data, (size_t) st.st_size);
291 return NULL; /* errno is set for us. */
292 }
293
294 fp->ctf_data_mmapped = data;
295 fp->ctf_data_mmapped_len = (size_t) st.st_size;
296
297 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
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
303 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
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
310 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
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 {
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));
325 }
326 bfd_set_cacheable (abfd, 1);
327
328 if (!bfd_check_format (abfd, bfd_object))
329 {
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));
337 }
338
339 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
340 {
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. */
345 }
346 arci->ctfi_bfd_close = ctf_bfdclose;
347 arci->ctfi_abfd = abfd;
348
349 return arci;
350 }
351
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. */
355
356 ctf_archive_t *
357 ctf_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. */
377 ctf_archive_t *
378 ctf_arc_open (const char *filename, int *errp)
379 {
380 return ctf_open (filename, NULL, errp);
381 }