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>