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);
 }
 }