aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
index 63c1886..0c973c3 100644
--- a/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/DebuggerSupportPlugin.cpp
@@ -16,6 +16,10 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+
+#include <chrono>
#define DEBUG_TYPE "orc"
@@ -97,8 +101,6 @@ public:
<< "\n";
});
- auto &SDOSec = G.createSection(SynthDebugSectionName, MemProt::Read);
-
for (auto &Sec : G.sections()) {
if (Sec.blocks().empty())
continue;
@@ -114,6 +116,10 @@ public:
NonDebugSections.push_back({&Sec, nullptr});
}
+ // Bail out early if no debug sections.
+ if (DebugSections.empty())
+ return Error::success();
+
// Write MachO header and debug section load commands.
Builder.Header.filetype = MachO::MH_OBJECT;
switch (G.getTargetTriple().getArch()) {
@@ -131,15 +137,51 @@ public:
Seg = &Builder.addSegment("");
+ StringMap<std::unique_ptr<MemoryBuffer>> DebugSectionMap;
+ StringRef DebugLineSectionData;
for (auto &DSec : DebugSections) {
auto [SegName, SecName] = DSec.GraphSec->getName().split(',');
DSec.BuilderSec = &Seg->addSection(SecName, SegName);
SectionRange SR(*DSec.GraphSec);
DSec.BuilderSec->Content.Size = SR.getSize();
- if (!SR.empty())
+ if (!SR.empty()) {
DSec.BuilderSec->align = Log2_64(SR.getFirstBlock()->getAlignment());
+ StringRef SectionData(SR.getFirstBlock()->getContent().data(),
+ SR.getFirstBlock()->getSize());
+ DebugSectionMap[SecName] =
+ MemoryBuffer::getMemBuffer(SectionData, G.getName(), false);
+ if (SecName == "__debug_line")
+ DebugLineSectionData = SectionData;
+ }
+ }
+
+ if (DebugLineSectionData.empty())
+ return make_error<StringError>(G.getName() +
+ " has debug info but no line table",
+ inconvertibleErrorCode());
+
+ // Add Stabs.
+ auto DWARFCtx = DWARFContext::create(DebugSectionMap, G.getPointerSize(),
+ G.getEndianness());
+ DWARFDataExtractor DebugLineData(
+ DebugLineSectionData, G.getEndianness() == support::endianness::little,
+ G.getPointerSize());
+ uint64_t Offset = 0;
+ DWARFDebugLine::LineTable LineTable;
+ if (auto Err = LineTable.parse(DebugLineData, &Offset, *DWARFCtx, nullptr,
+ consumeError))
+ return Err;
+
+ Builder.addSymbol("", MachO::N_SO, 0, 0, 0);
+ for (auto &FN : LineTable.Prologue.FileNames) {
+ if (auto Name = dwarf::toString(FN.Name))
+ Builder.addSymbol(*Name, MachO::N_SO, 0, 0, 0);
}
+ auto TimeStamp = std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
+ Builder.addSymbol("", MachO::N_OSO, 3, 1, TimeStamp);
for (auto &NDSP : NonDebugSections) {
auto [SegName, SecName] = NDSP.GraphSec->getName().split(',');
@@ -164,8 +206,12 @@ public:
}
}
+ Builder.addSymbol("", MachO::N_SO, 1, 0, 0);
+
+ // Lay out the debug object, create a section and block for it.
size_t DebugObjectSize = Builder.layout();
+ auto &SDOSec = G.createSection(SynthDebugSectionName, MemProt::Read);
MachOContainerBlock = &G.createMutableContentBlock(
SDOSec, G.allocateBuffer(DebugObjectSize), orc::ExecutorAddr(), 8, 0);