ctf-open-bfd.c revision 1.1 1 1.1 christos /* Opening CTF files with BFD.
2 1.1 christos Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of libctf.
5 1.1 christos
6 1.1 christos libctf is free software; you can redistribute it and/or modify it under
7 1.1 christos the terms of the GNU General Public License as published by the Free
8 1.1 christos Software Foundation; either version 3, or (at your option) any later
9 1.1 christos version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful, but
12 1.1 christos WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 1.1 christos See the GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; see the file COPYING. If not see
18 1.1 christos <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include <ctf-impl.h>
21 1.1 christos #include <stddef.h>
22 1.1 christos #include <assert.h>
23 1.1 christos #include <sys/types.h>
24 1.1 christos #include <sys/stat.h>
25 1.1 christos #include <errno.h>
26 1.1 christos #include <string.h>
27 1.1 christos #include <fcntl.h>
28 1.1 christos #include <elf.h>
29 1.1 christos #include <bfd.h>
30 1.1 christos #include "swap.h"
31 1.1 christos #include "ctf-endian.h"
32 1.1 christos
33 1.1 christos #include "elf-bfd.h"
34 1.1 christos
35 1.1 christos /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
36 1.1 christos ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
37 1.1 christos STRSECT, as needed, on close (though the STRSECT interior is bound to the bfd
38 1.1 christos * and is not actually freed by this machinery). */
39 1.1 christos
40 1.1 christos static struct ctf_archive_internal *
41 1.1 christos ctf_new_archive_internal (int is_archive, struct ctf_archive *arc,
42 1.1 christos ctf_file_t *fp, const ctf_sect_t *symsect,
43 1.1 christos const ctf_sect_t *strsect,
44 1.1 christos int *errp)
45 1.1 christos {
46 1.1 christos struct ctf_archive_internal *arci;
47 1.1 christos
48 1.1 christos if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
49 1.1 christos {
50 1.1 christos if (is_archive)
51 1.1 christos ctf_arc_close_internal (arc);
52 1.1 christos else
53 1.1 christos ctf_file_close (fp);
54 1.1 christos return (ctf_set_open_errno (errp, errno));
55 1.1 christos }
56 1.1 christos arci->ctfi_is_archive = is_archive;
57 1.1 christos if (is_archive)
58 1.1 christos arci->ctfi_archive = arc;
59 1.1 christos else
60 1.1 christos arci->ctfi_file = fp;
61 1.1 christos if (symsect)
62 1.1 christos memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
63 1.1 christos if (strsect)
64 1.1 christos memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
65 1.1 christos
66 1.1 christos return arci;
67 1.1 christos }
68 1.1 christos
69 1.1 christos /* Free the BFD bits of a CTF file on ctf_arc_close(). */
70 1.1 christos
71 1.1 christos static void
72 1.1 christos ctf_bfdclose (struct ctf_archive_internal *arci)
73 1.1 christos {
74 1.1 christos if (arci->ctfi_abfd != NULL)
75 1.1 christos if (!bfd_close_all_done (arci->ctfi_abfd))
76 1.1 christos ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
77 1.1 christos }
78 1.1 christos
79 1.1 christos /* Open a CTF file given the specified BFD. */
80 1.1 christos
81 1.1 christos ctf_archive_t *
82 1.1 christos ctf_bfdopen (struct bfd *abfd, int *errp)
83 1.1 christos {
84 1.1 christos ctf_archive_t *arc;
85 1.1 christos asection *ctf_asect;
86 1.1 christos bfd_byte *contents;
87 1.1 christos ctf_sect_t ctfsect;
88 1.1 christos
89 1.1 christos libctf_init_debug();
90 1.1 christos
91 1.1 christos if ((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL)
92 1.1 christos {
93 1.1 christos return (ctf_set_open_errno (errp, ECTF_NOCTFDATA));
94 1.1 christos }
95 1.1 christos
96 1.1 christos if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents))
97 1.1 christos {
98 1.1 christos ctf_dprintf ("ctf_bfdopen(): cannot malloc CTF section: %s\n",
99 1.1 christos bfd_errmsg (bfd_get_error()));
100 1.1 christos return (ctf_set_open_errno (errp, ECTF_FMT));
101 1.1 christos }
102 1.1 christos
103 1.1 christos ctfsect.cts_name = _CTF_SECTION;
104 1.1 christos ctfsect.cts_entsize = 1;
105 1.1 christos ctfsect.cts_size = bfd_section_size (ctf_asect);
106 1.1 christos ctfsect.cts_data = contents;
107 1.1 christos
108 1.1 christos if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
109 1.1 christos {
110 1.1 christos arc->ctfi_data = (void *) ctfsect.cts_data;
111 1.1 christos return arc;
112 1.1 christos }
113 1.1 christos
114 1.1 christos free (contents);
115 1.1 christos return NULL; /* errno is set for us. */
116 1.1 christos }
117 1.1 christos
118 1.1 christos /* Open a CTF file given the specified BFD and CTF section (which may contain a
119 1.1 christos CTF archive or a file). Takes ownership of the ctfsect, and frees it
120 1.1 christos later. */
121 1.1 christos
122 1.1 christos ctf_archive_t *
123 1.1 christos ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
124 1.1 christos const ctf_sect_t *ctfsect, int *errp)
125 1.1 christos {
126 1.1 christos struct ctf_archive *arc = NULL;
127 1.1 christos ctf_archive_t *arci;
128 1.1 christos ctf_file_t *fp = NULL;
129 1.1 christos ctf_sect_t *symsectp = NULL;
130 1.1 christos ctf_sect_t *strsectp = NULL;
131 1.1 christos const char *bfderrstr = NULL;
132 1.1 christos int is_archive;
133 1.1 christos
134 1.1 christos #ifdef HAVE_BFD_ELF
135 1.1 christos ctf_sect_t symsect, strsect;
136 1.1 christos Elf_Internal_Shdr *strhdr;
137 1.1 christos Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);
138 1.1 christos size_t symcount = symhdr->sh_size / symhdr->sh_entsize;
139 1.1 christos Elf_Internal_Sym *isymbuf;
140 1.1 christos bfd_byte *symtab;
141 1.1 christos const char *strtab = NULL;
142 1.1 christos /* TODO: handle SYMTAB_SHNDX. */
143 1.1 christos
144 1.1 christos if ((symtab = malloc (symhdr->sh_size)) == NULL)
145 1.1 christos {
146 1.1 christos bfderrstr = "Cannot malloc symbol table";
147 1.1 christos goto err;
148 1.1 christos }
149 1.1 christos
150 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
151 1.1 christos NULL, symtab, NULL);
152 1.1 christos free (isymbuf);
153 1.1 christos if (isymbuf == NULL)
154 1.1 christos {
155 1.1 christos bfderrstr = "Cannot read symbol table";
156 1.1 christos goto err_free_sym;
157 1.1 christos }
158 1.1 christos
159 1.1 christos if (elf_elfsections (abfd) != NULL
160 1.1 christos && symhdr->sh_link < elf_numsections (abfd))
161 1.1 christos {
162 1.1 christos strhdr = elf_elfsections (abfd)[symhdr->sh_link];
163 1.1 christos if (strhdr->contents == NULL)
164 1.1 christos {
165 1.1 christos if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
166 1.1 christos {
167 1.1 christos bfderrstr = "Cannot read string table";
168 1.1 christos goto err_free_sym;
169 1.1 christos }
170 1.1 christos }
171 1.1 christos else
172 1.1 christos strtab = (const char *) strhdr->contents;
173 1.1 christos }
174 1.1 christos
175 1.1 christos if (strtab)
176 1.1 christos {
177 1.1 christos /* The names here are more or less arbitrary, but there is no point
178 1.1 christos thrashing around digging the name out of the shstrtab given that we don't
179 1.1 christos use it for anything but debugging. */
180 1.1 christos
181 1.1 christos strsect.cts_data = strtab;
182 1.1 christos strsect.cts_name = ".strtab";
183 1.1 christos strsect.cts_size = strhdr->sh_size;
184 1.1 christos strsectp = &strsect;
185 1.1 christos
186 1.1 christos assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
187 1.1 christos symsect.cts_name = ".symtab";
188 1.1 christos symsect.cts_entsize = symhdr->sh_entsize;
189 1.1 christos symsect.cts_size = symhdr->sh_size;
190 1.1 christos symsect.cts_data = symtab;
191 1.1 christos symsectp = &symsect;
192 1.1 christos }
193 1.1 christos #endif
194 1.1 christos
195 1.1 christos if (ctfsect->cts_size > sizeof (uint64_t) &&
196 1.1 christos ((*(uint64_t *) ctfsect->cts_data) == CTFA_MAGIC))
197 1.1 christos {
198 1.1 christos is_archive = 1;
199 1.1 christos if ((arc = ctf_arc_bufopen ((void *) ctfsect->cts_data,
200 1.1 christos ctfsect->cts_size, errp)) == NULL)
201 1.1 christos goto err_free_str;
202 1.1 christos }
203 1.1 christos else
204 1.1 christos {
205 1.1 christos is_archive = 0;
206 1.1 christos if ((fp = ctf_bufopen (ctfsect, symsectp, strsectp, errp)) == NULL)
207 1.1 christos {
208 1.1 christos ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n",
209 1.1 christos ctf_errmsg (*errp));
210 1.1 christos goto err_free_str;
211 1.1 christos }
212 1.1 christos }
213 1.1 christos arci = ctf_new_archive_internal (is_archive, arc, fp, symsectp, strsectp,
214 1.1 christos errp);
215 1.1 christos
216 1.1 christos if (arci)
217 1.1 christos return arci;
218 1.1 christos err_free_str: ;
219 1.1 christos #ifdef HAVE_BFD_ELF
220 1.1 christos err_free_sym:
221 1.1 christos free (symtab);
222 1.1 christos #endif
223 1.1 christos err: _libctf_unused_;
224 1.1 christos if (bfderrstr)
225 1.1 christos {
226 1.1 christos ctf_dprintf ("ctf_bfdopen(): %s: %s\n", bfderrstr,
227 1.1 christos bfd_errmsg (bfd_get_error()));
228 1.1 christos ctf_set_open_errno (errp, ECTF_FMT);
229 1.1 christos }
230 1.1 christos return NULL;
231 1.1 christos }
232 1.1 christos
233 1.1 christos /* Open the specified file descriptor and return a pointer to a CTF archive that
234 1.1 christos contains one or more CTF containers. The file can be an ELF file, a raw CTF
235 1.1 christos file, or a CTF archive. The caller is responsible for closing the file
236 1.1 christos descriptor when it is no longer needed. If this is an ELF file, TARGET, if
237 1.1 christos non-NULL, should be the name of a suitable BFD target. */
238 1.1 christos
239 1.1 christos ctf_archive_t *
240 1.1 christos ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
241 1.1 christos {
242 1.1 christos ctf_archive_t *arci;
243 1.1 christos bfd *abfd;
244 1.1 christos int nfd;
245 1.1 christos
246 1.1 christos struct stat st;
247 1.1 christos ssize_t nbytes;
248 1.1 christos
249 1.1 christos ctf_preamble_t ctfhdr;
250 1.1 christos uint64_t arc_magic;
251 1.1 christos
252 1.1 christos memset (&ctfhdr, 0, sizeof (ctfhdr));
253 1.1 christos
254 1.1 christos libctf_init_debug();
255 1.1 christos
256 1.1 christos if (fstat (fd, &st) == -1)
257 1.1 christos return (ctf_set_open_errno (errp, errno));
258 1.1 christos
259 1.1 christos if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
260 1.1 christos return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
261 1.1 christos
262 1.1 christos /* If we have read enough bytes to form a CTF header and the magic string
263 1.1 christos matches, in either endianness, attempt to interpret the file as raw
264 1.1 christos CTF. */
265 1.1 christos
266 1.1 christos if ((size_t) nbytes >= sizeof (ctf_preamble_t)
267 1.1 christos && (ctfhdr.ctp_magic == CTF_MAGIC
268 1.1 christos || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
269 1.1 christos {
270 1.1 christos ctf_file_t *fp = NULL;
271 1.1 christos void *data;
272 1.1 christos
273 1.1 christos if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
274 1.1 christos return (ctf_set_open_errno (errp, errno));
275 1.1 christos
276 1.1 christos if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
277 1.1 christos NULL, 0, errp)) == NULL)
278 1.1 christos {
279 1.1 christos ctf_munmap (data, (size_t) st.st_size);
280 1.1 christos return NULL; /* errno is set for us. */
281 1.1 christos }
282 1.1 christos
283 1.1 christos fp->ctf_data_mmapped = data;
284 1.1 christos fp->ctf_data_mmapped_len = (size_t) st.st_size;
285 1.1 christos
286 1.1 christos return ctf_new_archive_internal (0, NULL, fp, NULL, NULL, errp);
287 1.1 christos }
288 1.1 christos
289 1.1 christos if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
290 1.1 christos return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
291 1.1 christos
292 1.1 christos if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
293 1.1 christos {
294 1.1 christos struct ctf_archive *arc;
295 1.1 christos
296 1.1 christos if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
297 1.1 christos return NULL; /* errno is set for us. */
298 1.1 christos
299 1.1 christos return ctf_new_archive_internal (1, arc, NULL, NULL, NULL, errp);
300 1.1 christos }
301 1.1 christos
302 1.1 christos /* Attempt to open the file with BFD. We must dup the fd first, since bfd
303 1.1 christos takes ownership of the passed fd. */
304 1.1 christos
305 1.1 christos if ((nfd = dup (fd)) < 0)
306 1.1 christos return (ctf_set_open_errno (errp, errno));
307 1.1 christos
308 1.1 christos if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
309 1.1 christos {
310 1.1 christos ctf_dprintf ("Cannot open BFD from %s: %s\n",
311 1.1 christos filename ? filename : "(unknown file)",
312 1.1 christos bfd_errmsg (bfd_get_error()));
313 1.1 christos return (ctf_set_open_errno (errp, ECTF_FMT));
314 1.1 christos }
315 1.1 christos bfd_set_cacheable (abfd, 1);
316 1.1 christos
317 1.1 christos if (!bfd_check_format (abfd, bfd_object))
318 1.1 christos {
319 1.1 christos ctf_dprintf ("BFD format problem in %s: %s\n",
320 1.1 christos filename ? filename : "(unknown file)",
321 1.1 christos bfd_errmsg (bfd_get_error()));
322 1.1 christos if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
323 1.1 christos return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
324 1.1 christos else
325 1.1 christos return (ctf_set_open_errno (errp, ECTF_FMT));
326 1.1 christos }
327 1.1 christos
328 1.1 christos if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
329 1.1 christos {
330 1.1 christos if (!bfd_close_all_done (abfd))
331 1.1 christos ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
332 1.1 christos return NULL; /* errno is set for us. */
333 1.1 christos }
334 1.1 christos arci->ctfi_bfd_close = ctf_bfdclose;
335 1.1 christos arci->ctfi_abfd = abfd;
336 1.1 christos
337 1.1 christos return arci;
338 1.1 christos }
339 1.1 christos
340 1.1 christos /* Open the specified file and return a pointer to a CTF container. The file
341 1.1 christos can be either an ELF file or raw CTF file. This is just a convenient
342 1.1 christos wrapper around ctf_fdopen() for callers. */
343 1.1 christos
344 1.1 christos ctf_archive_t *
345 1.1 christos ctf_open (const char *filename, const char *target, int *errp)
346 1.1 christos {
347 1.1 christos ctf_archive_t *arc;
348 1.1 christos int fd;
349 1.1 christos
350 1.1 christos if ((fd = open (filename, O_RDONLY)) == -1)
351 1.1 christos {
352 1.1 christos if (errp != NULL)
353 1.1 christos *errp = errno;
354 1.1 christos return NULL;
355 1.1 christos }
356 1.1 christos
357 1.1 christos arc = ctf_fdopen (fd, filename, target, errp);
358 1.1 christos (void) close (fd);
359 1.1 christos return arc;
360 1.1 christos }
361 1.1 christos
362 1.1 christos /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
363 1.1 christos NULL and an error in *err. Despite the fact that this uses CTF archives, it
364 1.1 christos must be in this file to avoid dragging in BFD into non-BFD-using programs. */
365 1.1 christos ctf_archive_t *
366 1.1 christos ctf_arc_open (const char *filename, int *errp)
367 1.1 christos {
368 1.1 christos return ctf_open (filename, NULL, errp);
369 1.1 christos }
370