aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2025-04-25 21:09:34 +0100
committerNick Alcock <nick.alcock@oracle.com>2025-04-25 21:23:08 +0100
commit918e356b18afb5daf4f0ba43f25373689782e3de (patch)
treecbdeebe8311b9176606a9127c9e3372ec59a0cf6 /libctf
parent88f2c13d1ce8e9ceac2b95a515c6d7ed96b87adb (diff)
downloadbinutils-918e356b18afb5daf4f0ba43f25373689782e3de.zip
binutils-918e356b18afb5daf4f0ba43f25373689782e3de.tar.gz
binutils-918e356b18afb5daf4f0ba43f25373689782e3de.tar.bz2
libctf: archive: allow opening BTF dicts in archives (not for upstreaming)
BTF dicts are normally suppressed in archives, but it is possible to create them with enough cunning. If such an archive is encountered, the BTF dicts in it have no parent name, which means that ctf_arc_import_parent (used by ctf_dict_open_cached, ctf_archive_next, and all the ctf_arc_lookup functions) fails to figure out what parent to import, and fails. Kludge around it by relying on our secret knowledge that ctf_link_write always emits the parent dict into the archive first. If no name is set, import the parent dict for now. (Before upstreaming, a new archive format with a dedicated parent dict field will turn up, obviating this kludge.)
Diffstat (limited to 'libctf')
-rw-r--r--libctf/ctf-archive.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index 06363e7..4b19cc9 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -839,11 +839,31 @@ ctf_arc_open_by_name_sections (const ctf_archive_t *arc,
static int
ctf_arc_import_parent (const ctf_archive_t *arc, ctf_dict_t *fp, int *errp)
{
- if ((fp->ctf_flags & LCTF_CHILD) && fp->ctf_parname && !fp->ctf_parent)
+ if ((fp->ctf_flags & LCTF_CHILD) && !fp->ctf_parent)
{
int err;
- ctf_dict_t *parent = ctf_dict_open_cached ((ctf_archive_t *) arc,
- fp->ctf_parname, &err);
+ ctf_dict_t *parent;
+ const char *parent_name = fp->ctf_parent_name;
+
+ /* If no parent is set, and this is an archive, assume that the parent
+ is the first dict in the archive, which matches what ctf_link
+ produces. UPTODO: add a dedicated header entry for parent
+ name. */
+
+ if (!parent_name && arc->ctfi_archive)
+ {
+ struct ctf_archive_modent *modent;
+ const char *nametbl;
+
+ modent = (ctf_archive_modent_t *) ((char *) arc->ctfi_archive
+ + sizeof (struct ctf_archive));
+
+ nametbl = (((const char *) arc->ctfi_archive)
+ + le64toh (arc->ctfi_archive->ctfa_names));
+ parent_name = &nametbl[le64toh (modent[0].name_offset)];
+ }
+
+ parent = ctf_dict_open_cached ((ctf_archive_t *) arc, parent_name, &err);
if (errp)
*errp = err;