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