[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug libctf/29242] ld crash when deduplicating CTF from multiple .o file

From: cvs-commit at gcc dot gnu.org
Subject: [Bug libctf/29242] ld crash when deduplicating CTF from multiple .o files with the same name
Date: Tue, 28 Jun 2022 11:35:04 +0000


--- Comment #4 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot 
gnu.org> ---
The binutils-2_38-branch branch has been updated by Nick Alcock


commit 7f9a495a1673fd5c431597bed64f0428f5e389a0
Author: Nick Alcock <nick.alcock@oracle.com>
Date:   Fri Jun 10 17:05:50 2022 +0100

    libctf: fix linking together multiple objects derived from the same source

    Right now, if you compile the same .c input repeatedly with CTF enabled
    and different compilation flags, then arrange to link all of these
    together, then things misbehave in various ways.  libctf may conflate
    either inputs (if the .o files have the same name, say if they are
    stored in different .a archives), or per-CU outputs when conflicting
    types are found: the latter can lead to entirely spurious errors when
    it tries to produce multiple per-CU outputs with the same name
    (discarding all but the last, but then looking for types in the earlier
    ones which have just been thrown away).

    Fixing this is multi-pronged.  Both inputs and outputs need to be
    differentiated in the hashtables libctf keeps them in: inputs with the
    same cuname and filename need to be considered distinct as long as they
    have different associated CTF dicts, and per-CU outputs need to be
    considered distinct as long as they have different associated input
    dicts.  Right now there is nothing tying the two together other than the
    CU name: fix this by introducing a new field in the ctf_dict_t named
    ctf_link_in_out, which (for input dicts) points to the associated per-CU
    output dict (if any), and for output dicts points to the associated
    input dict.  At creation time the name used is completely arbitrary:
    it's only important that it be distinct if CTF dicts are distinct.  So,
    when a clash is found, adjust the CU name by sticking the number of
    elements in the input on the end.  At output time, the CU name will
    appear in the linked object, so it matters a little more that it look
    slightly less ugly: in conflicting cases, append an incrementing
    integer, starting at 0.

    This naming scheme is not very helpful, but it's hard to see what else
    we can do.  The input .o name may be the same.  The input .a name is not
    even visible to ctf_link, and even *that* might be the same, because
    .a's can contain many members with the same name, all of which
    participate in the link.  All we really know is that the two have
    distinct dictionaries with distinct types in them, and at least this way
    they are all represented, any any symbols, variables etc referring to
    those types are accurately stored.

    (As a side-effect this also fixes a use-after-free and double-free when
    errors are found during variable or symbol emission.)

    Use the opportunity to prevent a couple of sources of problems, to wit
    changing the active CU mappings when a link has already been done
    (no effect on ld, which doesn't use CU mappings at all), and causing
    multiple consecutive ctf_link's to have the same net effect as just
    doing the last one (no effect on ld, which only ever does one
    ctf_link) rather than having the links be a sort of half-incremental
    not-really-intended mess.


            PR libctf/29242
            * ctf-impl.h (struct ctf_dict) [ctf_link_in_out]: New.
            * ctf-dedup.c (ctf_dedup_emit_type): Set it.
            * ctf-link.c (ctf_link_add_ctf_internal): Set the input
            CU name uniquely when clashes are found.
            (ctf_link_add): Document what repeated additions do.
            (ctf_new_per_cu_name): New, come up with a consistent
            name for a new per-CU dict.
            (ctf_link_deduplicating): Use it.
            (ctf_create_per_cu): Use it, and ctf_link_in_out, and set
            ctf_link_in_out properly.  Don't overwrite per-CU dicts with
            per-CU dicts relating to different inputs.
            (ctf_link_add_cu_mapping): Prevent per-CU mappings being set up
            if we already have per-CU outputs.
            (ctf_link_one_variable): Adjust ctf_link_per_cu call.
            (ctf_link_deduplicating_one_symtypetab): Likewise.
            (ctf_link_empty_outputs): New, delete all the ctf_link_outputs
            and blank out ctf_link_in_out on the corresponding inputs.
            (ctf_link): Clarify the effect of multiple ctf_link calls.
            Empty ctf_link_outputs if it already exists rather than
            having the old output leak into the new link.  Fix a variable
            * testsuite/config/default.exp (AR): Add.
            (OBJDUMP): Likewise.
            * testsuite/libctf-regression/libctf-repeat-cu.exp: New test.
            * testsuite/libctf-regression/libctf-repeat-cu*: Main program,
            library, and expected results for the test.

You are receiving this mail because:
You are on the CC list for the bug.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]