[DTrace-devel] [PATCH v2 07/20] dt_link: finish backing out varint, fixing dt_link-generated object files
Kris Van Hees
kris.van.hees at oracle.com
Fri Sep 16 12:25:41 UTC 2022
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
On Wed, Sep 07, 2022 at 01:59:55PM +0100, Nick Alcock via DTrace-devel wrote:
> For a while now, linking dtrace -G-generated object files has been
> saying
>
> /usr/bin/ld: .../build/test-triggers--usdt-tst-special.o: error adding symbols: no error
>
> This is more than slightly confusing. For starters, collect2 is
> corrupting the error message: the actual error is
>
> /usr/bin/ld: .../build/test-triggers--usdt-tst-special.o: error adding symbols: file format not recognized
>
> This is not much more helpful. The actual cause is in
> elf_link_add_object_symbols:
>
> name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
> isym->st_name);
>
> where the symbol name comes out as NULL. This is because we are hitting
> a sanity check in bfd_elf_string_from_elf_section:
>
> /* PR 24273: The string section's contents may have already
> been loaded elsewhere, eg because a corrupt file has the
> string section index in the ELF header pointing at a group
> section. So be paranoid, and test that the last byte of
> the section is zero. */
> if (hdr->sh_size == 0 || hdr->contents[hdr->sh_size - 1] != 0)
> return NULL;
>
> This paranoia has won out! We are generating string tables with
> hdr->sh_size one too small, pointing at the last byte of the last
> string.
>
> The cause is somewhat gross. dt_link.c:process_obj computes the length
> of the new strtab it's constructing by adding all the symbol names to a
> dt_strtab, asking it for its size, subtracting one for the \0 at the
> first byte, and then throwing the strtab away and directly editing the
> strtab in the object file, using the strtab it generated earlier only
> for its size. Doing things in two stages like this is a bit risky: it's
> riskier yet because it's using a dt_strtab, which is not a model of an
> ELF strtab at all but rather of a DTrace string table. No harm, they're
> the same: except that when varints landed the format of a string
> naturally changed to gain an extra length byte at the start. The size
> computation was changed to subtract two bytes rather than one (itself
> buggy: *every string in the strtab* had an extra byte on the front of
> it, so the wrong number of bytes was being subtracted and the resulting
> sh_size was too large). But when the varint code was backed out (in
> 29e3f422 "Remove the string length prefix"), this size computation was
> not changed back, leading to a sh_size that is one byte too low,
> triggering this failure.
>
> Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
> ---
> libdtrace/dt_link.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libdtrace/dt_link.c b/libdtrace/dt_link.c
> index 21ef56c0a3cb..5daaf2b02212 100644
> --- a/libdtrace/dt_link.c
> +++ b/libdtrace/dt_link.c
> @@ -1337,10 +1337,10 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
> */
> if (nsym > 0) {
> /*
> - * The first two bytes of the string table are reserved
> + * The first byte of the string table is reserved
> * for the \0 entry.
> */
> - len = dt_strtab_size(strtab) - 2;
> + len = dt_strtab_size(strtab) - 1;
>
> assert(len > 0);
> assert(dt_strtab_index(strtab, "") == 0);
> --
> 2.37.1.265.g363c192786.dirty
>
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list