dwarf-reader: Ignore zero length location expressions from DW_AT_location

Location expressions might occasionally be of length 0. E.g. a reason
for that are thread local variables that do not exactly have a
location to refer to. Compilers/Linkers may choose an empty location
description. E.g.  see the dwarfdump output for the added testcase
based on libandroid.so (from AOSP).

$ dwarfdump libandroid.so|egrep -B9 "gChoreographerE$"

LOCAL_SYMBOLS:
< 1><0x00000022> DW_TAG_namespace
                   DW_AT_name           android
< 2><0x00000027>   DW_TAG_variable
                     DW_AT_name           gChoreographer
                     DW_AT_type           <0x00000b65>
                     DW_AT_decl_file      0x00000003 .../choreographer.cpp
                     DW_AT_decl_line      0x00000059
                     DW_AT_location       len 0x0000: :
                     DW_AT_linkage_name   _ZN7androidL14gChoreographerE

The DW_AT_location is properly read by elfutils' dwarf_location(), but
is not useful for us to proceed with. Hence early exit on this.

	* src/abg-dwarf-reader.cc (die_location_expr): Ignore zero
	  length location expressions.
	* tests/data/Makefile.am: Add new test files.
	* tests/data/test-read-dwarf/test-libandroid.so: New test file.
	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
	* tests/test-read-dwarf.cc: Add new test case.

Reported-by: Dan Albert <danalbert@google.com>
Reviewed-by: Giuliano Procida <gprocida@google.com>
Cc: Mark Wielaard <mark@klomp.org>
Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Matthias Maennich 2020-10-29 12:21:00 +00:00 committed by Dodji Seketeli
parent 8a0825e319
commit 38e72b262d
5 changed files with 86965 additions and 3 deletions

View File

@ -9385,9 +9385,9 @@ compare_dies_cu_decl_file(const Dwarf_Die* l, const Dwarf_Die *r, bool &result)
/// @param expr_len the length of the resulting dwarf expression.
/// This is set iff the function returns true.
///
/// @return true if the attribute exists and has a dwarf expression as
/// value. In that case the expr and expr_len arguments are set to
/// the resulting dwarf exprssion.
/// @return true if the attribute exists and has a non-empty dwarf expression
/// as value. In that case the expr and expr_len arguments are set to the
/// resulting dwarf expression.
static bool
die_location_expr(const Dwarf_Die* die,
unsigned attr_name,
@ -9404,6 +9404,10 @@ die_location_expr(const Dwarf_Die* die,
size_t len = 0;
bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
// Ignore location expressions where reading them succeeded but
// their length is 0.
result &= len > 0;
if (result)
*expr_len = len;

View File

@ -520,6 +520,8 @@ test-read-dwarf/test-PR26568-2.o \
test-read-dwarf/test-PR26568-1.o \
test-read-dwarf/test-PR26568-1.o.abi \
test-read-dwarf/test-PR26568-2.o.abi \
test-read-dwarf/test-libandroid.so \
test-read-dwarf/test-libandroid.so.abi \
\
test-annotate/test0.abi \
test-annotate/test1.abi \

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -394,6 +394,13 @@ InOutSpec in_out_specs[] =
"data/test-read-dwarf/test-PR26568-2.o.abi",
"output/test-read-dwarf/test-PR26568-2.o.abi",
},
{
"data/test-read-dwarf/test-libandroid.so",
"",
HASH_TYPE_ID_STYLE,
"data/test-read-dwarf/test-libandroid.so.abi",
"output/test-read-dwarf/test-libandroid.so.abi",
},
// This should be the last entry.
{NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL}
};