include, libctf: add cth_parent_strlen CTFv4 header field

The first format difference between v3 and v4 is a cth_parent_strlen header
field.  This field (obviously not present in BTF) is populated from the
string table length of the parent at serialization time (protection against
being serialized before the parent is will be added in a later commit in
this series), and will be used at open time to prohibit opening of dicts
with a different strlen (which would corrupt the child's string table
if it was shared with the parent).

For now, just add the field, populate it at serialization time when linking
(when not linking, no deduplication is done and the correct value remains
unchanged), and dump it.

include/
	* ctf.h (ctf_header) [cth_parent_strlen]: New.

libctf/
	* ctf-dump.c (ctf_dump_header_sizefield): New.
	(ctf_dump_header): Use to dump the cth_parent_strlen.
	* ctf-open.c (upgrade_header_v2): Populate cth_parent_strlen.
	(upgrade_header_v3): Likewise.
	(ctf_flip_header): Flip it.
	(ctf_bufopen): Drop unnecessary initialization.
	* ctf-serialize.c (ctf_serialize): Write it out when linking.

ld/
	* testsuite/ld-ctf/data-func-conflicted-vars.d: Skip the nwe dump output.
	* testsuite/ld-ctf/data-func-conflicted.d: Likewise.
This commit is contained in:
Nick Alcock
2024-07-15 21:01:40 +01:00
parent 70d05ab0b2
commit 6c77689963
6 changed files with 49 additions and 2 deletions

View File

@@ -412,6 +412,7 @@ upgrade_header_v2 (ctf_header_t *hp)
hp->cth_funcoff = oldhp->cth_funcoff;
hp->cth_objtoff = oldhp->cth_objtoff;
hp->cth_lbloff = oldhp->cth_lbloff;
hp->cth_parent_strlen = 0; /* Strings start at offset 0. */
hp->cth_cuname = 0; /* No CU name. */
}
@@ -430,6 +431,7 @@ upgrade_header_v3 (ctf_header_t *hp)
hp->cth_funcoff = oldhp->cth_funcoff;
hp->cth_objtoff = oldhp->cth_objtoff;
hp->cth_lbloff = oldhp->cth_lbloff;
hp->cth_parent_strlen = 0; /* Strings start at offset 0. */
hp->cth_cuname = oldhp->cth_cuname;
hp->cth_parname = oldhp->cth_parname;
hp->cth_parlabel = oldhp->cth_parlabel;
@@ -1115,6 +1117,7 @@ ctf_flip_header (ctf_header_t *cth)
swap_thing (cth->cth_parlabel);
swap_thing (cth->cth_parname);
swap_thing (cth->cth_cuname);
swap_thing (cth->cth_parent_strlen);
swap_thing (cth->cth_objtoff);
swap_thing (cth->cth_funcoff);
swap_thing (cth->cth_objtidxoff);
@@ -1446,7 +1449,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
const ctf_sect_t *strsect, int *errp)
{
const ctf_preamble_t *pp;
size_t hdrsz = sizeof (ctf_header_t);
size_t hdrsz;
ctf_header_t *hp;
ctf_dict_t *fp;
int foreign_endian = 0;
@@ -1623,6 +1626,18 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
}
if ((hp->cth_parname != 0 && hp->cth_parname < hp->cth_parent_strlen)
|| (hp->cth_cuname != 0 && hp->cth_cuname < hp->cth_parent_strlen))
{
ctf_err_warn (NULL, 0, ECTF_CORRUPT,
_("Parent dict or CU name string offsets "
"(at %x and %x, respectively) are themselves "
"within the parent (upper bound: %x), thus "
"unreachable.\n"), hp->cth_parname, hp->cth_cuname,
hp->cth_parent_strlen);
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
}
/* Once everything is determined to be valid, attempt to decompress the CTF
data buffer if it is compressed, or copy it into new storage if it is not
compressed but needs endian-flipping. Otherwise we just put the data