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_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
46 /* Open a CTF file given the specified BFD. */
49 ctf_bfdopen (struct bfd
*abfd
, int *errp
)
58 if ((ctf_asect
= bfd_get_section_by_name (abfd
, _CTF_SECTION
)) == NULL
)
60 return (ctf_set_open_errno (errp
, ECTF_NOCTFDATA
));
63 if (!bfd_malloc_and_get_section (abfd
, ctf_asect
, &contents
))
65 ctf_dprintf ("ctf_bfdopen(): cannot malloc CTF section: %s\n",
66 bfd_errmsg (bfd_get_error()));
67 return (ctf_set_open_errno (errp
, ECTF_FMT
));
70 ctfsect
.cts_name
= _CTF_SECTION
;
71 ctfsect
.cts_entsize
= 1;
72 ctfsect
.cts_size
= bfd_section_size (ctf_asect
);
73 ctfsect
.cts_data
= contents
;
75 if ((arc
= ctf_bfdopen_ctfsect (abfd
, &ctfsect
, errp
)) != NULL
)
77 /* This frees the cts_data later. */
78 arc
->ctfi_data
= (void *) ctfsect
.cts_data
;
83 return NULL
; /* errno is set for us. */
86 /* Open a CTF file given the specified BFD and CTF section (which may contain a
87 CTF archive or a file). */
90 ctf_bfdopen_ctfsect (struct bfd
*abfd _libctf_unused_
,
91 const ctf_sect_t
*ctfsect
, int *errp
)
94 ctf_sect_t
*symsectp
= NULL
;
95 ctf_sect_t
*strsectp
= NULL
;
96 const char *bfderrstr
= NULL
;
99 ctf_sect_t symsect
, strsect
;
100 Elf_Internal_Shdr
*strhdr
;
101 Elf_Internal_Shdr
*symhdr
= &elf_symtab_hdr (abfd
);
102 size_t symcount
= symhdr
->sh_size
/ symhdr
->sh_entsize
;
103 Elf_Internal_Sym
*isymbuf
;
105 const char *strtab
= NULL
;
106 /* TODO: handle SYMTAB_SHNDX. */
108 if ((symtab
= malloc (symhdr
->sh_size
)) == NULL
)
110 bfderrstr
= "Cannot malloc symbol table";
114 isymbuf
= bfd_elf_get_elf_syms (abfd
, symhdr
, symcount
, 0,
119 bfderrstr
= "Cannot read symbol table";
123 if (elf_elfsections (abfd
) != NULL
124 && symhdr
->sh_link
< elf_numsections (abfd
))
126 strhdr
= elf_elfsections (abfd
)[symhdr
->sh_link
];
127 if (strhdr
->contents
== NULL
)
129 if ((strtab
= bfd_elf_get_str_section (abfd
, symhdr
->sh_link
)) == NULL
)
131 bfderrstr
= "Cannot read string table";
136 strtab
= (const char *) strhdr
->contents
;
141 /* The names here are more or less arbitrary, but there is no point
142 thrashing around digging the name out of the shstrtab given that we don't
143 use it for anything but debugging. */
145 strsect
.cts_data
= strtab
;
146 strsect
.cts_name
= ".strtab";
147 strsect
.cts_size
= strhdr
->sh_size
;
150 assert (symhdr
->sh_entsize
== get_elf_backend_data (abfd
)->s
->sizeof_sym
);
151 symsect
.cts_name
= ".symtab";
152 symsect
.cts_entsize
= symhdr
->sh_entsize
;
153 symsect
.cts_size
= symhdr
->sh_size
;
154 symsect
.cts_data
= symtab
;
159 arci
= ctf_arc_bufopen (ctfsect
, symsectp
, strsectp
, errp
);
162 /* Request freeing of the symsect. */
163 arci
->ctfi_free_symsect
= 1;
170 err
: _libctf_unused_
;
173 ctf_dprintf ("ctf_bfdopen(): %s: %s\n", bfderrstr
,
174 bfd_errmsg (bfd_get_error()));
175 ctf_set_open_errno (errp
, ECTF_FMT
);
180 /* Open the specified file descriptor and return a pointer to a CTF archive that
181 contains one or more CTF containers. The file can be an ELF file, a raw CTF
182 file, or a CTF archive. The caller is responsible for closing the file
183 descriptor when it is no longer needed. If this is an ELF file, TARGET, if
184 non-NULL, should be the name of a suitable BFD target. */
187 ctf_fdopen (int fd
, const char *filename
, const char *target
, int *errp
)
196 ctf_preamble_t ctfhdr
;
199 memset (&ctfhdr
, 0, sizeof (ctfhdr
));
203 if (fstat (fd
, &st
) == -1)
204 return (ctf_set_open_errno (errp
, errno
));
206 if ((nbytes
= ctf_pread (fd
, &ctfhdr
, sizeof (ctfhdr
), 0)) <= 0)
207 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
209 /* If we have read enough bytes to form a CTF header and the magic string
210 matches, in either endianness, attempt to interpret the file as raw
213 if ((size_t) nbytes
>= sizeof (ctf_preamble_t
)
214 && (ctfhdr
.ctp_magic
== CTF_MAGIC
215 || ctfhdr
.ctp_magic
== bswap_16 (CTF_MAGIC
)))
217 ctf_file_t
*fp
= NULL
;
220 if ((data
= ctf_mmap (st
.st_size
, 0, fd
)) == NULL
)
221 return (ctf_set_open_errno (errp
, errno
));
223 if ((fp
= ctf_simple_open (data
, (size_t) st
.st_size
, NULL
, 0, 0,
224 NULL
, 0, errp
)) == NULL
)
226 ctf_munmap (data
, (size_t) st
.st_size
);
227 return NULL
; /* errno is set for us. */
230 fp
->ctf_data_mmapped
= data
;
231 fp
->ctf_data_mmapped_len
= (size_t) st
.st_size
;
233 return ctf_new_archive_internal (0, NULL
, fp
, NULL
, NULL
, errp
);
236 if ((nbytes
= ctf_pread (fd
, &arc_magic
, sizeof (arc_magic
), 0)) <= 0)
237 return (ctf_set_open_errno (errp
, nbytes
< 0 ? errno
: ECTF_FMT
));
239 if ((size_t) nbytes
>= sizeof (uint64_t) && le64toh (arc_magic
) == CTFA_MAGIC
)
241 struct ctf_archive
*arc
;
243 if ((arc
= ctf_arc_open_internal (filename
, errp
)) == NULL
)
244 return NULL
; /* errno is set for us. */
246 return ctf_new_archive_internal (1, arc
, NULL
, NULL
, NULL
, errp
);
249 /* Attempt to open the file with BFD. We must dup the fd first, since bfd
250 takes ownership of the passed fd. */
252 if ((nfd
= dup (fd
)) < 0)
253 return (ctf_set_open_errno (errp
, errno
));
255 if ((abfd
= bfd_fdopenr (filename
, target
, nfd
)) == NULL
)
257 ctf_dprintf ("Cannot open BFD from %s: %s\n",
258 filename
? filename
: "(unknown file)",
259 bfd_errmsg (bfd_get_error()));
260 return (ctf_set_open_errno (errp
, ECTF_FMT
));
262 bfd_set_cacheable (abfd
, 1);
264 if (!bfd_check_format (abfd
, bfd_object
))
266 ctf_dprintf ("BFD format problem in %s: %s\n",
267 filename
? filename
: "(unknown file)",
268 bfd_errmsg (bfd_get_error()));
269 if (bfd_get_error() == bfd_error_file_ambiguously_recognized
)
270 return (ctf_set_open_errno (errp
, ECTF_BFD_AMBIGUOUS
));
272 return (ctf_set_open_errno (errp
, ECTF_FMT
));
275 if ((arci
= ctf_bfdopen (abfd
, errp
)) == NULL
)
277 if (!bfd_close_all_done (abfd
))
278 ctf_dprintf ("Cannot close BFD: %s\n", bfd_errmsg (bfd_get_error()));
279 return NULL
; /* errno is set for us. */
281 arci
->ctfi_bfd_close
= ctf_bfdclose
;
282 arci
->ctfi_abfd
= abfd
;
287 /* Open the specified file and return a pointer to a CTF container. The file
288 can be either an ELF file or raw CTF file. This is just a convenient
289 wrapper around ctf_fdopen() for callers. */
292 ctf_open (const char *filename
, const char *target
, int *errp
)
297 if ((fd
= open (filename
, O_RDONLY
)) == -1)
304 arc
= ctf_fdopen (fd
, filename
, target
, errp
);
309 /* Public entry point: open a CTF archive, or CTF file. Returns the archive, or
310 NULL and an error in *err. Despite the fact that this uses CTF archives, it
311 must be in this file to avoid dragging in BFD into non-BFD-using programs. */
313 ctf_arc_open (const char *filename
, int *errp
)
315 return ctf_open (filename
, NULL
, errp
);