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
= &elf_symtab_hdr (abfd
);
105 Elf_Internal_Sym
*isymbuf
;
106 bfd_byte
*symtab
= NULL
;
107 const char *strtab
= NULL
;
109 /* TODO: handle SYMTAB_SHNDX. */
111 /* Get the symtab, and the strtab associated with it. */
112 if (elf_tdata (abfd
) && symhdr
&& symhdr
->sh_size
&& symhdr
->sh_entsize
)
114 symcount
= symhdr
->sh_size
/ symhdr
->sh_entsize
;
115 if ((symtab
= malloc (symhdr
->sh_size
)) == NULL
)
117 bfderrstr
= N_("cannot malloc symbol table");
121 isymbuf
= bfd_elf_get_elf_syms (abfd
, symhdr
, symcount
, 0,
126 bfderrstr
= N_("cannot read symbol table");
130 if (elf_elfsections (abfd
) != NULL
131 && symhdr
->sh_link
< elf_numsections (abfd
))
133 Elf_Internal_Shdr
*strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
135 strsize
= strhdr
->sh_size
;
136 if (strhdr
->contents
== NULL
)
138 if ((strtab
= bfd_elf_get_str_section (abfd
, symhdr
->sh_link
)) == NULL
)
140 bfderrstr
= N_("cannot read string table");
145 strtab
= (const char *) strhdr
->contents
;
148 else /* No symtab: just try getting .strtab by name. */
150 bfd_byte
*str_bcontents
;
153 if ((str_asect
= bfd_get_section_by_name (abfd
, ".strtab")) != NULL
)
155 if (bfd_malloc_and_get_section (abfd
, str_asect
, &str_bcontents
))
157 strtab
= (const char *) str_bcontents
;
158 strtab_alloc
= (char *) str_bcontents
;
159 strsize
= str_asect
->size
;
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. */
170 strsect
.cts_data
= strtab
;
171 strsect
.cts_name
= ".strtab";
172 strsect
.cts_size
= strsize
;
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
;
187 arci
= ctf_arc_bufopen (ctfsect
, symsectp
, strsectp
, errp
);
190 /* Request freeing of the symsect and possibly the strsect. */
191 arci
->ctfi_free_symsect
= 1;
193 arci
->ctfi_free_strsect
= 1;
201 err
: _libctf_unused_
;
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
);
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. */
218 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
227 ctf_preamble_t ctfhdr
;
230 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
234 if (fstat (fd
, &st
) == -1)
235 return (ctf_set_open_errno (errp
, errno
));
237 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
238 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
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
244 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
245 && (ctfhdr
.ctp_magic
== CTF_MAGIC
246 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
248 ctf_file_t
*fp
= NULL
;
251 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
252 return (ctf_set_open_errno (errp
, errno
));
254 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
255 NULL
, 0, errp
)) == NULL
)
257 ctf_munmap (data
, (size_t) st
.st_size
);
258 return NULL
; /* errno is set for us. */
261 fp
->ctf_data_mmapped
= data
;
262 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
264 return ctf_new_archive_internal (0, 1, NULL
, fp
, NULL
, NULL
, errp
);
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
));
270 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
272 struct ctf_archive
*arc
;
274 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
275 return NULL
; /* errno is set for us. */
277 return ctf_new_archive_internal (1, 1, arc
, NULL
, NULL
, NULL
, errp
);
280 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
281 takes ownership of the passed fd. */
283 if ((nfd
= dup (fd
)) < 0)
284 return (ctf_set_open_errno (errp
, errno
));
286 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
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
));
293 bfd_set_cacheable (abfd
, 1);
295 if (!bfd_check_format (abfd
, bfd_object
))
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
));
303 return (ctf_set_open_errno (errp
, ECTF_FMT
));
306 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
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. */
313 arci
->ctfi_bfd_close
= ctf_bfdclose
;
314 arci
->ctfi_abfd
= abfd
;
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. */
324 ctf_open (const char *filename
, const char *target
, int *errp
)
329 if ((fd
= open (filename
, O_RDONLY
)) == -1)
336 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
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. */
345 ctf_arc_open (const char *filename
, int *errp
)
347 return ctf_open (filename
, NULL
, errp
);