libctf, open: fix opening CTF in binaries with no symtab
[deliverable/binutils-gdb.git] / libctf / ctf-open-bfd.c
1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2020 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_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
44 }
45
46 /* Open a CTF file given the specified BFD. */
47
48 ctf_archive_t *
49 ctf_bfdopen (struct bfd *abfd, int *errp)
50 {
51 ctf_archive_t *arc;
52 asection *ctf_asect;
53 bfd_byte *contents;
54 ctf_sect_t ctfsect;
55
56 libctf_init_debug();
57
58 if ((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL)
59 {
60 return (ctf_set_open_errno (errp, ECTF_NOCTFDATA));
61 }
62
63 if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents))
64 {
65 ctf_dprintf ("ctf_bfdopen(): cannot malloc CTF section: %s\n",
66 bfd_errmsg (bfd_get_error()));
67 return (ctf_set_open_errno (errp, ECTF_FMT));
68 }
69
70 ctfsect.cts_name = _CTF_SECTION;
71 ctfsect.cts_entsize = 1;
72 ctfsect.cts_size = bfd_section_size (ctf_asect);
73 ctfsect.cts_data = contents;
74
75 if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
76 {
77 /* This frees the cts_data later. */
78 arc->ctfi_data = (void *) ctfsect.cts_data;
79 return arc;
80 }
81
82 free (contents);
83 return NULL; /* errno is set for us. */
84 }
85
86 /* Open a CTF file given the specified BFD and CTF section (which may contain a
87 CTF archive or a file). */
88
89 ctf_archive_t *
90 ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
91 const ctf_sect_t *ctfsect, int *errp)
92 {
93 ctf_archive_t *arci;
94 ctf_sect_t *symsectp = NULL;
95 ctf_sect_t *strsectp = NULL;
96 const char *bfderrstr = NULL;
97 char *strtab_alloc = NULL;
98
99 #ifdef HAVE_BFD_ELF
100 ctf_sect_t symsect, strsect;
101 Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);
102 size_t symcount;
103 Elf_Internal_Sym *isymbuf;
104 bfd_byte *symtab = NULL;
105 const char *strtab = NULL;
106 size_t strsize;
107 /* TODO: handle SYMTAB_SHNDX. */
108
109 /* Get the symtab, and the strtab associated with it. */
110 if (elf_tdata (abfd) && symhdr && symhdr->sh_size && symhdr->sh_entsize)
111 {
112 symcount = symhdr->sh_size / symhdr->sh_entsize;
113 if ((symtab = malloc (symhdr->sh_size)) == NULL)
114 {
115 bfderrstr = "Cannot malloc symbol table";
116 goto err;
117 }
118
119 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
120 NULL, symtab, NULL);
121 free (isymbuf);
122 if (isymbuf == NULL)
123 {
124 bfderrstr = "Cannot read symbol table";
125 goto err_free_sym;
126 }
127
128 if (elf_elfsections (abfd) != NULL
129 && symhdr->sh_link < elf_numsections (abfd))
130 {
131 Elf_Internal_Shdr *strhdr = elf_elfsections (abfd)[symhdr->sh_link];
132
133 strsize = strhdr->sh_size;
134 if (strhdr->contents == NULL)
135 {
136 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
137 {
138 bfderrstr = "Cannot read string table";
139 goto err_free_sym;
140 }
141 }
142 else
143 strtab = (const char *) strhdr->contents;
144 }
145 }
146 else /* No symtab: just try getting .strtab by name. */
147 {
148 bfd_byte *str_bcontents;
149 asection *str_asect;
150
151 if ((str_asect = bfd_get_section_by_name (abfd, ".strtab")) != NULL)
152 {
153 if (bfd_malloc_and_get_section (abfd, str_asect, &str_bcontents))
154 {
155 strtab = (const char *) str_bcontents;
156 strtab_alloc = (char *) str_bcontents;
157 strsize = str_asect->size;
158 }
159 }
160 }
161
162 if (strtab)
163 {
164 /* The names here are more or less arbitrary, but there is no point
165 thrashing around digging the name out of the shstrtab given that we don't
166 use it for anything but debugging. */
167
168 strsect.cts_data = strtab;
169 strsect.cts_name = ".strtab";
170 strsect.cts_size = strsize;
171 strsectp = &strsect;
172 }
173
174 if (symtab)
175 {
176 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
177 symsect.cts_name = ".symtab";
178 symsect.cts_entsize = symhdr->sh_entsize;
179 symsect.cts_size = symhdr->sh_size;
180 symsect.cts_data = symtab;
181 symsectp = &symsect;
182 }
183 #endif
184
185 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
186 if (arci)
187 {
188 /* Request freeing of the symsect and possibly the strsect. */
189 arci->ctfi_free_symsect = 1;
190 if (strtab_alloc)
191 arci->ctfi_free_strsect = 1;
192 return arci;
193 }
194 #ifdef HAVE_BFD_ELF
195 err_free_sym:
196 free (symtab);
197 free (strtab_alloc);
198 #endif
199 err: _libctf_unused_;
200 if (bfderrstr)
201 {
202 ctf_dprintf ("ctf_bfdopen(): %s: %s\n", bfderrstr,
203 bfd_errmsg (bfd_get_error()));
204 ctf_set_open_errno (errp, ECTF_FMT);
205 }
206 return NULL;
207 }
208
209 /* Open the specified file descriptor and return a pointer to a CTF archive that
210 contains one or more CTF containers. The file can be an ELF file, a raw CTF
211 file, or a CTF archive. The caller is responsible for closing the file
212 descriptor when it is no longer needed. If this is an ELF file, TARGET, if
213 non-NULL, should be the name of a suitable BFD target. */
214
215 ctf_archive_t *
216 ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
217 {
218 ctf_archive_t *arci;
219 bfd *abfd;
220 int nfd;
221
222 struct stat st;
223 ssize_t nbytes;
224
225 ctf_preamble_t ctfhdr;
226 uint64_t arc_magic;
227
228 memset (&ctfhdr, 0, sizeof (ctfhdr));
229
230 libctf_init_debug();
231
232 if (fstat (fd, &st) == -1)
233 return (ctf_set_open_errno (errp, errno));
234
235 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
236 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
237
238 /* If we have read enough bytes to form a CTF header and the magic string
239 matches, in either endianness, attempt to interpret the file as raw
240 CTF. */
241
242 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
243 && (ctfhdr.ctp_magic == CTF_MAGIC
244 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
245 {
246 ctf_file_t *fp = NULL;
247 void *data;
248
249 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
250 return (ctf_set_open_errno (errp, errno));
251
252 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
253 NULL, 0, errp)) == NULL)
254 {
255 ctf_munmap (data, (size_t) st.st_size);
256 return NULL; /* errno is set for us. */
257 }
258
259 fp->ctf_data_mmapped = data;
260 fp->ctf_data_mmapped_len = (size_t) st.st_size;
261
262 return ctf_new_archive_internal (0, 1, NULL, fp, NULL, NULL, errp);
263 }
264
265 if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
266 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
267
268 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
269 {
270 struct ctf_archive *arc;
271
272 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
273 return NULL; /* errno is set for us. */
274
275 return ctf_new_archive_internal (1, 1, arc, NULL, NULL, NULL, errp);
276 }
277
278 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
279 takes ownership of the passed fd. */
280
281 if ((nfd = dup (fd)) < 0)
282 return (ctf_set_open_errno (errp, errno));
283
284 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
285 {
286 ctf_dprintf ("Cannot open BFD from %s: %s\n",
287 filename ? filename : "(unknown file)",
288 bfd_errmsg (bfd_get_error()));
289 return (ctf_set_open_errno (errp, ECTF_FMT));
290 }
291 bfd_set_cacheable (abfd, 1);
292
293 if (!bfd_check_format (abfd, bfd_object))
294 {
295 ctf_dprintf ("BFD format problem in %s: %s\n",
296 filename ? filename : "(unknown file)",
297 bfd_errmsg (bfd_get_error()));
298 if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
299 return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
300 else
301 return (ctf_set_open_errno (errp, ECTF_FMT));
302 }
303
304 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
305 {
306 if (!bfd_close_all_done (abfd))
307 ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
308 return NULL; /* errno is set for us. */
309 }
310 arci->ctfi_bfd_close = ctf_bfdclose;
311 arci->ctfi_abfd = abfd;
312
313 return arci;
314 }
315
316 /* Open the specified file and return a pointer to a CTF container. The file
317 can be either an ELF file or raw CTF file. This is just a convenient
318 wrapper around ctf_fdopen() for callers. */
319
320 ctf_archive_t *
321 ctf_open (const char *filename, const char *target, int *errp)
322 {
323 ctf_archive_t *arc;
324 int fd;
325
326 if ((fd = open (filename, O_RDONLY)) == -1)
327 {
328 if (errp != NULL)
329 *errp = errno;
330 return NULL;
331 }
332
333 arc = ctf_fdopen (fd, filename, target, errp);
334 (void) close (fd);
335 return arc;
336 }
337
338 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
339 NULL and an error in *err. Despite the fact that this uses CTF archives, it
340 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
341 ctf_archive_t *
342 ctf_arc_open (const char *filename, int *errp)
343 {
344 return ctf_open (filename, NULL, errp);
345 }
This page took 0.036573 seconds and 5 git commands to generate.