1 /* Opening CTF files with BFD.
2 Copyright (C) 2019 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/>. */
22 #include <sys/types.h>
30 #include "ctf-endian.h"
34 /* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
35 ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT and
36 STRSECT interior on close. */
38 static struct ctf_archive_internal
*
39 ctf_new_archive_internal (int is_archive
, struct ctf_archive
*arc
,
40 ctf_file_t
*fp
, const ctf_sect_t
*symsect
,
41 const ctf_sect_t
*strsect
,
44 struct ctf_archive_internal
*arci
;
46 if ((arci
= calloc (1, sizeof (struct ctf_archive_internal
))) == NULL
)
49 ctf_arc_close_internal (arc
);
52 return (ctf_set_open_errno (errp
, errno
));
54 arci
->ctfi_is_archive
= is_archive
;
56 arci
->ctfi_archive
= arc
;
60 memcpy (&arci
->ctfi_symsect
, symsect
, sizeof (struct ctf_sect
));
62 memcpy (&arci
->ctfi_strsect
, strsect
, sizeof (struct ctf_sect
));
67 /* Free the BFD bits of a CTF file on ctf_file_close(). */
70 ctf_bfdclose (struct ctf_archive_internal
*arci
)
72 if (arci
->ctfi_abfd
!= NULL
)
73 if (!bfd_close_all_done (arci
->ctfi_abfd
))
74 ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
77 /* Open a CTF file given the specified BFD. */
80 ctf_bfdopen (struct bfd
*abfd
, int *errp
)
89 if ((ctf_asect
= bfd_get_section_by_name (abfd
, _CTF_SECTION
)) == NULL
)
91 return (ctf_set_open_errno (errp
, ECTF_NOCTFDATA
));
94 if (!bfd_malloc_and_get_section (abfd
, ctf_asect
, &contents
))
96 ctf_dprintf ("ctf_bfdopen(): cannot malloc CTF section: %s\n",
97 bfd_errmsg (bfd_get_error()));
98 return (ctf_set_open_errno (errp
, ECTF_FMT
));
101 ctfsect
.cts_name
= _CTF_SECTION
;
102 ctfsect
.cts_entsize
= 1;
103 ctfsect
.cts_size
= bfd_section_size (ctf_asect
);
104 ctfsect
.cts_data
= contents
;
106 if ((arc
= ctf_bfdopen_ctfsect (abfd
, &ctfsect
, errp
)) != NULL
)
108 arc
->ctfi_data
= (void *) ctfsect
.cts_data
;
113 return NULL
; /* errno is set for us. */
116 /* Open a CTF file given the specified BFD and CTF section (which may contain a
117 CTF archive or a file). Takes ownership of the ctfsect, and frees it
121 ctf_bfdopen_ctfsect (struct bfd
*abfd _libctf_unused_
,
122 const ctf_sect_t
*ctfsect
, int *errp
)
124 struct ctf_archive
*arc
= NULL
;
126 ctf_file_t
*fp
= NULL
;
127 ctf_sect_t
*symsectp
= NULL
;
128 ctf_sect_t
*strsectp
= NULL
;
129 const char *bfderrstr
= NULL
;
134 ctf_sect_t symsect
, strsect
;
135 /* TODO: handle SYMTAB_SHNDX. */
137 if ((sym_asect
= bfd_section_from_elf_index (abfd
,
138 elf_onesymtab (abfd
))) != NULL
)
140 Elf_Internal_Shdr
*symhdr
= &elf_symtab_hdr (abfd
);
141 asection
*str_asect
= NULL
;
144 if (symhdr
->sh_link
!= SHN_UNDEF
&&
145 symhdr
->sh_link
<= elf_numsections (abfd
))
146 str_asect
= bfd_section_from_elf_index (abfd
, symhdr
->sh_link
);
148 Elf_Internal_Shdr
*strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
150 if (sym_asect
&& str_asect
)
152 if (!bfd_malloc_and_get_section (abfd
, str_asect
, &contents
))
154 bfderrstr
= "Cannot malloc string table";
158 strsect
.cts_data
= contents
;
159 strsect
.cts_name
= (char *) strsect
.cts_data
+ strhdr
->sh_name
;
160 strsect
.cts_size
= bfd_section_size (str_asect
);
161 strsect
.cts_entsize
= strhdr
->sh_size
;
164 if (!bfd_malloc_and_get_section (abfd
, sym_asect
, &contents
))
166 bfderrstr
= "Cannot malloc symbol table";
171 symsect
.cts_name
= (char *) strsect
.cts_data
+ symhdr
->sh_name
;
172 symsect
.cts_entsize
= symhdr
->sh_size
;
173 symsect
.cts_size
= bfd_section_size (sym_asect
);
174 symsect
.cts_data
= contents
;
180 if (ctfsect
->cts_size
> sizeof (uint64_t) &&
181 ((*(uint64_t *) ctfsect
->cts_data
) == CTFA_MAGIC
))
184 if ((arc
= ctf_arc_bufopen ((void *) ctfsect
->cts_data
,
185 ctfsect
->cts_size
, errp
)) == NULL
)
191 if ((fp
= ctf_bufopen (ctfsect
, symsectp
, strsectp
, errp
)) == NULL
)
193 ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n",
198 arci
= ctf_new_archive_internal (is_archive
, arc
, fp
, symsectp
, strsectp
,
205 free ((void *) symsect
.cts_data
);
207 free ((void *) strsect
.cts_data
);
209 err
: _libctf_unused_
;
212 ctf_dprintf ("ctf_bfdopen(): %s: %s\n", bfderrstr
,
213 bfd_errmsg (bfd_get_error()));
214 ctf_set_open_errno (errp
, ECTF_FMT
);
219 /* Open the specified file descriptor and return a pointer to a CTF archive that
220 contains one or more CTF containers. The file can be an ELF file, a raw CTF
221 file, or a CTF archive. The caller is responsible for closing the file
222 descriptor when it is no longer needed. If this is an ELF file, TARGET, if
223 non-NULL, should be the name of a suitable BFD target. */
226 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
235 ctf_preamble_t ctfhdr
;
238 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
242 if (fstat (fd
, &st
) == -1)
243 return (ctf_set_open_errno (errp
, errno
));
245 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
246 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
248 /* If we have read enough bytes to form a CTF header and the magic string
249 matches, in either endianness, attempt to interpret the file as raw
252 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
253 && (ctfhdr
.ctp_magic
== CTF_MAGIC
254 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
256 ctf_file_t
*fp
= NULL
;
259 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
260 return (ctf_set_open_errno (errp
, errno
));
262 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
263 NULL
, 0, errp
)) == NULL
)
265 ctf_munmap (data
, (size_t) st
.st_size
);
266 return NULL
; /* errno is set for us. */
269 fp
->ctf_data_mmapped
= data
;
270 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
272 return ctf_new_archive_internal (0, NULL
, fp
, NULL
, NULL
, errp
);
275 if ((nbytes
= ctf_pread (fd
, &arc_magic
, sizeof (arc_magic
), 0)) <= 0)
276 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
278 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
280 struct ctf_archive
*arc
;
282 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
283 return NULL
; /* errno is set for us. */
285 return ctf_new_archive_internal (1, arc
, NULL
, NULL
, NULL
, errp
);
288 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
289 takes ownership of the passed fd. */
291 if ((nfd
= dup (fd
)) < 0)
292 return (ctf_set_open_errno (errp
, errno
));
294 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
296 ctf_dprintf ("Cannot open BFD from %s: %s\n",
297 filename
? filename
: "(unknown file)",
298 bfd_errmsg (bfd_get_error()));
299 return (ctf_set_open_errno (errp
, ECTF_FMT
));
302 if (!bfd_check_format (abfd
, bfd_object
))
304 ctf_dprintf ("BFD format problem in %s: %s\n",
305 filename
? filename
: "(unknown file)",
306 bfd_errmsg (bfd_get_error()));
307 if (bfd_get_error() == bfd_error_file_ambiguously_recognized
)
308 return (ctf_set_open_errno (errp
, ECTF_BFD_AMBIGUOUS
));
310 return (ctf_set_open_errno (errp
, ECTF_FMT
));
313 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
315 if (!bfd_close_all_done (abfd
))
316 ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
317 return NULL
; /* errno is set for us. */
319 arci
->ctfi_bfd_close
= ctf_bfdclose
;
320 arci
->ctfi_abfd
= abfd
;
325 /* Open the specified file and return a pointer to a CTF container. The file
326 can be either an ELF file or raw CTF file. This is just a convenient
327 wrapper around ctf_fdopen() for callers. */
330 ctf_open (const char *filename
, const char *target
, int *errp
)
335 if ((fd
= open (filename
, O_RDONLY
)) == -1)
342 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
347 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
348 NULL and an error in *err. Despite the fact that this uses CTF archives, it
349 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
351 ctf_arc_open (const char *filename
, int *errp
)
353 return ctf_open (filename
, NULL
, errp
);