1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
4 This file is part of libctf.
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
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.
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/>. */
23 #include <sys/types.h>
32 #include "ctf-endian.h"
36 /* Free the BFD bits of a CTF file on ctf_arc_close(). */
39 ctf_bfdclose (struct ctf_archive_internal
*arci
)
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 ()));
47 /* Open a CTF file given the specified BFD. */
50 ctf_bfdopen (struct bfd
*abfd
, int *errp
)
59 if ((ctf_asect
= bfd_get_section_by_name (abfd
, _CTF_SECTION
)) == NULL
)
61 return (ctf_set_open_errno (errp
, ECTF_NOCTFDATA
));
64 if (!bfd_malloc_and_get_section (abfd
, ctf_asect
, &contents
))
66 ctf_err_warn (NULL
, 0, 0, _("ctf_bfdopen(): cannot malloc "
68 bfd_errmsg (bfd_get_error ()));
69 return (ctf_set_open_errno (errp
, ECTF_FMT
));
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
;
77 if ((arc
= ctf_bfdopen_ctfsect (abfd
, &ctfsect
, errp
)) != NULL
)
79 /* This frees the cts_data later. */
80 arc
->ctfi_data
= (void *) ctfsect
.cts_data
;
85 return NULL
; /* errno is set for us. */
88 /* Open a CTF file given the specified BFD and CTF section (which may contain a
89 CTF archive or a file). */
92 ctf_bfdopen_ctfsect (struct bfd
*abfd _libctf_unused_
,
93 const ctf_sect_t
*ctfsect
, int *errp
)
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;
103 ctf_sect_t symsect
, strsect
;
104 Elf_Internal_Shdr
*symhdr
;
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
;
112 const ctf_preamble_t
*preamble
;
114 if (ctfsect
->cts_data
== NULL
)
116 bfderrstr
= N_("CTF section is NULL");
119 preamble
= ctf_arc_bufpreamble (ctfsect
);
121 if (preamble
->ctp_flags
& CTF_F_DYNSTR
)
123 symhdr
= &elf_tdata (abfd
)->dynsymtab_hdr
;
124 strtab_name
= ".dynstr";
125 symtab_name
= ".dynsym";
129 symhdr
= &elf_tdata (abfd
)->symtab_hdr
;
130 strtab_name
= ".strtab";
131 symtab_name
= ".symtab";
134 /* TODO: handle SYMTAB_SHNDX. */
136 /* Get the symtab, and the strtab associated with it. */
137 if (elf_tdata (abfd
) && symhdr
&& symhdr
->sh_size
&& symhdr
->sh_entsize
)
139 symcount
= symhdr
->sh_size
/ symhdr
->sh_entsize
;
140 if ((symtab
= malloc (symhdr
->sh_size
)) == NULL
)
142 bfderrstr
= N_("cannot malloc symbol table");
146 isymbuf
= bfd_elf_get_elf_syms (abfd
, symhdr
, symcount
, 0,
151 bfderrstr
= N_("cannot read symbol table");
155 if (elf_elfsections (abfd
) != NULL
156 && symhdr
->sh_link
< elf_numsections (abfd
))
158 Elf_Internal_Shdr
*strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
160 strsize
= strhdr
->sh_size
;
161 if (strhdr
->contents
== NULL
)
163 if ((strtab
= bfd_elf_get_str_section (abfd
, symhdr
->sh_link
)) == NULL
)
165 bfderrstr
= N_("cannot read string table");
170 strtab
= (const char *) strhdr
->contents
;
173 else /* No symtab: just try getting .strtab or .dynstr by name. */
175 bfd_byte
*str_bcontents
;
178 if ((str_asect
= bfd_get_section_by_name (abfd
, strtab_name
)) != NULL
)
180 if (bfd_malloc_and_get_section (abfd
, str_asect
, &str_bcontents
))
182 strtab
= (const char *) str_bcontents
;
183 strtab_alloc
= (char *) str_bcontents
;
184 strsize
= str_asect
->size
;
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. */
195 strsect
.cts_data
= strtab
;
196 strsect
.cts_name
= strtab_name
;
197 strsect
.cts_size
= strsize
;
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
;
211 symsect_endianness
= bfd_little_endian (abfd
);
214 arci
= ctf_arc_bufopen (ctfsect
, symsectp
, strsectp
, errp
);
217 /* Request freeing of the symsect and possibly the strsect. */
218 arci
->ctfi_free_symsect
= 1;
220 arci
->ctfi_free_strsect
= 1;
222 /* Get the endianness right. */
223 if (symsect_endianness
> -1)
224 ctf_arc_symsect_endianness (arci
, symsect_endianness
);
232 err
: _libctf_unused_
;
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
);
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. */
249 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
258 ctf_preamble_t ctfhdr
;
261 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
265 if (fstat (fd
, &st
) == -1)
266 return (ctf_set_open_errno (errp
, errno
));
268 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
269 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
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
275 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
276 && (ctfhdr
.ctp_magic
== CTF_MAGIC
277 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
279 ctf_dict_t
*fp
= NULL
;
282 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
283 return (ctf_set_open_errno (errp
, errno
));
285 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
286 NULL
, 0, errp
)) == NULL
)
288 ctf_munmap (data
, (size_t) st
.st_size
);
289 return NULL
; /* errno is set for us. */
292 fp
->ctf_data_mmapped
= data
;
293 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
295 return ctf_new_archive_internal (0, 1, NULL
, fp
, NULL
, NULL
, errp
);
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
));
301 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
303 struct ctf_archive
*arc
;
305 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
306 return NULL
; /* errno is set for us. */
308 return ctf_new_archive_internal (1, 1, arc
, NULL
, NULL
, NULL
, errp
);
311 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
312 takes ownership of the passed fd. */
314 if ((nfd
= dup (fd
)) < 0)
315 return (ctf_set_open_errno (errp
, errno
));
317 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
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
));
324 bfd_set_cacheable (abfd
, 1);
326 if (!bfd_check_format (abfd
, bfd_object
))
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
));
334 return (ctf_set_open_errno (errp
, ECTF_FMT
));
337 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
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. */
344 arci
->ctfi_bfd_close
= ctf_bfdclose
;
345 arci
->ctfi_abfd
= abfd
;
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. */
355 ctf_open (const char *filename
, const char *target
, int *errp
)
360 if ((fd
= open (filename
, O_RDONLY
)) == -1)
367 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
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. */
376 ctf_arc_open (const char *filename
, int *errp
)
378 return ctf_open (filename
, NULL
, errp
);