diff options
| author | Pavel Labath <labath@google.com> | 2018-07-25 11:55:59 +0000 |
|---|---|---|
| committer | Pavel Labath <labath@google.com> | 2018-07-25 11:55:59 +0000 |
| commit | 7a59e3bf3775ca3ae33501a4c36ab8b66843eba9 (patch) | |
| tree | 497a2d13ed0e9e5c64f0636a1590db122721dc50 /llvm/unittests/DebugInfo | |
| parent | 374af8070eb8f1174d813c21a2d6eb2f25fa8406 (diff) | |
| download | bcm5719-llvm-7a59e3bf3775ca3ae33501a4c36ab8b66843eba9.tar.gz bcm5719-llvm-7a59e3bf3775ca3ae33501a4c36ab8b66843eba9.zip | |
dwarfgen: Add support for generating the debug_str_offsets section
Summary:
The motivation for this is D49493, where we'd like to test details of
debug_str_offsets behavior which is difficult to trigger from a
traditional test.
This adds the plubming necessary for dwarfgen to generate this section.
The more interesting changes are:
- I've moved emitStringOffsetsTableHeader function from DwarfFile to
DwarfStringPool, so I can generate the section header more easily from
the unit test.
- added a new addAttribute overload taking an MCExpr*. This is used to
generate the DW_AT_str_offsets_base, which links a compile unit to the
offset table.
I've also added a basic test for reading and writing DW_form_strx forms.
Reviewers: dblaikie, JDevlieghere, probinson
Subscribers: llvm-commits, aprantl
Differential Revision: https://reviews.llvm.org/D49670
llvm-svn: 337910
Diffstat (limited to 'llvm/unittests/DebugInfo')
| -rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp | 50 | ||||
| -rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp | 32 | ||||
| -rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h | 11 |
3 files changed, 88 insertions, 5 deletions
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp index 6b26318802a..004eafe0092 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -67,12 +67,23 @@ void TestAllForms() { const uint32_t Dwarf32Values[] = {1, 2, 3, 4, 5, 6, 7, 8}; const char *StringValue = "Hello"; const char *StrpValue = "World"; + const char *StrxValue = "Indexed"; + const char *Strx1Value = "Indexed1"; + const char *Strx2Value = "Indexed2"; + const char *Strx3Value = "Indexed3"; + const char *Strx4Value = "Indexed4"; auto ExpectedDG = dwarfgen::Generator::create(Triple, Version); ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded()); dwarfgen::Generator *DG = ExpectedDG.get().get(); dwarfgen::CompileUnit &CU = DG->addCompileUnit(); dwarfgen::DIE CUDie = CU.getUnitDIE(); + + if (Version >= 5) + CUDie.addAttribute(dwarf::DW_AT_str_offsets_base, dwarf::DW_FORM_sec_offset, + MCSymbolRefExpr::create(DG->getStringOffsetsStartSym(), + *DG->getMCContext())); + uint16_t Attr = DW_AT_lo_user; //---------------------------------------------------------------------- @@ -122,6 +133,19 @@ void TestAllForms() { const auto Attr_DW_FORM_string = static_cast<dwarf::Attribute>(Attr++); CUDie.addAttribute(Attr_DW_FORM_string, DW_FORM_string, StringValue); + const auto Attr_DW_FORM_strx = static_cast<dwarf::Attribute>(Attr++); + const auto Attr_DW_FORM_strx1 = static_cast<dwarf::Attribute>(Attr++); + const auto Attr_DW_FORM_strx2 = static_cast<dwarf::Attribute>(Attr++); + const auto Attr_DW_FORM_strx3 = static_cast<dwarf::Attribute>(Attr++); + const auto Attr_DW_FORM_strx4 = static_cast<dwarf::Attribute>(Attr++); + if (Version >= 5) { + CUDie.addAttribute(Attr_DW_FORM_strx, DW_FORM_strx, StrxValue); + CUDie.addAttribute(Attr_DW_FORM_strx1, DW_FORM_strx1, Strx1Value); + CUDie.addAttribute(Attr_DW_FORM_strx2, DW_FORM_strx2, Strx2Value); + CUDie.addAttribute(Attr_DW_FORM_strx3, DW_FORM_strx3, Strx3Value); + CUDie.addAttribute(Attr_DW_FORM_strx4, DW_FORM_strx4, Strx4Value); + } + const auto Attr_DW_FORM_strp = static_cast<dwarf::Attribute>(Attr++); CUDie.addAttribute(Attr_DW_FORM_strp, DW_FORM_strp, StrpValue); @@ -281,11 +305,33 @@ void TestAllForms() { //---------------------------------------------------------------------- auto ExtractedStringValue = toString(DieDG.find(Attr_DW_FORM_string)); EXPECT_TRUE((bool)ExtractedStringValue); - EXPECT_TRUE(strcmp(StringValue, *ExtractedStringValue) == 0); + EXPECT_STREQ(StringValue, *ExtractedStringValue); + + if (Version >= 5) { + auto ExtractedStrxValue = toString(DieDG.find(Attr_DW_FORM_strx)); + EXPECT_TRUE((bool)ExtractedStrxValue); + EXPECT_STREQ(StrxValue, *ExtractedStrxValue); + + auto ExtractedStrx1Value = toString(DieDG.find(Attr_DW_FORM_strx1)); + EXPECT_TRUE((bool)ExtractedStrx1Value); + EXPECT_STREQ(Strx1Value, *ExtractedStrx1Value); + + auto ExtractedStrx2Value = toString(DieDG.find(Attr_DW_FORM_strx2)); + EXPECT_TRUE((bool)ExtractedStrx2Value); + EXPECT_STREQ(Strx2Value, *ExtractedStrx2Value); + + auto ExtractedStrx3Value = toString(DieDG.find(Attr_DW_FORM_strx3)); + EXPECT_TRUE((bool)ExtractedStrx3Value); + EXPECT_STREQ(Strx3Value, *ExtractedStrx3Value); + + auto ExtractedStrx4Value = toString(DieDG.find(Attr_DW_FORM_strx4)); + EXPECT_TRUE((bool)ExtractedStrx4Value); + EXPECT_STREQ(Strx4Value, *ExtractedStrx4Value); + } auto ExtractedStrpValue = toString(DieDG.find(Attr_DW_FORM_strp)); EXPECT_TRUE((bool)ExtractedStrpValue); - EXPECT_TRUE(strcmp(StrpValue, *ExtractedStrpValue) == 0); + EXPECT_STREQ(StrpValue, *ExtractedStrpValue); //---------------------------------------------------------------------- // Test reference forms diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp index b93b0cc9bf9..f4ceda90b07 100644 --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp @@ -54,16 +54,36 @@ void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, uint64_t U) { } void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, + const MCExpr *Expr) { + auto &DG = CU->getGenerator(); + Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form, + DIEExpr(Expr)); +} + +void dwarfgen::DIE::addAttribute(uint16_t A, dwarf::Form Form, StringRef String) { auto &DG = CU->getGenerator(); - if (Form == DW_FORM_string) { + switch (Form) { + case DW_FORM_string: Die->addValue(DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form, new (DG.getAllocator()) DIEInlineString(String, DG.getAllocator())); - } else { + break; + + case DW_FORM_strp: + case DW_FORM_GNU_str_index: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: Die->addValue( DG.getAllocator(), static_cast<dwarf::Attribute>(A), Form, DIEString(DG.getStringPool().getEntry(*DG.getAsmPrinter(), String))); + break; + + default: + llvm_unreachable("Unhandled form!"); } } @@ -427,6 +447,7 @@ llvm::Error dwarfgen::Generator::init(Triple TheTriple, uint16_t V) { Asm->setDwarfVersion(Version); StringPool = llvm::make_unique<DwarfStringPool>(Allocator, *Asm, StringRef()); + StringOffsetsStartSym = Asm->createTempSymbol("str_offsets_base"); return Error::success(); } @@ -448,7 +469,12 @@ StringRef dwarfgen::Generator::generate() { CU->setLength(CUOffset - 4); } Abbreviations.Emit(Asm.get(), MOFI->getDwarfAbbrevSection()); - StringPool->emit(*Asm, MOFI->getDwarfStrSection()); + + StringPool->emitStringOffsetsTableHeader(*Asm, MOFI->getDwarfStrOffSection(), + StringOffsetsStartSym); + StringPool->emit(*Asm, MOFI->getDwarfStrSection(), + MOFI->getDwarfStrOffSection()); + MS->SwitchSection(MOFI->getDwarfInfoSection()); for (auto &CU : CompileUnits) { uint16_t Version = CU->getVersion(); diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h index 6d41cb53f2c..a1c5d607e23 100644 --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h @@ -89,6 +89,14 @@ public: /// \param U the unsigned integer to encode. void addAttribute(uint16_t Attr, dwarf::Form Form, uint64_t U); + /// Add an attribute value to be encoded as a DIEExpr + /// + /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that + /// represents a user defined DWARF attribute. + /// \param Form the dwarf::Form to use when encoding the attribute. + /// \param Expr the MC expression used to compute the value + void addAttribute(uint16_t Attr, dwarf::Form Form, const MCExpr *Expr); + /// Add an attribute value to be encoded as a DIEString or DIEInlinedString. /// /// \param Attr a dwarf::Attribute enumeration value or any uint16_t that @@ -242,6 +250,8 @@ class Generator { std::vector<std::unique_ptr<LineTable>> LineTables; DIEAbbrevSet Abbreviations; + MCSymbol *StringOffsetsStartSym; + SmallString<4096> FileBytes; /// The stream we use to generate the DWARF into as an ELF file. std::unique_ptr<raw_svector_ostream> Stream; @@ -293,6 +303,7 @@ public: MCContext *getMCContext() const { return MC.get(); } DIEAbbrevSet &getAbbrevSet() { return Abbreviations; } DwarfStringPool &getStringPool() { return *StringPool; } + MCSymbol *getStringOffsetsStartSym() const { return StringOffsetsStartSym; } /// Save the generated DWARF file to disk. /// |

