[llvm] c87d405 - [DWARF] Add API to get data from MCDwarfLineStr

Alexander Yermolovich via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 14:08:44 PDT 2022


Author: Alexander Yermolovich
Date: 2022-04-21T14:08:20-07:00
New Revision: c87d405b22474877288b8356175061c1fb02fcba

URL: https://github.com/llvm/llvm-project/commit/c87d405b22474877288b8356175061c1fb02fcba
DIFF: https://github.com/llvm/llvm-project/commit/c87d405b22474877288b8356175061c1fb02fcba.diff

LOG: [DWARF] Add API to get data from MCDwarfLineStr

This API will be used in D121876, to get finalized string data for
.debug_line_str.

Reviewed By: dblaikie, rafauler

Differential Revision: https://reviews.llvm.org/D124052

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCDwarf.h
    llvm/include/llvm/MC/StringTableBuilder.h
    llvm/lib/MC/MCDwarf.cpp
    llvm/unittests/MC/DwarfLineTableHeaders.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 79ad4aefd0440..a4f08b40b33c7 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -62,6 +62,9 @@ class MCDwarfLineStr {
 
   /// Emit the .debug_line_str section if appropriate.
   void emitSection(MCStreamer *MCOS);
+
+  /// Returns finalized section.
+  SmallString<0> getFinalizedData();
 };
 
 /// Instances of this class represent the name of the dwarf .file directive and

diff  --git a/llvm/include/llvm/MC/StringTableBuilder.h b/llvm/include/llvm/MC/StringTableBuilder.h
index 3f9c91be05d35..42133f3f77265 100644
--- a/llvm/include/llvm/MC/StringTableBuilder.h
+++ b/llvm/include/llvm/MC/StringTableBuilder.h
@@ -85,7 +85,6 @@ class StringTableBuilder {
   void write(raw_ostream &OS) const;
   void write(uint8_t *Buf) const;
 
-private:
   bool isFinalized() const { return Finalized; }
 };
 

diff  --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index f2e92fe007a8a..0f45f2f079b26 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -334,12 +334,18 @@ void MCDwarfLineStr::emitSection(MCStreamer *MCOS) {
   // Switch to the .debug_line_str section.
   MCOS->SwitchSection(
       MCOS->getContext().getObjectFileInfo()->getDwarfLineStrSection());
+  SmallString<0> Data = getFinalizedData();
+  MCOS->emitBinaryData(Data.str());
+}
+
+SmallString<0> MCDwarfLineStr::getFinalizedData() {
   // Emit the strings without perturbing the offsets we used.
-  LineStrings.finalizeInOrder();
+  if (!LineStrings.isFinalized())
+    LineStrings.finalizeInOrder();
   SmallString<0> Data;
   Data.resize(LineStrings.getSize());
   LineStrings.write((uint8_t *)Data.data());
-  MCOS->emitBinaryData(Data.str());
+  return Data;
 }
 
 void MCDwarfLineStr::emitRef(MCStreamer *MCOS, StringRef Path) {

diff  --git a/llvm/unittests/MC/DwarfLineTableHeaders.cpp b/llvm/unittests/MC/DwarfLineTableHeaders.cpp
index 24fd246bbd3be..b68593531943d 100644
--- a/llvm/unittests/MC/DwarfLineTableHeaders.cpp
+++ b/llvm/unittests/MC/DwarfLineTableHeaders.cpp
@@ -131,8 +131,13 @@ class DwarfLineTableHeaders : public ::testing::Test {
     LineEntries.push_back(LineEntry);
     MCDwarfLineTable::emitOne(TheStreamer, Section, LineEntries);
     TheStreamer->emitLabel(LineEndSym);
-    if (LineStr)
-      LineStr->emitSection(TheStreamer);
+    if (LineStr) {
+      SmallString<0> Data = LineStr->getFinalizedData();
+      TheStreamer->SwitchSection(TheStreamer->getContext()
+                                     .getObjectFileInfo()
+                                     ->getDwarfLineStrSection());
+      TheStreamer->emitBinaryData(Data.str());
+    }
   }
 
   /// Check contents of .debug_line section
@@ -156,15 +161,37 @@ class DwarfLineTableHeaders : public ::testing::Test {
     llvm_unreachable(".debug_line not found");
   }
 
+  /// Check contents of .debug_line_str section
+  void verifyDebugLineStrContents(const llvm::object::ObjectFile &E) {
+    for (const llvm::object::SectionRef &Section : E.sections()) {
+      Expected<StringRef> SectionNameOrErr = Section.getName();
+      ASSERT_TRUE(static_cast<bool>(SectionNameOrErr));
+      StringRef SectionName = *SectionNameOrErr;
+      if (SectionName.empty() || SectionName != ".debug_line_str")
+        continue;
+      Expected<StringRef> ContentsOrErr = Section.getContents();
+      ASSERT_TRUE(static_cast<bool>(ContentsOrErr));
+      StringRef Contents = *ContentsOrErr;
+      ASSERT_TRUE(Contents.find("dir") != StringRef::npos);
+      ASSERT_TRUE(Contents.find("file") != StringRef::npos);
+      ASSERT_TRUE(Contents.size() == 9);
+      return;
+    }
+    llvm_unreachable(".debug_line_str not found");
+  }
+
   ///  Open ObjFileData as an object file and read its .debug_line section
-  void readAndCheckDebugLineContents(StringRef ObjFileData,
-                                     ArrayRef<uint8_t> Expected) {
+  void readAndCheckDebugContents(StringRef ObjFileData,
+                                     ArrayRef<uint8_t> Expected, uint8_t DwarfVersion) {
     std::unique_ptr<MemoryBuffer> MB =
         MemoryBuffer::getMemBuffer(ObjFileData, "", false);
     std::unique_ptr<object::Binary> Bin =
         cantFail(llvm::object::createBinary(MB->getMemBufferRef()));
     if (auto *E = dyn_cast<llvm::object::ELFObjectFileBase>(&*Bin)) {
-      return verifyDebugLineContents(*E, Expected);
+      verifyDebugLineContents(*E, Expected);
+      if (DwarfVersion >= 5)
+        verifyDebugLineStrContents(*E);
+      return;
     }
     llvm_unreachable("ELF object file not found");
   }
@@ -178,20 +205,21 @@ TEST_F(DwarfLineTableHeaders, TestDWARF4HeaderEmission) {
   SmallString<0> EmittedBinContents;
   raw_svector_ostream VecOS(EmittedBinContents);
   StreamerContext C = createStreamer(VecOS);
-  C.Ctx->setDwarfVersion(4);
+  constexpr uint8_t DwarfVersion = 4;
+  C.Ctx->setDwarfVersion(DwarfVersion);
   emitDebugLineSection(C);
   C.Streamer->Finish();
-  readAndCheckDebugLineContents(
+  readAndCheckDebugContents(
       EmittedBinContents.str(),
       {/*    Total length=*/0x30, 0, 0, 0,
-       /*   DWARF version=*/4, 0,
+       /*   DWARF version=*/DwarfVersion, 0,
        /* Prologue length=*/0x14, 0, 0, 0,
        /* min_inst_length=*/1,
        /*max_ops_per_inst=*/1,
        /* default_is_stmt=*/DWARF2_LINE_DEFAULT_IS_STMT,
        /*       line_base=*/static_cast<uint8_t>(-5),
        /*      line_range=*/14,
-       /*     opcode_base=*/13});
+       /*     opcode_base=*/13}, DwarfVersion);
 }
 
 TEST_F(DwarfLineTableHeaders, TestDWARF5HeaderEmission) {
@@ -201,13 +229,14 @@ TEST_F(DwarfLineTableHeaders, TestDWARF5HeaderEmission) {
   SmallString<0> EmittedBinContents;
   raw_svector_ostream VecOS(EmittedBinContents);
   StreamerContext C = createStreamer(VecOS);
-  C.Ctx->setDwarfVersion(5);
+  constexpr uint8_t DwarfVersion = 5;
+  C.Ctx->setDwarfVersion(DwarfVersion);
   emitDebugLineSection(C);
   C.Streamer->Finish();
-  readAndCheckDebugLineContents(
+  readAndCheckDebugContents(
       EmittedBinContents.str(),
       {/*    Total length=*/0x43, 0, 0, 0,
-       /*   DWARF version=*/5, 0,
+       /*   DWARF version=*/DwarfVersion, 0,
        /*        ptr size=*/8,
        /*         segment=*/0,
        /* Prologue length=*/0x25, 0, 0, 0,
@@ -216,5 +245,5 @@ TEST_F(DwarfLineTableHeaders, TestDWARF5HeaderEmission) {
        /* default_is_stmt=*/DWARF2_LINE_DEFAULT_IS_STMT,
        /*       line_base=*/static_cast<uint8_t>(-5),
        /*      line_range=*/14,
-       /*     opcode_base=*/13});
+       /*     opcode_base=*/13}, DwarfVersion);
 }


        


More information about the llvm-commits mailing list