1 /* Opening CTF files with BFD.
2 Copyright (C) 2019-2020 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
;
102 ctf_sect_t symsect
, strsect
;
103 Elf_Internal_Shdr
*symhdr
;
105 Elf_Internal_Sym
*isymbuf
;
106 bfd_byte
*symtab
= NULL
;
107 const char *symtab_name
;
108 const char *strtab
= NULL
;
109 const char *strtab_name
;
111 const ctf_preamble_t
*preamble
;
113 if (ctfsect
->cts_data
== NULL
)
115 bfderrstr
= N_("CTF section is NULL");
118 preamble
= ctf_arc_bufpreamble (ctfsect
);
120 if (preamble
->ctp_flags
& CTF_F_DYNSTR
)
122 symhdr
= &elf_tdata (abfd
)->dynsymtab_hdr
;
123 strtab_name
= ".dynstr";
124 symtab_name
= ".dynsym";
128 symhdr
= &elf_tdata (abfd
)->symtab_hdr
;
129 strtab_name
= ".strtab";
130 symtab_name
= ".symtab";
133 /* TODO: handle SYMTAB_SHNDX. */
135 /* Get the symtab, and the strtab associated with it. */
136 if (elf_tdata (abfd
) && symhdr
&& symhdr
->sh_size
&& symhdr
->sh_entsize
)
138 symcount
= symhdr
->sh_size
/ symhdr
->sh_entsize
;
139 if ((symtab
= malloc (symhdr
->sh_size
)) == NULL
)
141 bfderrstr
= N_("cannot malloc symbol table");
145 isymbuf
= bfd_elf_get_elf_syms (abfd
, symhdr
, symcount
, 0,
150 bfderrstr
= N_("cannot read symbol table");
154 if (elf_elfsections (abfd
) != NULL
155 && symhdr
->sh_link
< elf_numsections (abfd
))
157 Elf_Internal_Shdr
*strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
159 strsize
= strhdr
->sh_size
;
160 if (strhdr
->contents
== NULL
)
162 if ((strtab
= bfd_elf_get_str_section (abfd
, symhdr
->sh_link
)) == NULL
)
164 bfderrstr
= N_("cannot read string table");
169 strtab
= (const char *) strhdr
->contents
;
172 else /* No symtab: just try getting .strtab or .dynstr by name. */
174 bfd_byte
*str_bcontents
;
177 if ((str_asect
= bfd_get_section_by_name (abfd
, strtab_name
)) != NULL
)
179 if (bfd_malloc_and_get_section (abfd
, str_asect
, &str_bcontents
))
181 strtab
= (const char *) str_bcontents
;
182 strtab_alloc
= (char *) str_bcontents
;
183 strsize
= str_asect
->size
;
190 /* The names here are more or less arbitrary, but there is no point
191 thrashing around digging the name out of the shstrtab given that we don't
192 use it for anything but debugging. */
194 strsect
.cts_data
= strtab
;
195 strsect
.cts_name
= strtab_name
;
196 strsect
.cts_size
= strsize
;
202 assert (symhdr
->sh_entsize
== get_elf_backend_data (abfd
)->s
->sizeof_sym
);
203 symsect
.cts_name
= symtab_name
;
204 symsect
.cts_entsize
= symhdr
->sh_entsize
;
205 symsect
.cts_size
= symhdr
->sh_size
;
206 symsect
.cts_data
= symtab
;
211 arci
= ctf_arc_bufopen (ctfsect
, symsectp
, strsectp
, errp
);
214 /* Request freeing of the symsect and possibly the strsect. */
215 arci
->ctfi_free_symsect
= 1;
217 arci
->ctfi_free_strsect
= 1;
225 err
: _libctf_unused_
;
228 ctf_err_warn (NULL
, 0, 0, "ctf_bfdopen(): %s: %s", gettext (bfderrstr
),
229 bfd_errmsg (bfd_get_error()));
230 ctf_set_open_errno (errp
, ECTF_FMT
);
235 /* Open the specified file descriptor and return a pointer to a CTF archive that
236 contains one or more CTF dicts. The file can be an ELF file, a file
237 containing raw CTF, or a CTF archive. The caller is responsible for closing
238 the file descriptor when it is no longer needed. If this is an ELF file,
239 TARGET, if non-NULL, should be the name of a suitable BFD target. */
242 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
251 ctf_preamble_t ctfhdr
;
254 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
258 if (fstat (fd
, &st
) == -1)
259 return (ctf_set_open_errno (errp
, errno
));
261 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
262 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
264 /* If we have read enough bytes to form a CTF header and the magic string
265 matches, in either endianness, attempt to interpret the file as raw
268 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
269 && (ctfhdr
.ctp_magic
== CTF_MAGIC
270 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
272 ctf_dict_t
*fp
= NULL
;
275 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
276 return (ctf_set_open_errno (errp
, errno
));
278 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
279 NULL
, 0, errp
)) == NULL
)
281 ctf_munmap (data
, (size_t) st
.st_size
);
282 return NULL
; /* errno is set for us. */
285 fp
->ctf_data_mmapped
= data
;
286 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
288 return ctf_new_archive_internal (0, 1, NULL
, fp
, NULL
, NULL
, errp
);
291 if ((nbytes
= ctf_pread (fd
, &arc_magic
, sizeof (arc_magic
), 0)) <= 0)
292 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
294 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
296 struct ctf_archive
*arc
;
298 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
299 return NULL
; /* errno is set for us. */
301 return ctf_new_archive_internal (1, 1, arc
, NULL
, NULL
, NULL
, errp
);
304 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
305 takes ownership of the passed fd. */
307 if ((nfd
= dup (fd
)) < 0)
308 return (ctf_set_open_errno (errp
, errno
));
310 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
312 ctf_err_warn (NULL
, 0, 0, _("cannot open BFD from %s: %s"),
313 filename
? filename
: _("(unknown file)"),
314 bfd_errmsg (bfd_get_error ()));
315 return (ctf_set_open_errno (errp
, ECTF_FMT
));
317 bfd_set_cacheable (abfd
, 1);
319 if (!bfd_check_format (abfd
, bfd_object
))
321 ctf_err_warn (NULL
, 0, 0, _("BFD format problem in %s: %s"),
322 filename
? filename
: _("(unknown file)"),
323 bfd_errmsg (bfd_get_error ()));
324 if (bfd_get_error() == bfd_error_file_ambiguously_recognized
)
325 return (ctf_set_open_errno (errp
, ECTF_BFD_AMBIGUOUS
));
327 return (ctf_set_open_errno (errp
, ECTF_FMT
));
330 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
332 if (!bfd_close_all_done (abfd
))
333 ctf_err_warn (NULL
, 0, 0, _("cannot close BFD: %s"),
334 bfd_errmsg (bfd_get_error ()));
335 return NULL
; /* errno is set for us. */
337 arci
->ctfi_bfd_close
= ctf_bfdclose
;
338 arci
->ctfi_abfd
= abfd
;
343 /* Open the specified file and return a pointer to a CTF dict. The file
344 can be either an ELF file or raw CTF file. This is just a convenient
345 wrapper around ctf_fdopen() for callers. */
348 ctf_open (const char *filename
, const char *target
, int *errp
)
353 if ((fd
= open (filename
, O_RDONLY
)) == -1)
360 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
365 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
366 NULL and an error in *err. Despite the fact that this uses CTF archives, it
367 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
369 ctf_arc_open (const char *filename
, int *errp
)
371 return ctf_open (filename
, NULL
, errp
);