xref: /netbsd-src/external/gpl3/gdb/dist/libctf/ctf-open-bfd.c (revision 53b02e147d4ed531c0d2a5ca9b3e8026ba3e99b5)
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 containers.  The file can be an ELF file, a raw CTF
213    file, or a CTF archive.  The caller is responsible for closing the file
214    descriptor when it is no longer needed.  If this is an ELF file, TARGET, if
215    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_file_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 container.  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 }
349