aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksei Vetrov <vvvvvv@google.com>2023-12-12 22:04:40 +0000
committerGiuliano Procida <gprocida@google.com>2023-12-13 11:25:58 +0000
commit7979d57ad006d679c8ad6dcee1b9a9d31a3ff8d3 (patch)
tree888ca6b24fd50016311990d7143fd857a122a511
parent20fb84fcd511d8f92e27444f4357334d5d55d05e (diff)
downloadstg-7979d57ad006d679c8ad6dcee1b9a9d31a3ff8d3.tar.gz
DWARF processor: treat empty location expression as no location
Change `GetExpression` to `MaybeGetExpression`, which returns an empty optional if the expression is empty. Handle this the same as "attribute is not present" in `MaybeGetExpression` callers. According to the DWARF 5 standard: > If no location attribute is present in a variable entry representing > the definition of a variable (that is, with no DW_AT_declaration > attribute), or if the location attribute is present but has an empty > location description (as described in Section 2.6 on page 38), the > variable is assumed to exist in the source code but not in the > executable program. So according to the standard, an empty DWARF location expression is equivalent to "no location attribute is present". PiperOrigin-RevId: 590329297 Change-Id: Ia09b078d1a4acaa93e50c3ab9f9b0985b1598043
-rw-r--r--dwarf_wrappers.cc30
1 files changed, 24 insertions, 6 deletions
diff --git a/dwarf_wrappers.cc b/dwarf_wrappers.cc
index e5780eb..d13d7b8 100644
--- a/dwarf_wrappers.cc
+++ b/dwarf_wrappers.cc
@@ -129,13 +129,19 @@ struct Expression {
size_t length = 0;
};
-Expression GetExpression(Dwarf_Attribute& attribute) {
+std::optional<Expression> MaybeGetExpression(Dwarf_Attribute& attribute) {
Expression result;
Check(dwarf_getlocation(&attribute, &result.atoms, &result.length) ==
kReturnOk) << "dwarf_getlocation returned error";
- Check(result.atoms != nullptr && result.length > 0)
- << "dwarf_getlocation returned empty expression";
+ // If no location attribute is present or has an empty location description,
+ // the variable is present in the source but not in the object code.
+ // So zero length expression is equivalent of no location attribute.
+ if (result.length == 0) {
+ return std::nullopt;
+ }
+ Check(result.atoms != nullptr)
+ << "dwarf_getlocation returned non-empty expression with NULL atoms";
return result;
}
@@ -298,7 +304,11 @@ std::optional<Entry> Entry::MaybeGetReference(uint32_t attribute) {
namespace {
std::optional<Address> GetAddressFromLocation(Dwarf_Attribute& attribute) {
- const auto expression = GetExpression(attribute);
+ const auto expression_opt = MaybeGetExpression(attribute);
+ if (!expression_opt) {
+ return {};
+ }
+ const Expression& expression = *expression_opt;
Dwarf_Attribute result_attribute;
if (dwarf_getlocation_attr(&attribute, expression.atoms, &result_attribute) ==
@@ -360,7 +370,11 @@ std::optional<uint64_t> Entry::MaybeGetMemberByteOffset() {
}
// Parse location expression
- const auto expression = GetExpression(attribute.value());
+ const auto expression_opt = MaybeGetExpression(attribute.value());
+ if (!expression_opt) {
+ return {};
+ }
+ const Expression& expression = *expression_opt;
// Parse virtual base classes offset, which looks like this:
// [0] = DW_OP_dup
@@ -394,7 +408,11 @@ std::optional<uint64_t> Entry::MaybeGetVtableOffset() {
}
// Parse location expression
- const Expression expression = GetExpression(attribute.value());
+ const auto expression_opt = MaybeGetExpression(attribute.value());
+ if (!expression_opt) {
+ return {};
+ }
+ const Expression& expression = *expression_opt;
// We expect compilers to produce expression with one constant operand
if (expression.length == 1) {