1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2024 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;
105 ctf_sect_t symsect
, strsect
;
106 Elf_Internal_Shdr
*symhdr
;
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
;
114 const ctf_preamble_t
*preamble
;
116 if (ctfsect
->cts_data
== NULL
)
118 bfderrstr
= N_("CTF section is NULL");
121 preamble
= ctf_arc_bufpreamble (ctfsect
);
123 if (preamble
->ctp_flags
& CTF_F_DYNSTR
)
125 symhdr
= &elf_tdata (abfd
)->dynsymtab_hdr
;
126 strtab_name
= ".dynstr";
127 symtab_name
= ".dynsym";
131 symhdr
= &elf_tdata (abfd
)->symtab_hdr
;
132 strtab_name
= ".strtab";
133 symtab_name
= ".symtab";
136 /* TODO: handle SYMTAB_SHNDX. */
138 /* Get the symtab, and the strtab associated with it. */
139 if (elf_tdata (abfd
) && symhdr
&& symhdr
->sh_size
&& symhdr
->sh_entsize
)
141 symcount
= symhdr
->sh_size
/ symhdr
->sh_entsize
;
142 if ((symtab
= malloc (symhdr
->sh_size
)) == NULL
)
144 bfderrstr
= N_("cannot malloc symbol table");
148 isymbuf
= bfd_elf_get_elf_syms (abfd
, symhdr
, symcount
, 0,
153 bfderrstr
= N_("cannot read symbol table");
157 if (elf_elfsections (abfd
) != NULL
158 && symhdr
->sh_link
< elf_numsections (abfd
))
160 Elf_Internal_Shdr
*strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
162 strsize
= strhdr
->sh_size
;
163 if (strhdr
->contents
== NULL
)
165 if ((strtab
= bfd_elf_get_str_section (abfd
, symhdr
->sh_link
)) == NULL
)
167 bfderrstr
= N_("cannot read string table");
172 strtab
= (const char *) strhdr
->contents
;
175 else /* No symtab: just try getting .strtab or .dynstr by name. */
177 bfd_byte
*str_bcontents
;
180 if ((str_asect
= bfd_get_section_by_name (abfd
, strtab_name
)) != NULL
)
182 if (bfd_malloc_and_get_section (abfd
, str_asect
, &str_bcontents
))
184 strtab
= (const char *) str_bcontents
;
185 strtab_alloc
= (char *) str_bcontents
;
186 strsize
= str_asect
->size
;
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. */
197 strsect
.cts_data
= strtab
;
198 strsect
.cts_name
= strtab_name
;
199 strsect
.cts_size
= strsize
;
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
;
213 symsect_endianness
= bfd_little_endian (abfd
);
216 arci
= ctf_arc_bufopen (ctfsect
, symsectp
, strsectp
, errp
);
219 /* Request freeing of the symsect and possibly the strsect. */
220 arci
->ctfi_free_symsect
= 1;
222 arci
->ctfi_free_strsect
= 1;
224 /* Get the endianness right. */
225 if (symsect_endianness
> -1)
226 ctf_arc_symsect_endianness (arci
, symsect_endianness
);
234 err
: _libctf_unused_
;
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
);
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. */
251 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
260 ctf_preamble_t ctfhdr
;
263 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
267 if (fstat (fd
, &st
) == -1)
268 return (ctf_set_open_errno (errp
, errno
));
270 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
271 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
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
277 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
278 && (ctfhdr
.ctp_magic
== CTF_MAGIC
279 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
281 ctf_dict_t
*fp
= NULL
;
284 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
285 return (ctf_set_open_errno (errp
, errno
));
287 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
288 NULL
, 0, errp
)) == NULL
)
290 ctf_munmap (data
, (size_t) st
.st_size
);
291 return NULL
; /* errno is set for us. */
294 fp
->ctf_data_mmapped
= data
;
295 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
297 return ctf_new_archive_internal (0, 1, NULL
, fp
, NULL
, NULL
, errp
);
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
));
303 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
305 struct ctf_archive
*arc
;
307 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
308 return NULL
; /* errno is set for us. */
310 return ctf_new_archive_internal (1, 1, arc
, NULL
, NULL
, NULL
, errp
);
313 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
314 takes ownership of the passed fd. */
316 if ((nfd
= dup (fd
)) < 0)
317 return (ctf_set_open_errno (errp
, errno
));
319 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
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
));
326 bfd_set_cacheable (abfd
, 1);
328 if (!bfd_check_format (abfd
, bfd_object
))
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
));
336 return (ctf_set_open_errno (errp
, ECTF_FMT
));
339 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
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. */
346 arci
->ctfi_bfd_close
= ctf_bfdclose
;
347 arci
->ctfi_abfd
= abfd
;
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. */
357 ctf_open (const char *filename
, const char *target
, int *errp
)
362 if ((fd
= open (filename
, O_RDONLY
)) == -1)
369 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
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. */
378 ctf_arc_open (const char *filename
, int *errp
)
380 return ctf_open (filename
, NULL
, errp
);