Reapply r246012 [dsymutil] Emit real dSYM companion binaries.
With a fix for big endian machines. Thanks to Daniel Sanders for the debugging!
Original commit message:
The binaries containing the linked DWARF generated by dsymutil are not
standard relocatable object files like emitted did previsously. They should be
dSYM companion files, which means they have a different file type in the
header, but also a couple other peculiarities:
- they contain the segments and sections from the original binary in their
load commands, but not the actual contents. This means they get an address
and a size, but their offset is always 0 (but these are not virtual sections)
- they also conatin all the defined symbols from the original binary
This makes MC a really bad fit to emit these kind of binaries. The approach
that was used in this patch is to leverage MC's section layout for the
debug sections, but to use a replacement for MachObjectWriter that lives
in MachOUtils.cpp. Some of the low-level helpers from MachObjectWriter
were reused too.
llvm-svn: 246673
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index ed06dba..84e4e4b 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -10,6 +10,7 @@
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "dsymutil.h"
+#include "MachOUtils.h"
#include "NonRelocatableStringpool.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/StringMap.h"
@@ -475,7 +476,7 @@
bool init(Triple TheTriple, StringRef OutputFilename);
/// \brief Dump the file to the disk.
- bool finish();
+ bool finish(const DebugMap &);
AsmPrinter &getAsmPrinter() const { return *Asm; }
@@ -617,7 +618,10 @@
return true;
}
-bool DwarfStreamer::finish() {
+bool DwarfStreamer::finish(const DebugMap &DM) {
+ if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty())
+ return MachOUtils::generateDsymCompanion(DM, *MS, *OutFile);
+
MS->Finish();
return true;
}
@@ -3057,7 +3061,7 @@
Streamer->emitStrings(StringPool);
}
- return Options.NoOutput ? true : Streamer->finish();
+ return Options.NoOutput ? true : Streamer->finish(Map);
}
}