x86: introduce %BW to avoid going through vex_w_table[]
[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
98 #ifdef HAVE_BFD_ELF
99 ctf_sect_t symsect, strsect;
100 Elf_Internal_Shdr *strhdr;
101 Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);
102 size_t symcount = symhdr->sh_size / symhdr->sh_entsize;
103 Elf_Internal_Sym *isymbuf;
104 bfd_byte *symtab;
105 const char *strtab = NULL;
106 /* TODO: handle SYMTAB_SHNDX. */
107
108 if ((symtab = malloc (symhdr->sh_size)) == NULL)
109 {
110 bfderrstr = "Cannot malloc symbol table";
111 goto err;
112 }
113
114 isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0,
115 NULL, symtab, NULL);
116 free (isymbuf);
117 if (isymbuf == NULL)
118 {
119 bfderrstr = "Cannot read symbol table";
120 goto err_free_sym;
121 }
122
123 if (elf_elfsections (abfd) != NULL
124 && symhdr->sh_link < elf_numsections (abfd))
125 {
126 strhdr = elf_elfsections (abfd)[symhdr->sh_link];
127 if (strhdr->contents == NULL)
128 {
129 if ((strtab = bfd_elf_get_str_section (abfd, symhdr->sh_link)) == NULL)
130 {
131 bfderrstr = "Cannot read string table";
132 goto err_free_sym;
133 }
134 }
135 else
136 strtab = (const char *) strhdr->contents;
137 }
138
139 if (strtab)
140 {
141 /* The names here are more or less arbitrary, but there is no point
142 thrashing around digging the name out of the shstrtab given that we don't
143 use it for anything but debugging. */
144
145 strsect.cts_data = strtab;
146 strsect.cts_name = ".strtab";
147 strsect.cts_size = strhdr->sh_size;
148 strsectp = &strsect;
149
150 assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym);
151 symsect.cts_name = ".symtab";
152 symsect.cts_entsize = symhdr->sh_entsize;
153 symsect.cts_size = symhdr->sh_size;
154 symsect.cts_data = symtab;
155 symsectp = &symsect;
156 }
157 #endif
158
159 arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
160 if (arci)
161 {
162 /* Request freeing of the symsect. */
163 arci->ctfi_free_symsect = 1;
164 return arci;
165 }
166 #ifdef HAVE_BFD_ELF
167 err_free_sym:
168 free (symtab);
169 #endif
170 err: _libctf_unused_;
171 if (bfderrstr)
172 {
173 ctf_dprintf ("ctf_bfdopen(): %s: %s\n", bfderrstr,
174 bfd_errmsg (bfd_get_error()));
175 ctf_set_open_errno (errp, ECTF_FMT);
176 }
177 return NULL;
178 }
179
180 /* Open the specified file descriptor and return a pointer to a CTF archive that
181 contains one or more CTF containers. The file can be an ELF file, a raw CTF
182 file, or a CTF archive. The caller is responsible for closing the file
183 descriptor when it is no longer needed. If this is an ELF file, TARGET, if
184 non-NULL, should be the name of a suitable BFD target. */
185
186 ctf_archive_t *
187 ctf_fdopen (int fd, const char *filename, const char *target, int *errp)
188 {
189 ctf_archive_t *arci;
190 bfd *abfd;
191 int nfd;
192
193 struct stat st;
194 ssize_t nbytes;
195
196 ctf_preamble_t ctfhdr;
197 uint64_t arc_magic;
198
199 memset (&ctfhdr, 0, sizeof (ctfhdr));
200
201 libctf_init_debug();
202
203 if (fstat (fd, &st) == -1)
204 return (ctf_set_open_errno (errp, errno));
205
206 if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0)
207 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
208
209 /* If we have read enough bytes to form a CTF header and the magic string
210 matches, in either endianness, attempt to interpret the file as raw
211 CTF. */
212
213 if ((size_t) nbytes >= sizeof (ctf_preamble_t)
214 && (ctfhdr.ctp_magic == CTF_MAGIC
215 || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC)))
216 {
217 ctf_file_t *fp = NULL;
218 void *data;
219
220 if ((data = ctf_mmap (st.st_size, 0, fd)) == NULL)
221 return (ctf_set_open_errno (errp, errno));
222
223 if ((fp = ctf_simple_open (data, (size_t) st.st_size, NULL, 0, 0,
224 NULL, 0, errp)) == NULL)
225 {
226 ctf_munmap (data, (size_t) st.st_size);
227 return NULL; /* errno is set for us. */
228 }
229
230 fp->ctf_data_mmapped = data;
231 fp->ctf_data_mmapped_len = (size_t) st.st_size;
232
233 return ctf_new_archive_internal (0, NULL, fp, NULL, NULL, errp);
234 }
235
236 if ((nbytes = ctf_pread (fd, &arc_magic, sizeof (arc_magic), 0)) <= 0)
237 return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT));
238
239 if ((size_t) nbytes >= sizeof (uint64_t) && le64toh (arc_magic) == CTFA_MAGIC)
240 {
241 struct ctf_archive *arc;
242
243 if ((arc = ctf_arc_open_internal (filename, errp)) == NULL)
244 return NULL; /* errno is set for us. */
245
246 return ctf_new_archive_internal (1, arc, NULL, NULL, NULL, errp);
247 }
248
249 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
250 takes ownership of the passed fd. */
251
252 if ((nfd = dup (fd)) < 0)
253 return (ctf_set_open_errno (errp, errno));
254
255 if ((abfd = bfd_fdopenr (filename, target, nfd)) == NULL)
256 {
257 ctf_dprintf ("Cannot open BFD from %s: %s\n",
258 filename ? filename : "(unknown file)",
259 bfd_errmsg (bfd_get_error()));
260 return (ctf_set_open_errno (errp, ECTF_FMT));
261 }
262 bfd_set_cacheable (abfd, 1);
263
264 if (!bfd_check_format (abfd, bfd_object))
265 {
266 ctf_dprintf ("BFD format problem in %s: %s\n",
267 filename ? filename : "(unknown file)",
268 bfd_errmsg (bfd_get_error()));
269 if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
270 return (ctf_set_open_errno (errp, ECTF_BFD_AMBIGUOUS));
271 else
272 return (ctf_set_open_errno (errp, ECTF_FMT));
273 }
274
275 if ((arci = ctf_bfdopen (abfd, errp)) == NULL)
276 {
277 if (!bfd_close_all_done (abfd))
278 ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
279 return NULL; /* errno is set for us. */
280 }
281 arci->ctfi_bfd_close = ctf_bfdclose;
282 arci->ctfi_abfd = abfd;
283
284 return arci;
285 }
286
287 /* Open the specified file and return a pointer to a CTF container. The file
288 can be either an ELF file or raw CTF file. This is just a convenient
289 wrapper around ctf_fdopen() for callers. */
290
291 ctf_archive_t *
292 ctf_open (const char *filename, const char *target, int *errp)
293 {
294 ctf_archive_t *arc;
295 int fd;
296
297 if ((fd = open (filename, O_RDONLY)) == -1)
298 {
299 if (errp != NULL)
300 *errp = errno;
301 return NULL;
302 }
303
304 arc = ctf_fdopen (fd, filename, target, errp);
305 (void) close (fd);
306 return arc;
307 }
308
309 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
310 NULL and an error in *err. Despite the fact that this uses CTF archives, it
311 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
312 ctf_archive_t *
313 ctf_arc_open (const char *filename, int *errp)
314 {
315 return ctf_open (filename, NULL, errp);
316 }
This page took 0.036456 seconds and 4 git commands to generate.