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