folly icon indicating copy to clipboard operation
folly copied to clipboard

symbolizer::findDefinitionDie returns incorrect DW_AT_specification offset for DW_FORM_ref_addr

Open joelhock opened this issue 7 months ago • 0 comments

symbolizer::findDefinitionDie unconditionally adds cu.offset to the offset returned by getAttribute<uint64_t>(cu, die, DW_AT_specification). in my gcc14-compiled binaries, that is usually correct since the DW_AT_specification is specified as DW_FORM_sdata, but sometimes it is represented as DW_FORM_ref_addr, in which case it is an absolute offset form the beginning of the .debug_info section (this is according to https://github.com/eliben/pyelftools/issues/241#issuecomment-565637775 ). this issue caused a an out-of-bounds FOLLY_SAFE_CHECK(sp.size() >= sizeof(T), "underflow"); in read.

a small patch to readAttribute fixes my use case, but i'm not sure it's completely proper, especially since it causes the Attribute's uint64_t attrValue to be negative:

     case DW_FORM_ref_addr:
-      return {spec, die, readOffset(info, die.is64Bit)};
+    {
+      uint64_t rawval = readOffset(info, die.is64Bit);
+      if(spec.name == DW_AT_specification) {
+        // A DW_AT_specification attribute is of class reference, and a
+        // reference is relative to the first byte of the cu header unless its
+        // of form DW_AT_refaddr, where its relative to the .debug_info section.
+        rawval -= cu.offset;
+      }
+      return {spec, die, rawval};
+    }

joelhock avatar May 30 '25 14:05 joelhock