This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Fix a misleading usage of DWARF forms with DIEExpr. NFC.
ClosedPublic

Authored by ikudrin on Jul 16 2020, 8:46 AM.

Details

Summary

For now, DIEExpr is used only in two places:

  1. in the debug info library unit test suite to emit a DW_AT_str_offsets_base attribute with the DW_FORM_sec_offset form, see dwarfgen::DIE::addStrOffsetsBaseAttribute();
  2. in DwarfCompileUnit::addLocationAttribute() to generate the location attribute for a TLS variable.

The later case used an incorrect DWARF form of DW_FORM_udata, which implies storing an uleb128 value, not a 4/8 byte constant. The generated result was as expected because DIEExpr::SizeOf() did not handle the used form, but returned the size of the code pointer by default.

The patch fixes the issue by using more appropriate DWARF forms for the problematic case and making DIEExpr::SizeOf() more straightforward.

Diff Detail

Event Timeline

ikudrin created this revision.Jul 16 2020, 8:46 AM

I guess this change is NFC? The observable behavior (the exact bits) produced by LLVM remains the same - because, even though the form changed, blocks don't actually have forms, it's just a way for us to internally communicate how things should be encoded?

(I guess if we had a really big TLS symbol location then the ULEB encoding would be a problem? Hmm - actually, if sizeof() does the right thing, but the code that actually wrote the value wrote it out as ULEB, wouldn't that throw off the whole encoding & not write enough bytes to the block? That sounds like it'd be testable in some form? (later ops wouldn't be at the right byte offset, or the whole DWARF emission would be a bit short & throw off everything?))

The change is NFC (NFCI?). The form is ignored in DIEExpr::emitValue() and only the result of SizeOf() is used, which returned the expected value because it used AP->getPointerSize() for unhandled forms. All the construction is quite fragile and worked only thanks to the fortune.

dblaikie accepted this revision.Jul 16 2020, 8:54 PM

The change is NFC (NFCI?).

Yeah, always intent is the best we can do, really.

The form is ignored in DIEExpr::emitValue() and only the result of SizeOf() is used, which returned the expected value because it used AP->getPointerSize() for unhandled forms. All the construction is quite fragile and worked only thanks to the fortune.

Oh, form isn't ignored exactly - but it's used via SizeOf so the bug is symmetric: if SizeOf got the size wrong, at least it'd get it wrong both in the layout code that needed to know the size ahead of time, and in the bytes being emitted - so you wouldn't end up with the output being weirdly the wrong length compared to other lengths/offsets/etc used in the DWARF.

Makes sense. Thanks for the patch/explanation.

This revision is now accepted and ready to land.Jul 16 2020, 8:54 PM
This revision was automatically updated to reflect the committed changes.