]> sourceware.org Git - libabigail.git/commit
Better support for golang programs
authorDodji Seketeli <dodji@redhat.com>
Thu, 22 Sep 2022 12:58:53 +0000 (14:58 +0200)
committerDodji Seketeli <dodji@redhat.com>
Thu, 22 Sep 2022 12:58:53 +0000 (14:58 +0200)
commita1c3242801d4744060b4b6e5bec1f12b26bf1968
tree15b3395d99caddeae49ef4d23abed0449538b6f4
parentaad0e11f5058d287fa44d35f017798f317c6a698
Better support for golang programs

When analyzing the bettercap program written in Golang, the DWARF
reader goes into an infinite loop due to this recursive DWARF
construct:

 [ 8bbf9]    subroutine_type      abbrev: 40
             name                 (string) "gopkg.in/sourcemap%2ev1.fn"
             byte_size            (udata) 4
             lo_user+0x900        (data1) 19
             lo_user+0x904        (addr) +0000000000
 [ 8bc1b]      formal_parameter     abbrev: 41
               type                 (ref_addr) [ 8ba8b]
 [ 8bc20]      formal_parameter     abbrev: 41
               type                 (ref_addr) [ 8bc4b]
 [ 8bc25]      formal_parameter     abbrev: 41
               type                 (ref_addr) [ 6d43e]
 [ 8bc2b]    typedef              abbrev: 39
             name                 (string) "gopkg.in/sourcemap%2ev1.fn"
             type                 (ref_addr) [ 8bbf9]
 [ 8bc4b]    pointer_type         abbrev: 43
             name                 (string) "*gopkg.in/sourcemap%2ev1.fn"
             type                 (ref_addr) [ 8bc2b]
             lo_user+0x900        (data1) 0
             lo_user+0x904        (addr) +0000000000

Note how the typedef DIE at offset [ 8bc2b] references the function
type DIE at offset [ 8bbf9] which second parameter DIE at offset
[8bc20] has a pointer type described by the DIE [ 8bc4b].  This last
pointer type is a pointer to the typedef type which DIE has the offset
[ 8bc2b], which started this paragraph.  This is a recursive
construct.

First, there is die_qualified_type_name in the DWARF reader that goes
look unnecessarily into the underlying type of a typedef.  This makes
that function end-up in an infinite loop.  That is especially
unfortunate because we do not need to do that to construct the name of
the typedef.  This looks like an old relic of ancient unrelated code
that needs to go.  This patch lets it go.

Second, when building the IR for function type, build_function_type
also ends up in a infinite loop because it's written naively.  To fix
that, this patch does what we do to handle recursively defined
classes.  The function type IR for that function type DIE is
"forward-declared" as being "Work In Progress" aka WIP; then when a
construct references that same DIE, the WIP IR is returned.  When we
are done constructing the function type IR for that DIE, the IR is no
longer marked WIP.  That way, the infinite recursion is avoided.

Now that all function types can be represented in the IR,
function_decl::get_pretty_representation_of_declarator is crashing
because it wrongly forgets that a parameter can have a function type.
The patch fixes that.

Last but not least, it appears that the name of elf symbols and
functions can contain characters that need to be escaped (to respect
the lexical rules of XML) in the emitted ABIXML.  The patch fixes
that.

Together, this patch makes it so that running fedabipkgdiff to compare
packages against themselves now succeeds on the f36 distribution, for
the following Golang packages:

    $ fedabipkgdiff  --self-compare --from fc36 {containerd, bettercap,
    apptainer, rclone, singularity}

* src/abg-dwarf-reader.cc (die_qualified_type_name): Don't look at
the underlying type unnecessarily.
(build_function_type): Look for the WIP type first to avoid
infinite recursion.
* src/abg-ir.cc
(function_decl::get_pretty_representation_of_declarator): A
parameter can have a function type.
* src/abg-writer.cc (write_elf_symbol_reference)
(write_function_decl): Escape symbol names, function names and
symbol references.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-dwarf-reader.cc
src/abg-ir.cc
src/abg-writer.cc
This page took 0.03357 seconds and 5 git commands to generate.