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