[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