aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2023-09-22 10:38:07 -0700
committerLang Hames <lhames@gmail.com>2023-09-22 10:56:40 -0700
commitdb51e572893e9e4403d65920dc5e87a8885b059c (patch)
tree1b96274b97885b33d5ec4ce41e59e962b31153d5
parenta12c2977debb640d2e694c72ed74344d366d89ae (diff)
downloadllvm-db51e572893e9e4403d65920dc5e87a8885b059c.zip
llvm-db51e572893e9e4403d65920dc5e87a8885b059c.tar.gz
llvm-db51e572893e9e4403d65920dc5e87a8885b059c.tar.bz2
[ORC] Add N_SO and N_OSO stabs entries to MachO debug objects.
No testcase: This code generates an in-memory object file that is shared with the debugger. The object file is malformed in ways that don't matter to the debugger, but mean that it can't be inspected by most tools.
-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);