From 16207c4af7bc2510ba5d996b8dbdecda30d15200 Mon Sep 17 00:00:00 2001 From: Giuliano Procida Date: Thu, 13 Jan 2022 08:56:48 +0000 Subject: [PATCH] Bug 28191 - Interpret DWARF 5 addrx locations This change uses libdw facilities to interpret location expressions instead of using libabigail's own mini-interpreter. With the fix for elfutils https://sourceware.org/bugzilla/show_bug.cgi?id=28220 in elfutils-0.186, abidw will correctly interpret Clang DWARF 5 symbol addresses. Without that fix many declarations will not be linked to their corresponding symbols due to the incorrect interpretation of location attribute data. * src/abg-dwarf-reader.cc (die_location_address): Use dwarf_attr_integrate, dwarf_getlocation and dwarf_getlocation_attr to decode addreses, instead of die_location_expr and eval_last_constant_dwarf_sub_expr. * tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi: Refresh test reference output; two more symbols have types. Signed-off-by: Giuliano Procida --- src/abg-dwarf-reader.cc | 23 +++-- .../PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi | 86 +++++++++++-------- 2 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index b4617620..f125196d 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -8855,18 +8855,31 @@ die_location_address(Dwarf_Die* die, uint64_t expr_len = 0; is_tls_address = false; - if (!die_location_expr(die, DW_AT_location, &expr, &expr_len)) + + if (!die) return false; - int64_t addr = 0; - if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, addr, is_tls_address)) + Dwarf_Attribute attr; + if (!dwarf_attr_integrate(const_cast(die), DW_AT_location, &attr)) return false; - address = addr; + if (dwarf_getlocation(&attr, &expr, &expr_len)) + return false; + // Ignore location expressions where reading them succeeded but + // their length is 0. + if (expr_len == 0) + return false; + + Dwarf_Attribute result; + if (!dwarf_getlocation_attr(&attr, expr, &result)) + // A location that has been interpreted as an address. + return !dwarf_formaddr(&result, &address); + + // Just get the address out of the number field. + address = expr->number; return true; } - /// Return the index of a function in its virtual table. That is, /// return the value of the DW_AT_vtable_elem_location attribute. /// diff --git a/tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi b/tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi index 4a84fe97..91542872 100644 --- a/tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi +++ b/tests/data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi @@ -639,6 +639,14 @@ + + + + + + + + @@ -665,6 +673,7 @@ + @@ -673,6 +682,7 @@ + @@ -727,11 +737,11 @@ - - + + - + @@ -739,7 +749,7 @@ - + @@ -768,63 +778,63 @@ - + - - - + + + - + - + - + - + - + - + - + - + - + - + - + @@ -834,7 +844,7 @@ - + @@ -944,8 +954,8 @@ - - + + @@ -974,13 +984,13 @@ - + - + @@ -994,10 +1004,10 @@ - - + + - + @@ -1030,9 +1040,9 @@ - - - + + + @@ -1045,11 +1055,11 @@ - + - + @@ -1068,11 +1078,15 @@ - - + + + + + + - - + +