diff --git a/binutils/objdump.c b/binutils/objdump.c index c8d32c8b3c6..9b5c1db928c 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -4784,13 +4784,13 @@ dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED, return xasprintf ("%s%s", blanks, s); } -/* Make a ctfsect suitable for ctf_bfdopen_ctfsect(). */ +/* Make a ctfsect suitable for ctf_bfdopen(). */ static ctf_sect_t -make_ctfsect (const char *name, bfd_byte *data, - bfd_size_type size) +make_ctfsect (const char *name, bfd_byte *data, bfd_size_type size) { - ctf_sect_t ctfsect; + ctf_sect_t ctfsect = {0}; + ctfsect.cts_section = CTF_ELF_SECT; ctfsect.cts_name = name; ctfsect.cts_entsize = 1; ctfsect.cts_size = size; @@ -4913,7 +4913,7 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name, from a different section entirely. */ ctfsect = make_ctfsect (sect_name, ctfdata, bfd_section_size (sec)); - if ((ctfa = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL) + if ((ctfa = ctf_bfdopen (abfd, ctf_open_sect (NULL, &ctfsect), &err)) == NULL) { dump_ctf_errs (NULL); non_fatal (_("CTF open failure: %s"), ctf_errmsg (err)); @@ -4932,8 +4932,10 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name, return; } - ctfsect = make_ctfsect (parent_sect_name, ctfpdata, bfd_section_size (psec)); - if ((ctfpa = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL) + ctfsect = make_ctfsect (parent_sect_name, ctfpdata, + bfd_section_size (psec)); + if ((ctfpa = ctf_bfdopen (abfd, ctf_open_sect (NULL, &ctfsect), + &err)) == NULL) { dump_ctf_errs (NULL); non_fatal (_("CTF open failure: %s"), ctf_errmsg (err)); diff --git a/binutils/readelf.c b/binutils/readelf.c index 21f3be865c6..5fa255b0417 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -17331,8 +17331,10 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, #ifdef ENABLE_LIBCTF static ctf_sect_t * -shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata) +shdr_to_ctf_sect (ctf_sect_t *buf, ctf_elfsect_names_t sect, + Elf_Internal_Shdr *shdr, Filedata *filedata) { + buf->cts_section = sect; buf->cts_name = printable_section_name (filedata, shdr); buf->cts_size = shdr->sh_size; buf->cts_entsize = shdr->sh_entsize; @@ -17427,7 +17429,7 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) void * data = NULL; void * symdata = NULL; void * strdata = NULL; - ctf_sect_t ctfsect, symsect, strsect; + ctf_sect_t ctfsect = {0}, symsect = {0}, strsect = {0}; ctf_sect_t * symsectp = NULL; ctf_sect_t * strsectp = NULL; ctf_archive_t * ctfa = NULL; @@ -17440,7 +17442,7 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) ctf_error_t err; bool ret = false; - shdr_to_ctf_sect (&ctfsect, section, filedata); + shdr_to_ctf_sect (&ctfsect, CTF_ELF_SECT, section, filedata); data = get_section_contents (section, filedata); ctfsect.cts_data = data; @@ -17462,7 +17464,8 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) symtab_sec->sh_size, _("symbols"))) == NULL) goto fail; - symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata); + symsectp = shdr_to_ctf_sect (&symsect, CTF_ELF_SYMSECT, symtab_sec, + filedata); symsect.cts_data = symdata; } @@ -17479,7 +17482,8 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) strtab_sec->sh_size, _("strings"))) == NULL) goto fail; - strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata); + strsectp = shdr_to_ctf_sect (&strsect, CTF_ELF_STRSECT, strtab_sec, + filedata); strsect.cts_data = strdata; } @@ -17487,7 +17491,8 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata) archive: libctf papers over the difference, so we can pretend it is always an archive. */ - if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL) + if ((ctfa = ctf_arc_bufopen (ctf_open_sect (ctf_open_sect (ctf_open_sect (NULL, + &ctfsect), symsectp), strsectp), &err)) == NULL) { dump_ctf_errs (NULL); error (_("CTF open failure: %s\n"), ctf_errmsg (err)); diff --git a/gdb/ctfread.c b/gdb/ctfread.c index 936929de384..1067f5982af 100644 --- a/gdb/ctfread.c +++ b/gdb/ctfread.c @@ -1468,7 +1468,7 @@ elfctf_build_psymtabs (struct objfile *of) const char *name; ctf_error_t err; - ctf_archive_t *arc = ctf_bfdopen (abfd, &err); + ctf_archive_t *arc = ctf_bfdopen (abfd, NULL, &err); if (arc == nullptr) error (_("ctf_bfdopen failed on %s - %s"), bfd_get_filename (abfd), ctf_errmsg (err)); diff --git a/include/ctf-api.h b/include/ctf-api.h index a69dd814df3..741aa36859b 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -78,21 +78,51 @@ typedef int ctf_error_t; struct bfd; +/* Symbolic names for CTF sections. */ + +typedef enum ctf_sect_names + { + CTF_SECT_HEADER, + CTF_SECT_OBJT, + CTF_SECT_OBJTIDX = CTF_SECT_OBJT, + CTF_SECT_FUNC, + CTF_SECT_FUNCIDX = CTF_SECT_FUNC, + CTF_SECT_VAR, + CTF_SECT_TYPE, + CTF_SECT_STR + } ctf_sect_names_t; + +/* Symbolic names for ELF sections associated with CTF. */ +typedef enum ctf_elfsect_names + { + CTF_ELF_SECT, /* The .ctf section. */ + CTF_ELF_SYMSECT, /* The associated symtab. */ + CTF_ELF_STRSECT, /* The ELF string table. */ + } ctf_elfsect_names_t; + /* If the debugger needs to provide the CTF library with a set of raw buffers for use as the CTF data, symbol table, and string table, it can do so by - filling in ctf_sect_t structures and passing them to ctf_bufopen. + filling in ctf_sect_t structures and passing them to ctf_bufopen et al via + the ctf_open_sect_t function. - The contents of this structure must always be in native endianness. At read - time, the symbol table endianness is derived from the BFD target (if BFD is - in use): if a BFD target is not in use, please call ctf_symsect_endianness or - ctf_arc_symsect_endianness. */ + At read time, the symbol table endianness is derived from the BFD target (if + BFD is in use): if a BFD target is not in use, please call + ctf_symsect_endianness or ctf_arc_symsect_endianness. */ typedef struct ctf_sect { + /* Used by ctf_open_sect et al. Must be zero-initialized. */ + struct + { + void *reserved1; + void *reserved2; + } reserved; + + ctf_elfsect_names_t cts_section; /* ELF section this corresponds to. */ const char *cts_name; /* Section name (if any). */ const void *cts_data; /* Pointer to section data. */ size_t cts_size; /* Size of data in bytes. */ - size_t cts_entsize; /* Size of each section entry (symtab only). */ + size_t cts_entsize; /* Size of each section entry (symtab only). */ } ctf_sect_t; /* A minimal symbol extracted from a linker's internal symbol table @@ -161,28 +191,6 @@ enum ctf_link_flags typedef int ctf_link_flags_t; #endif -/* Symbolic names for CTF sections. */ - -typedef enum ctf_sect_names - { - CTF_SECT_HEADER, - CTF_SECT_OBJT, - CTF_SECT_OBJTIDX = CTF_SECT_OBJT, - CTF_SECT_FUNC, - CTF_SECT_FUNCIDX = CTF_SECT_FUNC, - CTF_SECT_VAR, - CTF_SECT_TYPE, - CTF_SECT_STR - } ctf_sect_names_t; - -/* Symbolic names for ELF sections associated with CTF. */ -typedef enum ctf_elfsect_names - { - CTF_ELF_SECT, /* The .ctf section. */ - CTF_ELF_SYMSECT, /* The associated symtab. */ - CTF_ELF_STRSECT, /* The ELF string table. */ - } ctf_elfsect_names_t; - /* Encoding information for integers, floating-point values, and certain other intrinsics can be obtained by calling ctf_type_encoding, below. The flags field will contain values appropriate for the type defined in . @@ -288,7 +296,7 @@ typedef int ctf_func_type_flags_t; _CTF_ITEM (ECTF_SYMBAD, "symbol table data buffer is not valid") \ _CTF_ITEM (ECTF_STRBAD, "string table data buffer is not valid") \ _CTF_ITEM (ECTF_CORRUPT, "file data structure corruption detected") \ - _CTF_ITEM (ECTF_NOCTFDATA, "file does not contain CTF data") \ + _CTF_ITEM (ECTF_NOCTFDATA, "no .ctf or .BTF section") \ _CTF_ITEM (ECTF_NOCTFBUF, "buffer does not contain CTF data") \ _CTF_ITEM (ECTF_NOSYMTAB, "symbol table information is not available") \ _CTF_ITEM (ECTF_NOPARENT, "the parent CTF dictionary is needed but unavailable") \ @@ -445,12 +453,37 @@ extern ctf_next_t *ctf_next_copy (ctf_next_t *); All these functions except for ctf_close use BFD and can open anything BFD can open, hunting down the .ctf section for you, so are not available in the - libctf-nobfd flavour of the library. If you want to provide the CTF section - yourself, you can do that with ctf_bfdopen_ctfsect. */ + libctf-nobfd flavour of the library. If you want to provide some sections + yourself, you can do that using the optional ctf_open_sect_t argument to + ctf_bfdopen. -extern ctf_archive_t *ctf_bfdopen (struct bfd *, ctf_error_t *); -extern ctf_archive_t *ctf_bfdopen_ctfsect (struct bfd *, const ctf_sect_t *, - ctf_error_t *); + Some of these functions take a list of sections, constructed by the + ctf_open_sect function, which chains together ctf_open_sect_t structs (pass + the return value of each into the next call). These other sections are + optional and usually consist of symtab, strtab, and symtypetab sections. If + you don't pass the right sections in (usually symtypetab and associated + string and symbol tables linked via sh_link), opening will succeed but things + like symbol->type lookup will not be available, and the ctf_*_lookup_symbol + functions will fail with ECTF_NOSYMTAB. The structures returned by + ctf_open_sect are consumed by the open functions and should not be used + again. The ctf_sect_t's passed in, and the buffers they wrap, are still + owned by the caller; the ctf_sect_t's can be freed, but the buffers are in + use: do not free them until the archive, and all dicts derived from it, are + closed. + + We do not define what happens if you pass in multiple sections of the same + type in ctf_open_sect (this is to enable us to define useful behaviour in the + future if need be). + + ctf_open_sect cannot fail and can be called in a nested fashion in the + argument list of functions taking a ctf_open_sect_t to pass in multiple + sections easily. */ + +typedef struct ctf_open_sect ctf_open_sect_t; +extern ctf_open_sect_t *ctf_open_sect (ctf_open_sect_t *, ctf_sect_t *); + +extern ctf_archive_t *ctf_bfdopen (struct bfd *, ctf_open_sect_t *, + ctf_error_t *); extern ctf_archive_t *ctf_fdopen (int fd, const char *filename, const char *target, ctf_error_t *); extern ctf_archive_t *ctf_open (const char *filename, @@ -483,24 +516,11 @@ extern void ctf_arc_symsect_endianness (ctf_archive_t *, int little_endian); Almost all functions that open archives will also open raw CTF dicts, which are treated as if they were archives with only one member. - Some of these functions take optional raw symtab and strtab section content - in the form of ctf_sect_t structures. For CTF in ELF files, the more - convenient opening functions above extract these .dynsym and its associated - string table (usually .dynsym) whenever the CTF_F_DYNSTR flag is set in the - CTF preamble (which it almost always will be for linked objects, but not for - .o files). If you use ctf_arc_bufopen and do not specify symbol/string - tables, the ctf_*_lookup_symbol functions will fail with ECTF_NOSYMTAB. - Do not free the buffers passed to ctf_arc_bufopen until the archive, and - all dicts derived from it, are closed. - Like many other convenient opening functions, ctf_arc_open needs BFD and is not available in libctf-nobfd. */ extern ctf_archive_t *ctf_arc_open (const char *, ctf_error_t *); -extern ctf_archive_t *ctf_arc_bufopen (const ctf_sect_t *ctfsect, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, - ctf_error_t *); +extern ctf_archive_t *ctf_arc_bufopen (ctf_open_sect_t *, ctf_error_t *); extern void ctf_arc_close (ctf_archive_t *); /* Get boolean properties of an archive. Only one property is defined so far: a @@ -588,7 +608,7 @@ extern void ctf_arc_flush_caches (ctf_archive_t *); /* The next functions return or close real CTF files, not archives or ELF files containing CTF content. They can be passed symbol and string table sections - if need be. + if need be. (A sect of type CTF_ELF_SECT is obviously mandatory.) Unlike ctf_dict_open et al above, these low-level functions expose the parent/child relationship between CTF dicts (ctf_dict_open* opens parents as @@ -610,9 +630,7 @@ extern void ctf_arc_flush_caches (ctf_archive_t *); something other than input object files, see ctf_link_add_cu_mapping and CTF_LINK_SHARE_*. */ -extern ctf_dict_t *ctf_bufopen (const ctf_sect_t *ctfsect, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ctf_dict_t *parent, +extern ctf_dict_t *ctf_bufopen (ctf_open_sect_t *sects, ctf_dict_t *parent, ctf_error_t *); extern void ctf_dict_close (ctf_dict_t *); diff --git a/include/ctf-test-api.h b/include/ctf-test-api.h deleted file mode 100644 index ba3bbfdf8de..00000000000 --- a/include/ctf-test-api.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Testsuite-internal API to libctf. - Copyright (C) 2025 Free Software Foundation, Inc. - - This file is part of libctf. - - libctf is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not see - . */ - -/* This header file defines the interfaces available from the CTF debugger - library, libctf. This API can be used by a debugger to operate on data in - the Compact ANSI-C Type Format (CTF). */ - -#ifndef _CTF_TEST_API_H -#define _CTF_TEST_API_H - -#include - -extern ctf_dict_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size, - const char *symsect, size_t symsect_size, - size_t symsect_entsize, - const char *strsect, size_t strsect_size, - ctf_dict_t *parent, ctf_error_t *errp); - -#endif /* _CTF_TEST_API_H */ diff --git a/ld/ldlang.c b/ld/ldlang.c index a5b546c2e21..c1ee19611ed 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3849,7 +3849,7 @@ ldlang_open_ctf (void) wrapper): files derived from a previous relocatable link have a CTF archive containing possibly many CTF files. */ - if ((file->the_ctf = ctf_bfdopen (file->the_bfd, &err)) == NULL) + if ((file->the_ctf = ctf_bfdopen (file->the_bfd, NULL, &err)) == NULL) { if (err != ECTF_NOCTFDATA) { diff --git a/libctf/Makefile.am b/libctf/Makefile.am index 491a5ce133b..23787750f2d 100644 --- a/libctf/Makefile.am +++ b/libctf/Makefile.am @@ -124,6 +124,6 @@ EXTRA_DEJAGNU_SITE_CONFIG = development.exp DISTCLEANFILES += site.exp development.exp -EXTRA_DIST = libtool-version libctf.ver $(INCDIR)/ctf-test-api.h +EXTRA_DIST = libtool-version libctf.ver include doc/local.mk diff --git a/libctf/Makefile.in b/libctf/Makefile.in index 1b13bc8ccf8..61805451965 100644 --- a/libctf/Makefile.in +++ b/libctf/Makefile.in @@ -647,7 +647,7 @@ CC_FOR_TARGET = ` \ # development.sh is used to determine -Werror default. CONFIG_STATUS_DEPENDENCIES = $(BFDDIR)/development.sh EXTRA_DEJAGNU_SITE_CONFIG = development.exp -EXTRA_DIST = libtool-version libctf.ver $(INCDIR)/ctf-test-api.h +EXTRA_DIST = libtool-version libctf.ver @BUILD_INFO_TRUE@AM_MAKEINFOFLAGS = --no-split all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index f6cefe1aa2b..700c881e92d 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -618,14 +618,16 @@ ctf_arc_find_magic (unsigned char *buf, size_t len, int *strtab) contain a ctf_archive) or a single ctf_dict: endian-swap the archive header as necessary, and check all its offsets for validity. Close/optionally unmap BUF and/or FP on error. Arrange to free or unmap - the SYMSECT or STRSECT, as needed, on close. */ + any passed-in symbol or string sections on close. The CTF section in the + passed-in SECTS is ignored: it's assumed to already be passed in as BUF. */ struct ctf_archive_internal * ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, enum arc_on_close_operation on_close, - size_t len, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ctf_error_t *errp) + size_t len, ctf_open_sect_t *sects, + ctf_error_t *errp) { + ctf_sect_t *strsect = NULL, *symsect = NULL; struct ctf_archive_internal *arci = NULL; size_t ufsize; ctf_error_t err = 0; @@ -772,7 +774,7 @@ ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, while ((magic = ctf_arc_find_magic (p, MIN (65, len - (p - buf)), &strtab)) != NULL) { ssize_t dict_len; - ctf_sect_t tmp; + ctf_sect_t tmp = {0}; if (strtab) break; @@ -780,10 +782,9 @@ ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, p = magic; arci->ctfi_members[i] = (p - buf); - memset (&tmp, 0, sizeof (ctf_sect_t)); tmp.cts_size = len - (p - buf); /* (upper bound) */ tmp.cts_data = p; - if ((dict_len = ctf_buflen (&tmp, &err)) < 0) + if ((dict_len = ctf_buflen (ctf_open_sect (NULL, &tmp), &err)) < 0) { ctf_set_open_errno (errp, err); ctf_err (err_locus (NULL), err, @@ -879,10 +880,28 @@ ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, goto err_set; } + if (sects) + { + ctf_sect_t *sect = (ctf_sect_t *) sects; + + do + { + switch (sect->cts_section) + { + case CTF_ELF_SYMSECT: symsect = sect; break; + case CTF_ELF_STRSECT: strsect = sect; break; + default: + ; + } + sect = ctf_list_next (sect); + } while (sect); + } + if (symsect) - memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect)); + memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect)); if (strsect) - memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect)); + memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect)); + arci->ctfi_free_symsect = 0; arci->ctfi_free_strsect = 0; arci->ctfi_symsect_little_endian = -1; @@ -915,12 +934,11 @@ ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, is. */ struct ctf_archive_internal * -ctf_new_archive_wrapper (ctf_dict_t *fp, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ctf_error_t *errp) +ctf_new_archive_wrapper (ctf_dict_t *fp, ctf_open_sect_t *sects, ctf_error_t *errp) { struct ctf_archive_internal *arci; if ((arci = ctf_new_archive_internal (NULL, fp, 0, FREE_ARCHIVE_ON_DICT_CLOSE, - 0, symsect, strsect, errp)) != NULL) + 0, sects, errp)) != NULL) arci->ctfi_symsect_little_endian = fp->ctf_symsect_little_endian; return arci; } @@ -944,7 +962,7 @@ ctf_sect_t ctf_arc_elf_sect (const struct ctf_archive_internal *arci, ctf_elfsect_names_t sect) { - ctf_sect_t error = { "ERROR", NULL, 0, 0 }; + ctf_sect_t error = { {0}, 0, "ERROR", NULL, 0, 0 }; if (arci->ctfi_dict) return ctf_elf_sect (arci->ctfi_dict, sect); @@ -1000,11 +1018,26 @@ ctf_arc_bufpreamble_v1 (const ctf_sect_t *ctfsect) preserve until ctf_arc_close() time). Returns the archive, or NULL and an error in *err (if not NULL). */ ctf_archive_t * -ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ctf_error_t *errp) +ctf_arc_bufopen (ctf_open_sect_t *sects, ctf_error_t *errp) { + ctf_sect_t *sect = (ctf_sect_t *) sects; + ctf_sect_t *ctfsect = NULL; + int v1 = 0; + if (sect == NULL) + return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); + + do + { + if (sect->cts_section == CTF_ELF_SECT) + ctfsect = sect; + sect = ctf_list_next (sect); + } while (sect); + + if (ctfsect == NULL) + return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); + if (ctfsect->cts_data != NULL && ctfsect->cts_size > sizeof (uint64_t) && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_V1_MAGIC)) @@ -1012,7 +1045,7 @@ ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, return ctf_new_archive_internal ((unsigned char *) ctfsect->cts_data, NULL, v1, FREE_ARCHIVE_ONLY_DICT, ctfsect->cts_size, - symsect, strsect, errp); + sects, errp); } /* Open a CTF archive from a given fd. Returns the archive (wrapper), or @@ -1064,7 +1097,7 @@ ctf_arc_open_internal (int fd, const char *filename, ctf_error_t *errp) v1 = 1; ret = ctf_new_archive_internal (content, NULL, v1, close_op, s.st_size, - NULL, NULL, errp); + NULL, errp); /* ctf_new_archive_internal cleans up on error, so shouldn't do so. */ return ret; @@ -1210,28 +1243,21 @@ ctf_arc_set_parent (struct ctf_archive_internal *arci, ctf_dict_t *parent) if non-NULL. */ static ctf_dict_t * ctf_dict_open_by_offset (struct ctf_archive_internal *arci, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, size_t offset, - size_t len, ctf_dict_t *parent, - int little_endian_symtab, ctf_error_t *errp) + ctf_open_sect_t *sects, size_t offset, size_t len, + ctf_dict_t *parent, int little_endian_symtab, + ctf_error_t *errp) { - ctf_sect_t ctfsect; + ctf_sect_t ctfsect = {0}; ctf_dict_t *fp; ctf_dprintf ("ctf_dict_open_by_offset(%zi): opening\n", offset); - if (symsect->cts_name == NULL) - symsect = NULL; - if (strsect->cts_name == NULL) - strsect = NULL; - - memset (&ctfsect, 0, sizeof (ctf_sect_t)); - /* Offsets in v1 are relative to the ctfs header offset. In v2 they are simply file offsets. */ if (arci->ctfi_v1_hdr) offset += arci->ctfi_v1_hdr->ctfs; + ctfsect.cts_section = CTF_ELF_SECT; ctfsect.cts_name = _CTF_SECTION; ctfsect.cts_entsize = 1; ctfsect.cts_data = (void *) (&arci->ctfi_archive[offset]); @@ -1241,7 +1267,7 @@ ctf_dict_open_by_offset (struct ctf_archive_internal *arci, if (arci->ctfi_v1_hdr) ctfsect.cts_data = (void *) (&arci->ctfi_archive[offset] + sizeof (uint64_t)); - fp = ctf_bufopen_len (&ctfsect, symsect, strsect, NULL, parent, arci, + fp = ctf_bufopen_len (ctf_open_sect (sects, &ctfsect), NULL, parent, arci, 0, errp); if (!fp) return NULL; /* errno is set for us. */ @@ -1285,6 +1311,8 @@ ctf_dict_open_by_index (struct ctf_archive_internal *arci, size_t index, { ctf_dict_t *fp; ctf_dict_t *parent = arci->ctfi_parent; + ctf_sect_t symsect, strsect; + ctf_sect_t *symsectp = NULL, *strsectp = NULL; size_t len; if (index >= arci->ctfi_nmemb) @@ -1312,8 +1340,21 @@ ctf_dict_open_by_index (struct ctf_archive_internal *arci, size_t index, } len = ctf_arc_get_dict_len (arci, index); - fp = ctf_dict_open_by_offset (arci, &arci->ctfi_symsect, - &arci->ctfi_strsect, + + /* Take a copy of the ctf_sect_t's out of the way to keep the list chaining + done by ctf_open_sect from persisting or crossing threads unpleasantly. */ + if (arci->ctfi_symsect.cts_name != NULL) + { + memcpy (&symsect, &arci->ctfi_symsect, sizeof (struct ctf_sect)); + symsectp = &symsect; + } + if (arci->ctfi_strsect.cts_name != NULL) + { + memcpy (&strsect, &arci->ctfi_strsect, sizeof (struct ctf_sect)); + strsectp = &strsect; + } + + fp = ctf_dict_open_by_offset (arci, ctf_open_sect (ctf_open_sect (NULL, symsectp), strsectp), arci->ctfi_members[index], len, parent, arci->ctfi_symsect_little_endian, errp); if (fp) diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index a4bbf4d961b..002d27d4d75 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -197,7 +197,7 @@ ctf_create_internal (ctf_dict_t *parent, ctf_import_flags_t import_flags, ctf_dynhash_t *structs = NULL, *unions = NULL, *enums = NULL, *names = NULL; ctf_dynhash_t *datasecs = NULL, *tags = NULL; - ctf_sect_t cts; + ctf_sect_t cts = {0}; ctf_dict_t *fp; libctf_init_debug(); @@ -222,13 +222,14 @@ ctf_create_internal (ctf_dict_t *parent, ctf_import_flags_t import_flags, goto err; } + cts.cts_section = CTF_ELF_SECT; cts.cts_name = _CTF_SECTION; cts.cts_data = &hdr; cts.cts_size = sizeof (hdr); cts.cts_entsize = 1; - if ((fp = ctf_bufopen_len (&cts, NULL, NULL, NULL, parent, NULL, import_flags - | CTF_IMPORT_NEW, errp)) == NULL) + if ((fp = ctf_bufopen_len (ctf_open_sect (NULL, &cts), NULL, parent, NULL, + import_flags | CTF_IMPORT_NEW, errp)) == NULL) goto err; /* These hashes will have been initialized with a starting size of zero, diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 407f857c465..ee43c3f133b 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -24,7 +24,6 @@ #include #include "ctf-util-port.h" #include -#include #include "ctf-util-sha1.h" #include #include @@ -888,11 +887,9 @@ extern void ctf_depreserialize (ctf_dict_t *fp); extern struct ctf_archive_internal * ctf_new_archive_internal (unsigned char *buf, ctf_dict_t *fp, int v1, enum arc_on_close_operation on_close, size_t len, - const ctf_sect_t *symsect, const ctf_sect_t *strsect, - ctf_error_t *errp); + ctf_open_sect_t *sects, ctf_error_t *errp); struct ctf_archive_internal *ctf_new_archive_wrapper (ctf_dict_t *fp, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, + ctf_open_sect_t *sects, ctf_error_t *errp); extern struct ctf_archive_internal * ctf_arc_open_internal (int fd, const char *filename, ctf_error_t *errp); @@ -909,13 +906,11 @@ extern ctf_dict_t *ctf_create_internal (ctf_dict_t *parent, ctf_import_flags_t import_flags, ctf_error_t *errp); extern void *ctf_set_open_errno (ctf_error_t *, ctf_error_t); -extern ssize_t ctf_buflen (const ctf_sect_t *ctfsect, ctf_error_t *errp); +extern ssize_t ctf_buflen (ctf_open_sect_t *sects, ctf_error_t *errp); extern ctf_ret_t ctf_flip_header (void *, int, int, int); extern ctf_error_t ctf_flip (ctf_dict_t *, ctf_header_t *, unsigned char *, int is_btf, int to_foreign); -extern ctf_dict_t *ctf_bufopen_len (const ctf_sect_t *ctfsect, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, +extern ctf_dict_t *ctf_bufopen_len (ctf_open_sect_t *sects, ssize_t *len, ctf_dict_t *parent, ctf_archive_t *ctf_archive, ctf_import_flags_t import_flags, diff --git a/libctf/ctf-link.c b/libctf/ctf-link.c index eb70d8c1ce8..d8ba6520d7e 100644 --- a/libctf/ctf-link.c +++ b/libctf/ctf-link.c @@ -1187,7 +1187,7 @@ ctf_link_deduplicating_per_cu (ctf_dict_t *fp) if ((in_arc = ctf_new_archive_internal (NULL, outputs[0], 0, FREE_ARCHIVE_ONLY_DICT, 0, - NULL, NULL, &err)) == NULL) + NULL, &err)) == NULL) { ctf_set_errno (fp, err); goto err_outputs; @@ -1515,9 +1515,10 @@ ctf_link_against (ctf_dict_t *fp, ctf_archive_t *against, ctf_archive_t *dict, == NULL) return ctf_err (err_locus (fp), err, _("cannot open against-types parent dict")); - /* Add the sole parent, then the single child. */ + /* Add the sole parent, then the single child. The parent is never written + out or CU-mapped, so give it a non-colliding name. */ - if (ctf_link_add (fp, against, _CTF_SECTION, NULL) < 0) + if (ctf_link_add (fp, against, "//@@parent@name@irrelevant//", NULL) < 0) return -1; /* errno is set for us. */ if (ctf_link_add (fp, dict, name, NULL) < 0) diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c index e28a0b870c8..36f72d05b16 100644 --- a/libctf/ctf-open-bfd.c +++ b/libctf/ctf-open-bfd.c @@ -44,63 +44,42 @@ ctf_bfdclose (struct ctf_archive_internal *arci) bfd_errmsg (bfd_get_error ())); } -/* Open a CTF file given the specified BFD. */ +/* Open a CTF file given the specified BFD, and other sections which may + override it (the CTF section may contain a CTF archive or a file). */ ctf_archive_t * -ctf_bfdopen (struct bfd *abfd, ctf_error_t *errp) -{ - ctf_archive_t *arc; - asection *ctf_asect; - bfd_byte *contents; - ctf_sect_t ctfsect; - - libctf_init_debug(); - - if (((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL) - && ((ctf_asect = bfd_get_section_by_name (abfd, ".BTF")) == NULL)) - { - return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); - } - - if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents)) - { - ctf_err (err_locus (NULL), 0, _("cannot malloc CTF section: %s"), - bfd_errmsg (bfd_get_error ())); - return (ctf_set_open_errno (errp, ECTF_FMT)); - } - - ctfsect.cts_name = bfd_section_name(ctf_asect); - ctfsect.cts_entsize = 1; - ctfsect.cts_size = bfd_section_size (ctf_asect); - ctfsect.cts_data = contents; - - if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL) - { - /* This frees the cts_data later. */ - arc->ctfi_data = (void *) ctfsect.cts_data; - return arc; - } - - free (contents); - return NULL; /* errno is set for us. */ -} - -/* Open a CTF file given the specified BFD and CTF section (which may contain a - CTF archive or a file). */ - -ctf_archive_t * -ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, - const ctf_sect_t *ctfsect, ctf_error_t *errp) +ctf_bfdopen (struct bfd *abfd _libctf_unused_, ctf_open_sect_t *sects, ctf_error_t *errp) { ctf_archive_t *arci; + ctf_sect_t *sect = (ctf_sect_t *) sects; + ctf_sect_t ctfsect = {0}; + ctf_sect_t *ctfsectp = NULL; ctf_sect_t *symsectp = NULL; ctf_sect_t *strsectp = NULL; const char *bfderrstr = NULL; + char *ctf_alloc = NULL; char *strtab_alloc = NULL; int symsect_endianness = -1; + int free_ctfsect = 0; libctf_init_debug(); + /* Extract user-passed sects. */ + + do + { + switch (sect->cts_section) + { + case CTF_ELF_SECT: ctfsectp = sect; break; + case CTF_ELF_SYMSECT: symsectp = sect; break; + case CTF_ELF_STRSECT: strsectp = sect; break; + default: + /* Unknown sections are fine, and ignored. */ + ; + } + sect = ctf_list_next (sect); + } while (sect); + #ifdef HAVE_BFD_ELF ctf_sect_t symsect, strsect; Elf_Internal_Shdr *symhdr; @@ -113,10 +92,29 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, size_t strsize; const ctf_preamble_t *preamble; - if (ctfsect->cts_data == NULL) + if (!ctfsectp) { - bfderrstr = N_("CTF section is NULL"); - goto err; + asection *ctf_asect; + bfd_byte *contents; + + if (((ctf_asect = bfd_get_section_by_name (abfd, _CTF_SECTION)) == NULL) + && ((ctf_asect = bfd_get_section_by_name (abfd, ".BTF")) == NULL)) + return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); + + if (!bfd_malloc_and_get_section (abfd, ctf_asect, &contents)) + { + bfderrstr = N_("cannot malloc CTF section"); + goto err; + } + + ctf_alloc = (char *) contents; + ctfsect.cts_section = CTF_ELF_SECT; + ctfsect.cts_name = bfd_section_name (ctf_asect); + ctfsect.cts_entsize = 1; + ctfsect.cts_size = bfd_section_size (ctf_asect); + ctfsect.cts_data = contents; + ctfsectp = &ctfsect; + free_ctfsect = 1; } /* v3 dicts may cite the symtab or the dynsymtab, without using sh_link to @@ -124,11 +122,11 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, now). */ errno = 0; - preamble = ctf_arc_bufpreamble_v1 (ctfsect); + preamble = ctf_arc_bufpreamble_v1 (ctfsectp); if (!preamble && errno == EOVERFLOW) { bfderrstr = N_("section too short to be CTF or BTF"); - goto err; + goto err_free_ctf; } if (!preamble || (preamble && preamble->ctp_flags & CTF_F_DYNSTR)) @@ -153,7 +151,7 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, if ((symtab = malloc (symhdr->sh_size)) == NULL) { bfderrstr = N_("cannot malloc symbol table"); - goto err; + goto err_free_ctf; } isymbuf = bfd_elf_get_elf_syms (abfd, symhdr, symcount, 0, @@ -205,6 +203,7 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, thrashing around digging the name out of the shstrtab given that we don't use it for anything but debugging. */ + strsect.cts_section = CTF_ELF_STRSECT; strsect.cts_data = strtab; strsect.cts_name = strtab_name; strsect.cts_size = strsize; @@ -214,6 +213,7 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, if (symtab) { assert (symhdr->sh_entsize == get_elf_backend_data (abfd)->s->sizeof_sym); + symsect.cts_section = CTF_ELF_SYMSECT; symsect.cts_name = symtab_name; symsect.cts_entsize = symhdr->sh_entsize; symsect.cts_size = symhdr->sh_size; @@ -224,7 +224,8 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, symsect_endianness = bfd_little_endian (abfd); #endif - arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp); + arci = ctf_arc_bufopen (ctf_open_sect (ctf_open_sect (ctf_open_sect (NULL, + ctfsectp), symsectp), strsectp), errp); if (arci) { /* Request freeing of the symsect and possibly the strsect. */ @@ -236,10 +237,16 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_, if (symsect_endianness > -1) ctf_arc_symsect_endianness (arci, symsect_endianness); + /* This frees the cts_data later. */ + if (free_ctfsect) + arci->ctfi_data = (void *) ctfsect.cts_data; + /* XXX get the data model right. */ return arci; } #ifdef HAVE_BFD_ELF + err_free_ctf: + free (ctf_alloc); err_free_sym: free (symtab); free (strtab_alloc); @@ -328,7 +335,7 @@ ctf_fdopen (int fd, const char *filename, const char *target, ctf_error_t *errp) return (ctf_set_open_errno (errp, err)); } - if ((arci = ctf_bfdopen (abfd, errp)) == NULL) + if ((arci = ctf_bfdopen (abfd, NULL, errp)) == NULL) { if (!bfd_close_all_done (abfd)) ctf_err (err_locus (NULL), 0, _("cannot close BFD: %s"), diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 55741017e48..1db76cda985 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -1720,50 +1720,33 @@ void ctf_set_ctl_hashes (ctf_dict_t *fp) fp->ctf_lookups[5].ctl_hash = NULL; } -/* Open a CTF file, mocking up a suitable ctf_sect. */ +/* Chain ctf_sect_t's together. No memory allocation is needed, so this + function cannot fail and can be called in a nested fashion safely. */ -ctf_dict_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size, - const char *symsect, size_t symsect_size, - size_t symsect_entsize, - const char *strsect, size_t strsect_size, - ctf_dict_t *parent, ctf_error_t *errp) +ctf_open_sect_t *ctf_open_sect (ctf_open_sect_t *open_sect, ctf_sect_t *sect) { - ctf_sect_t skeleton; + /* A ctf_open_sect_t *is* a ctf_sect_t: they are layout-equivalent, but also + they both start with a ctf_list_t. */ - ctf_sect_t ctf_sect, sym_sect, str_sect; - ctf_sect_t *ctfsectp = NULL; - ctf_sect_t *symsectp = NULL; - ctf_sect_t *strsectp = NULL; + ctf_list_t *existing = (ctf_list_t *) open_sect; - skeleton.cts_name = _CTF_SECTION; - skeleton.cts_entsize = 1; + /* Allow the caller to pass in a NULL sect: return the passed-in sect and do + nothing to it. (Simplifies call chains in which some members are + optional, e.g. ctf_bfdopen). */ - if (ctfsect) + if (!sect) + return (ctf_open_sect_t *) open_sect; + + /* Allow reuse of the same section in multiple calls. */ + memset ((ctf_list_t *) sect, 0, sizeof (ctf_list_t)); + + if (open_sect) { - memcpy (&ctf_sect, &skeleton, sizeof (struct ctf_sect)); - ctf_sect.cts_data = ctfsect; - ctf_sect.cts_size = ctfsect_size; - ctfsectp = &ctf_sect; + ctf_list_append (existing, sect); + return (ctf_open_sect_t *) existing; } - - if (symsect) - { - memcpy (&sym_sect, &skeleton, sizeof (struct ctf_sect)); - sym_sect.cts_data = symsect; - sym_sect.cts_size = symsect_size; - sym_sect.cts_entsize = symsect_entsize; - symsectp = &sym_sect; - } - - if (strsect) - { - memcpy (&str_sect, &skeleton, sizeof (struct ctf_sect)); - str_sect.cts_data = strsect; - str_sect.cts_size = strsect_size; - strsectp = &str_sect; - } - - return ctf_bufopen (ctfsectp, symsectp, strsectp, parent, errp); + else + return (ctf_open_sect_t *) sect; } /* Decode the specified CTF or BTF buffer and optional symbol table, and create @@ -1772,12 +1755,9 @@ ctf_dict_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size, ctf_open(), below. */ ctf_dict_t * -ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ctf_dict_t *parent, - ctf_error_t *errp) +ctf_bufopen (ctf_open_sect_t *sects, ctf_dict_t *parent, ctf_error_t *errp) { - return ctf_bufopen_len (ctfsect, symsect, strsect, NULL, parent, NULL, - 0, errp); + return ctf_bufopen_len (sects, NULL, parent, NULL, 0, errp); } /* Get the length of a CTF buffer, without returning it. The length includes @@ -1785,11 +1765,11 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, though will not be larger than the section size. */ ssize_t -ctf_buflen (const ctf_sect_t *ctfsect, ctf_error_t *errp) +ctf_buflen (ctf_open_sect_t *sects, ctf_error_t *errp) { ssize_t len; - ctf_bufopen_len (ctfsect, NULL, NULL, &len, NULL, NULL, 0, errp); + ctf_bufopen_len (sects, &len, NULL, NULL, 0, errp); return len; } @@ -1801,8 +1781,7 @@ ctf_buflen (const ctf_sect_t *ctfsect, ctf_error_t *errp) if LEN is NULL, the dict is returned in ctf_dict_t, or NULL on error. */ ctf_dict_t * -ctf_bufopen_len (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, - const ctf_sect_t *strsect, ssize_t *len, ctf_dict_t *parent, +ctf_bufopen_len (ctf_open_sect_t *sects, ssize_t *len, ctf_dict_t *parent, ctf_archive_t *ctf_archive, ctf_import_flags_t import_flags, ctf_error_t *errp) { @@ -1817,6 +1796,8 @@ ctf_bufopen_len (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_header_v3_t *header_v3 = NULL; ctf_dict_t *fp; size_t ctf_adjustment = 0; + ctf_sect_t *sect = (ctf_sect_t *) sects; + ctf_sect_t *ctfsect = NULL, *strsect = NULL, *symsect = NULL; /* These match the CTF_VERSION definitions up to IS_BTF. */ enum @@ -1839,6 +1820,28 @@ ctf_bufopen_len (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_set_open_errno (errp, 0); + /* Figure out what sects we've got. */ + + if (sect == NULL) + return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); + + do + { + switch (sect->cts_section) + { + case CTF_ELF_SECT: ctfsect = sect; break; + case CTF_ELF_SYMSECT: symsect = sect; break; + case CTF_ELF_STRSECT: strsect = sect; break; + default: + /* Unknown sections are fine, and ignored. */ + ; + } + sect = ctf_list_next (sect); + } while (sect); + + if (ctfsect == NULL) + return (ctf_set_open_errno (errp, ECTF_NOCTFDATA)); + ctf_dprintf ("ctf_bufopen %zi+%zi+%zi bytes: validating\n", ctfsect ? ctfsect->cts_size : 0, symsect ? symsect->cts_size : 0, @@ -2451,10 +2454,10 @@ ctf_bufopen_len (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, memcpy (&fp->ctf_data, ctfsect, sizeof (ctf_sect_t)); if (symsect != NULL) - { - memcpy (&fp->ctf_ext_symtab, symsect, sizeof (ctf_sect_t)); - memcpy (&fp->ctf_ext_strtab, strsect, sizeof (ctf_sect_t)); - } + memcpy (&fp->ctf_ext_symtab, symsect, sizeof (ctf_sect_t)); + + if (strsect != NULL) + memcpy (&fp->ctf_ext_strtab, strsect, sizeof (ctf_sect_t)); if (fp->ctf_data.cts_name != NULL) if ((fp->ctf_data.cts_name = strdup (fp->ctf_data.cts_name)) == NULL) @@ -2796,6 +2799,8 @@ ctf_archive_t * ctf_dict_arc (ctf_dict_t *fp, int flags) { struct ctf_archive_internal *arci; + ctf_sect_t symsect, strsect; + ctf_sect_t *symsectp = NULL, *strsectp = NULL; ctf_error_t err; if (fp->ctf_archive) @@ -2808,8 +2813,21 @@ ctf_dict_arc (ctf_dict_t *fp, int flags) if (flags & CTF_DICT_ARC_ORIGINAL) return NULL; - if ((arci = ctf_new_archive_wrapper (fp, &fp->ctf_ext_symtab, - &fp->ctf_ext_strtab, &err)) == NULL) + /* Take a copy of the ctf_sect_t's out of the way to keep the list chaining + done by ctf_open_sect from persisting or crossing threads unpleasantly. */ + if (fp->ctf_ext_symtab.cts_name != NULL) + { + memcpy (&symsect, &fp->ctf_ext_symtab, sizeof (struct ctf_sect)); + symsectp = &symsect; + } + if (fp->ctf_ext_symtab.cts_name != NULL) + { + memcpy (&strsect, &fp->ctf_ext_symtab, sizeof (struct ctf_sect)); + strsectp = &strsect; + } + + if ((arci = ctf_new_archive_wrapper (fp, ctf_open_sect (ctf_open_sect (NULL, symsectp), strsectp), + &err)) == NULL) { ctf_set_errno (fp, err); return NULL; @@ -2829,7 +2847,7 @@ ctf_dict_arc (ctf_dict_t *fp, int flags) ctf_sect_t ctf_elf_sect (const ctf_dict_t *fp, ctf_elfsect_names_t sect) { - ctf_sect_t error = { "ERROR", NULL, 0, 0 }; + ctf_sect_t error = { {0}, 0, "ERROR", NULL, 0, 0 }; switch (sect) { @@ -2840,6 +2858,7 @@ ctf_elf_sect (const ctf_dict_t *fp, ctf_elfsect_names_t sect) case CTF_ELF_STRSECT: return fp->ctf_ext_strtab; default: + error.cts_section = sect; return error; } } diff --git a/libctf/libctf.ver b/libctf/libctf.ver index c3bec8ad7c6..11eeacb4340 100644 --- a/libctf/libctf.ver +++ b/libctf/libctf.ver @@ -22,8 +22,8 @@ LIBCTF_2.0 { ctf_dict_open; ctf_dict_open_by_index; + ctf_open_sect; ctf_bufopen; - ctf_simple_open; ctf_create; ctf_close; ctf_dict_close; @@ -34,7 +34,6 @@ LIBCTF_2.0 { ctf_dict_parent; ctf_type_isparent; - ctf_dict_set_model; ctf_dict_model; @@ -180,7 +179,6 @@ LIBCTF_2.0 { ctf_open; /* libctf only. */ ctf_arc_open; /* libctf only. */ ctf_bfdopen; /* libctf only. */ - ctf_bfdopen_ctfsect; /* libctf only. */ local: *; }; diff --git a/libctf/testsuite/libctf-regression/open-error-free.c b/libctf/testsuite/libctf-regression/open-error-free.c index a41c2933a2d..2cb7879870d 100644 --- a/libctf/testsuite/libctf-regression/open-error-free.c +++ b/libctf/testsuite/libctf-regression/open-error-free.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_VALGRIND_VALGRIND_H @@ -105,6 +105,7 @@ void free (void *ptr) int main (void) { ctf_dict_t *fp; + ctf_sect_t sect = {0}; ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) }; int err; ctf_id_t type; @@ -156,8 +157,13 @@ int main (void) malloc_count = 0; free_count = 0; - if ((ctf_simple_open (written, written_size, NULL, 0, 0, NULL, 0, - NULL, &err)) != NULL) + sect.cts_section = CTF_ELF_SECT; + sect.cts_name = ".ctf"; + sect.cts_entsize = 1; + sect.cts_size = written_size; + sect.cts_data = written; + + if ((ctf_bufopen (ctf_open_sect (NULL, §), NULL, &err)) != NULL) { fprintf (stderr, "wildly corrupted dict still opened OK?!\n"); exit (1); diff --git a/libctf/testsuite/libctf-writable/id-assignment.c b/libctf/testsuite/libctf-writable/id-assignment.c index 10e1de41d99..95388f58e18 100644 --- a/libctf/testsuite/libctf-writable/id-assignment.c +++ b/libctf/testsuite/libctf-writable/id-assignment.c @@ -1,11 +1,26 @@ /* Test parent / child ID assignment. */ -#include +#include #include #include #include #include +/* Make a ctfsect suitable for ctf_bfdopen(). */ +static ctf_sect_t +make_ctfsect (const char *name, bfd_byte *data, bfd_size_type size) +{ + ctf_sect_t ctfsect = {0}; + + ctfsect.cts_section = CTF_ELF_SECT; + ctfsect.cts_name = name; + ctfsect.cts_entsize = 1; + ctfsect.cts_size = size; + ctfsect.cts_data = data; + + return ctfsect; +} + int test (int empty_parent, int unserialized_parent) { @@ -47,7 +62,8 @@ test (int empty_parent, int unserialized_parent) ctf_dict_close (parent); - if ((parent = ctf_simple_open ((char *) pbuf, psize, NULL, 0, 0, NULL, 0, NULL, &err)) == NULL) + if ((parent = ctf_bufopen (ctf_open_sect (NULL, make_ctfsect (".ctf", (char *) pbuf, psize)), + NULL, &err)) == NULL) goto parent_open_err; if (!empty_parent) @@ -201,12 +217,12 @@ test (int empty_parent, int unserialized_parent) free (pbuf); free (cbuf); - if ((parent = ctf_simple_open ((char *) pbuf2, psize, NULL, 0, 0, NULL, 0, - NULL, &err)) == NULL) + if ((parent = ctf_bufopen (ctf_open_sect (NULL, make_ctfsect ((char *) pbuf2, psize)), + NULL, &err)) == NULL) goto parent_open_err; - if ((child = ctf_simple_open ((char *) cbuf2, csize, NULL, 0, 0, NULL, - 0, parent, &err)) == NULL) + if ((child = ctf_bufopen (ctf_open_sect (NULL, make_ctfsect ((char *) cbuf2, csize)), + parent, &err)) == NULL) goto child_open_err; if (!empty_parent) diff --git a/libctf/testsuite/libctf-writable/libctf-bitfield-name-lookup.c b/libctf/testsuite/libctf-writable/libctf-bitfield-name-lookup.c index 548333261a8..27995fd3f3d 100644 --- a/libctf/testsuite/libctf-writable/libctf-bitfield-name-lookup.c +++ b/libctf/testsuite/libctf-writable/libctf-bitfield-name-lookup.c @@ -9,6 +9,7 @@ int bitfieldery (int count, int up, int pos) { unsigned char *ctf_written; + ctf_sect_t sect = {0}; size_t size; ctf_dict_t *dict; const char *err = "opening"; @@ -72,8 +73,15 @@ int bitfieldery (int count, int up, int pos) ctf_dict_close (dict); err = "opening"; - if ((dict = ctf_simple_open ((char *) ctf_written, size, NULL, 0, - 0, NULL, 0, NULL, &open_err)) == NULL) + + sect.cts_section = CTF_ELF_SECT; + sect.cts_name = ".ctf"; + sect.cts_entsize = 1; + sect.cts_size = size; + sect.cts_data = (char *) ctf_written; + + if ((dict = ctf_bufopen (ctf_open_sect (NULL, §), NULL, + &open_err)) == NULL) goto open_err; err = "looking up"; diff --git a/libctf/testsuite/libctf-writable/symtypetab-nonlinker-writeout.c b/libctf/testsuite/libctf-writable/symtypetab-nonlinker-writeout.c index 236fb454c9c..fe4bc0b7db3 100644 --- a/libctf/testsuite/libctf-writable/symtypetab-nonlinker-writeout.c +++ b/libctf/testsuite/libctf-writable/symtypetab-nonlinker-writeout.c @@ -36,6 +36,7 @@ try_maybe_reporting (int report) ctf_dict_t *fp; ctf_id_t func, func2, func3, base, base2, base3; ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) }; + ctf_sect_t sect = {0}; ctf_id_t dummy = 0; ctf_next_t *i = NULL; ctf_id_t symtype; @@ -167,8 +168,14 @@ try_maybe_reporting (int report) ctf_file_close (fp); /* Read back in. */ - if ((fp = ctf_simple_open ((const char *) buf, bufsiz, NULL, 0, 0, NULL, - 0, NULL, &err)) == NULL) + + sect.cts_section = CTF_ELF_SECT; + sect.cts_name = ".ctf"; + sect.cts_entsize = 1; + sect.cts_size = bufsize; + sect.cts_data = (char *) buf; + + if ((fp = ctf_bufopen (ctf_open_sect (NULL, §), NULL, &err)) == NULL) goto open_err; /* Verify symbol order against the order we expect if this dict is sorted and