]> Git Repo - binutils.git/blob - libctf/ctf-open-bfd.c
libctf, ld, binutils: add textual error/warning reporting for libctf
[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_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, 1, 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, 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.042233 seconds and 4 git commands to generate.