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