]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - libctf/ctf-open-bfd.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / libctf / ctf-open-bfd.c
1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2021 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 #ifdef HAVE_BFD_ELF
103 ctf_sect_t symsect, strsect;
104 Elf_Internal_Shdr *symhdr;
105 size_t symcount;
106 Elf_Internal_Sym *isymbuf;
107 bfd_byte *symtab = NULL;
108 const char *symtab_name;
109 const char *strtab = NULL;
110 const char *strtab_name;
111 size_t strsize;
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
134 /* TODO: handle SYMTAB_SHNDX. */
135
136 /* Get the symtab, and the strtab associated with it. */
137 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
138 {
139 symcount = symhdr->sh_size / symhdr->sh_entsize;
140 if ((symtab = malloc (symhdr->sh_size)) == NULL)
141 {
142 bfderrstr = N_("cannot malloc symbol table");
143 goto err;
144 }
145
146 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
147 NULL, symtab, NULL);
148 free (isymbuf);
149 if (isymbuf == NULL)
150 {
151 bfderrstr = N_("cannot read symbol table");
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];
159
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 {
165 bfderrstr = N_("cannot read string table");
166 goto err_free_sym;
167 }
168 }
169 else
170 strtab = (const char *) strhdr->contents;
171 }
172 }
173 else /* No symtab: just try getting .strtab or .dynstr by name. */
174 {
175 bfd_byte *str_bcontents;
176 asection *str_asect;
177
178 if ((str_asect = bfd_get_section_by_name (abfd, strtab_name)) != NULL)
179 {
180 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
181 {
182 strtab = (const char *) str_bcontents;
183 strtab_alloc = (char *) str_bcontents;
184 strsize = str_asect->size;
185 }
186 }
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;
196 strsect.cts_name = strtab_name;
197 strsect.cts_size = strsize;
198 strsectp = &strsect;
199 }
200
201 if (symtab)
202 {
203 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
204 symsect.cts_name = symtab_name;
205 symsect.cts_entsize = symhdr->sh_entsize;
206 symsect.cts_size = symhdr->sh_size;
207 symsect.cts_data = symtab;
208 symsectp = &symsect;
209 }
210
211 symsect_endianness = bfd_little_endian (abfd);
212 #endif
213
214 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
215 if (arci)
216 {
217 /* Request freeing of the symsect and possibly the strsect. */
218 arci->ctfi_free_symsect = 1;
219 if (strtab_alloc)
220 arci->ctfi_free_strsect = 1;
221
222 /* Get the endianness right. */
223 if (symsect_endianness > -1)
224 ctf_arc_symsect_endianness (arci, symsect_endianness);
225 return arci;
226 }
227 #ifdef HAVE_BFD_ELF
228 err_free_sym:
229 free (symtab);
230 free (strtab_alloc);
231 #endif
232 err: _libctf_unused_;
233 if (bfderrstr)
234 {
235 ctf_err_warn (NULL, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr),
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
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. */
247
248 ctf_archive_t *
249 ctf_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
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. */
274
275 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
276 && (ctfhdr.ctp_magic == CTF_MAGIC
277 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
278 {
279 ctf_dict_t *fp = NULL;
280 void *data;
281
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)
287 {
288 ctf_munmap (data, (size_t) st.st_size);
289 return NULL; /* errno is set for us. */
290 }
291
292 fp->ctf_data_mmapped = data;
293 fp->ctf_data_mmapped_len = (size_t) st.st_size;
294
295 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
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
301 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
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
308 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
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 {
319 ctf_err_warn (NULL, 0, 0, _("cannot open BFD from %s: %s"),
320 filename ? filename : _("(unknown file)"),
321 bfd_errmsg (bfd_get_error ()));
322 return (ctf_set_open_errno (errp, ECTF_FMT));
323 }
324 bfd_set_cacheable (abfd, 1);
325
326 if (!bfd_check_format (abfd, bfd_object))
327 {
328 ctf_err_warn (NULL, 0, 0, _("BFD format problem in %s: %s"),
329 filename ? filename : _("(unknown file)"),
330 bfd_errmsg (bfd_get_error ()));
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))
340 ctf_err_warn (NULL, 0, 0, _("cannot close BFD: %s"),
341 bfd_errmsg (bfd_get_error ()));
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
350 /* Open the specified file and return a pointer to a CTF dict. The file
351 can be either an ELF file or raw CTF file. This is just a convenient
352 wrapper around ctf_fdopen() for callers. */
353
354 ctf_archive_t *
355 ctf_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. */
375 ctf_archive_t *
376 ctf_arc_open (const char *filename, int *errp)
377 {
378 return ctf_open (filename, NULL, errp);
379 }