[lld] r218703 - [mach-o] create __unwind_info section on x86_64

Tim Northover tnorthover at apple.com
Tue Sep 30 14:29:55 PDT 2014


Author: tnorthover
Date: Tue Sep 30 16:29:54 2014
New Revision: 218703

URL: http://llvm.org/viewvc/llvm-project?rev=218703&view=rev
Log:
[mach-o] create __unwind_info section on x86_64

This is a minimally useful pass to construct the __unwind_info section in a
final object from the various __compact_unwind inputs. Currently it doesn't
produce any compressed pages, only works for x86_64 and will fail if any
function ends up without __compact_unwind.

rdar://problem/18208653

Added:
    lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
    lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
Modified:
    lld/trunk/include/lld/Core/DefinedAtom.h
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Core/DefinedAtom.cpp
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
    lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
    lld/trunk/test/mach-o/exe-offsets.yaml
    lld/trunk/test/mach-o/exe-segment-overlap.yaml

Modified: lld/trunk/include/lld/Core/DefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Sep 30 16:29:54 2014
@@ -137,6 +137,7 @@ public:
     typeDTraceDOF,          // runtime data for Dtrace [Darwin]
     typeTempLTO,            // temporary atom for bitcode reader
     typeCompactUnwindInfo,  // runtime data for unwinder [Darwin]
+    typeProcessedUnwindInfo,// compressed compact unwind info [Darwin]
     typeThunkTLV,           // thunk used to access a TLV [Darwin]
     typeTLVInitialData,     // initial data for a TLV [Darwin]
     typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Sep 30 16:29:54 2014
@@ -214,6 +214,9 @@ public:
   // GOT creation Pass should be run.
   bool needsGOTPass() const;
 
+  /// Pass to transform __compact_unwind into __unwind_info should be run.
+  bool needsCompactUnwindPass() const;
+
   /// Magic symbol name stubs will need to help lazy bind.
   StringRef binderSymbolName() const;
 

Modified: lld/trunk/lib/Core/DefinedAtom.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/DefinedAtom.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/Core/DefinedAtom.cpp (original)
+++ lld/trunk/lib/Core/DefinedAtom.cpp Tue Sep 30 16:29:54 2014
@@ -41,6 +41,7 @@ DefinedAtom::ContentPermissions DefinedA
   case typeLiteral16:
   case typeDTraceDOF:
   case typeCompactUnwindInfo:
+  case typeProcessedUnwindInfo:
   case typeRONote:
   case typeNoAlloc:
     return permR__;

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h Tue Sep 30 16:29:54 2014
@@ -53,6 +53,20 @@ public:
   /// Used by GOTPass to update GOT References
   virtual void updateReferenceToGOT(const Reference *, bool targetIsNowGOT) {}
 
+  /// Does this architecture make use of __unwind_info sections for exception
+  /// handling? If so, it will need a separate pass to create them.
+  virtual bool needsCompactUnwind() = 0;
+
+  /// Returns the kind of reference to use to synthesize a 32-bit image-offset
+  /// value, used in the __unwind_info section.
+  virtual Reference::KindValue imageOffsetKind() = 0;
+
+  /// Returns the kind of reference to use to synthesize a 32-bit image-offset
+  /// indirect value. Used for personality functions in the __unwind_info
+  /// section.
+  virtual Reference::KindValue imageOffsetKindIndirect() = 0;
+
+
   /// Used by normalizedFromAtoms() to know where to generated rebasing and 
   /// binding info in final executables.
   virtual bool isPointer(const Reference &) = 0;
@@ -126,6 +140,7 @@ public:
   /// Copy raw content then apply all fixup References on an Atom.
   virtual void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                                    FindAddressForAtom findAddress,
+                                   uint64_t imageBaseAddress,
                                    uint8_t *atomContentBuffer) = 0;
 
   /// Used in -r mode to convert a Reference to a mach-o relocation.

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Tue Sep 30 16:29:54 2014
@@ -36,6 +36,17 @@ public:
   bool isCallSite(const Reference &) override;
   bool isPointer(const Reference &) override;
   bool isPairedReloc(const normalized::Relocation &) override;
+
+  bool needsCompactUnwind() override {
+    return false;
+  }
+  Reference::KindValue imageOffsetKind() override {
+    return invalid;
+  }
+  Reference::KindValue imageOffsetKindIndirect() override {
+    return invalid;
+  }
+
   std::error_code getReferenceInfo(const normalized::Relocation &reloc,
                                    const DefinedAtom *inAtom,
                                    uint32_t offsetInAtom,
@@ -59,6 +70,7 @@ public:
 
   void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                            FindAddressForAtom findAddress,
+                           uint64_t imageBaseAddress,
                            uint8_t *atomContentBuffer) override;
 
   void appendSectionRelocations(const DefinedAtom &atom,
@@ -904,9 +916,10 @@ void ArchHandler_arm::applyFixupFinal(co
 }
 
 void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom,
-                                           bool relocatable,
-                                           FindAddressForAtom findAddress,
-                                           uint8_t *atomContentBuffer) {
+                                          bool relocatable,
+                                          FindAddressForAtom findAddress,
+                                          uint64_t imageBaseAddress,
+                                          uint8_t *atomContentBuffer) {
   // Copy raw bytes.
   memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
   // Apply fix-ups.

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Tue Sep 30 16:29:54 2014
@@ -76,6 +76,17 @@ public:
   bool isCallSite(const Reference &) override;
   bool isPointer(const Reference &) override;
   bool isPairedReloc(const normalized::Relocation &) override;
+
+  bool needsCompactUnwind() override {
+    return false;
+  }
+  Reference::KindValue imageOffsetKind() override {
+    return invalid;
+  }
+  Reference::KindValue imageOffsetKindIndirect() override {
+    return invalid;
+  }
+
   std::error_code getReferenceInfo(const normalized::Relocation &reloc,
                                    const DefinedAtom *inAtom,
                                    uint32_t offsetInAtom,
@@ -103,6 +114,7 @@ public:
 
   void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                            FindAddressForAtom findAddress,
+                           uint64_t imageBaseAddress,
                            uint8_t *atomContentBuffer) override;
 
   void appendSectionRelocations(const DefinedAtom &atom,
@@ -440,6 +452,7 @@ std::error_code ArchHandler_arm64::getPa
 void ArchHandler_arm64::generateAtomContent(const DefinedAtom &atom,
                                             bool relocatable,
                                             FindAddressForAtom findAddress,
+                                            uint64_t imageBaseAddress,
                                             uint8_t *atomContentBuffer) {
   // Copy raw bytes.
   memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Tue Sep 30 16:29:54 2014
@@ -36,6 +36,17 @@ public:
   bool isCallSite(const Reference &) override;
   bool isPointer(const Reference &) override;
   bool isPairedReloc(const normalized::Relocation &) override;
+
+  bool needsCompactUnwind() override {
+    return false;
+  }
+  Reference::KindValue imageOffsetKind() override {
+    return invalid;
+  }
+  Reference::KindValue imageOffsetKindIndirect() override {
+    return invalid;
+  }
+
   std::error_code getReferenceInfo(const normalized::Relocation &reloc,
                                    const DefinedAtom *inAtom,
                                    uint32_t offsetInAtom,
@@ -59,6 +70,7 @@ public:
 
   void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                            FindAddressForAtom findAddress,
+                           uint64_t imageBaseAddress,
                            uint8_t *atomContentBuffer) override;
 
   void appendSectionRelocations(const DefinedAtom &atom,
@@ -364,9 +376,10 @@ ArchHandler_x86::getPairReferenceInfo(co
 }
 
 void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom,
-                                           bool relocatable,
-                                           FindAddressForAtom findAddress,
-                                           uint8_t *atomContentBuffer) {
+                                          bool relocatable,
+                                          FindAddressForAtom findAddress,
+                                          uint64_t imageBaseAddress,
+                                          uint8_t *atomContentBuffer) {
   // Copy raw bytes.
   memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
   // Apply fix-ups.

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Tue Sep 30 16:29:54 2014
@@ -46,6 +46,9 @@ public:
     case ripRel32Got:
       canBypassGOT = false;
       return true;
+    case imageOffsetGot:
+      canBypassGOT = false;
+      return true;
     default:
       return false;
     }
@@ -55,8 +58,30 @@ public:
   void updateReferenceToGOT(const Reference *ref, bool targetNowGOT) override {
     assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);
     assert(ref->kindArch() == Reference::KindArch::x86_64);
-    const_cast<Reference *>(ref)
+
+    switch (ref->kindValue()) {
+    case ripRel32Got:
+      assert(targetNowGOT && "target must be GOT");
+    case ripRel32GotLoad:
+      const_cast<Reference *>(ref)
         ->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);
+      break;
+    case imageOffsetGot:
+      const_cast<Reference *>(ref)->setKindValue(imageOffset);
+      break;
+    default:
+      llvm_unreachable("unknown GOT reference kind");
+    }
+  }
+
+  bool needsCompactUnwind() override {
+    return true;
+  }
+  Reference::KindValue imageOffsetKind() override {
+    return imageOffset;
+  }
+  Reference::KindValue imageOffsetKindIndirect() override {
+    return imageOffsetGot;
   }
 
   const StubInfo &stubInfo() override { return _sStubInfo; }
@@ -64,6 +89,7 @@ public:
   bool isCallSite(const Reference &) override;
   bool isPointer(const Reference &) override;
   bool isPairedReloc(const normalized::Relocation &) override;
+
   std::error_code getReferenceInfo(const normalized::Relocation &reloc,
                                    const DefinedAtom *inAtom,
                                    uint32_t offsetInAtom,
@@ -91,6 +117,7 @@ public:
 
   void generateAtomContent(const DefinedAtom &atom, bool relocatable,
                            FindAddressForAtom findAddress,
+                           uint64_t imageBase,
                            uint8_t *atomContentBuffer) override;
 
   void appendSectionRelocations(const DefinedAtom &atom,
@@ -130,6 +157,11 @@ private:
                            /// to "leaq _foo(%rip), %rax
     lazyPointer,           /// Location contains a lazy pointer.
     lazyImmediateLocation, /// Location contains immediate value used in stub.
+
+    imageOffset,           /// Location contains offset of atom in final image
+    imageOffsetGot,        /// Location contains offset of GOT entry for atom in
+                           /// final image (typically personality function).
+
   };
 
   Reference::KindValue kindFromReloc(const normalized::Relocation &reloc);
@@ -138,7 +170,7 @@ private:
 
   void applyFixupFinal(const Reference &ref, uint8_t *location,
                        uint64_t fixupAddress, uint64_t targetAddress,
-                       uint64_t inAtomAddress);
+                       uint64_t inAtomAddress, uint64_t imageBaseAddress);
 
   void applyFixupRelocatable(const Reference &ref, uint8_t *location,
                              uint64_t fixupAddress,
@@ -165,6 +197,7 @@ const Registry::KindStrings ArchHandler_
   LLD_KIND_STRING_ENTRY(pointer64), LLD_KIND_STRING_ENTRY(pointer64Anon),
   LLD_KIND_STRING_ENTRY(delta32), LLD_KIND_STRING_ENTRY(delta64),
   LLD_KIND_STRING_ENTRY(delta32Anon), LLD_KIND_STRING_ENTRY(delta64Anon),
+  LLD_KIND_STRING_ENTRY(imageOffset), LLD_KIND_STRING_ENTRY(imageOffsetGot),
   LLD_KIND_STRING_END
 };
 
@@ -382,6 +415,7 @@ ArchHandler_x86_64::getPairReferenceInfo
 void ArchHandler_x86_64::generateAtomContent(const DefinedAtom &atom,
                                              bool relocatable,
                                              FindAddressForAtom findAddress,
+                                             uint64_t imageBaseAddress,
                                              uint8_t *atomContentBuffer) {
   // Copy raw bytes.
   memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
@@ -400,8 +434,8 @@ void ArchHandler_x86_64::generateAtomCon
                                         atomAddress);
     } else {
       applyFixupFinal(*ref, &atomContentBuffer[offset],
-                                  fixupAddress, targetAddress,
-                                  atomAddress);
+                      fixupAddress, targetAddress,
+                      atomAddress, imageBaseAddress);
     }
   }
 }
@@ -410,7 +444,8 @@ void ArchHandler_x86_64::applyFixupFinal
                                          uint8_t *location,
                                          uint64_t fixupAddress,
                                          uint64_t targetAddress,
-                                         uint64_t inAtomAddress) {
+                                         uint64_t inAtomAddress,
+                                         uint64_t imageBaseAddress) {
   if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
     return;
   assert(ref.kindArch() == Reference::KindArch::x86_64);
@@ -455,6 +490,10 @@ void ArchHandler_x86_64::applyFixupFinal
   case lazyImmediateLocation:
     // do nothing
     return;
+  case imageOffset:
+  case imageOffsetGot:
+    write32(*loc32, _swap, (targetAddress - imageBaseAddress) + ref.addend());
+    return;
   case invalid:
     // Fall into llvm_unreachable().
     break;
@@ -514,6 +553,10 @@ void ArchHandler_x86_64::applyFixupReloc
   case lazyImmediateLocation:
     llvm_unreachable("lazy reference kind implies Stubs pass was run");
     return;
+  case imageOffset:
+  case imageOffsetGot:
+    llvm_unreachable("image offset implies __unwind_info");
+    return;
   case invalid:
     // Fall into llvm_unreachable().
     break;
@@ -605,6 +648,10 @@ void ArchHandler_x86_64::appendSectionRe
   case lazyImmediateLocation:
     llvm_unreachable("lazy reference kind implies Stubs pass was run");
     return;
+  case imageOffset:
+  case imageOffsetGot:
+    llvm_unreachable("__unwind_info references should have been resolved");
+    return;
   case invalid:
     // Fall into llvm_unreachable().
     break;

Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Tue Sep 30 16:29:54 2014
@@ -4,6 +4,7 @@ add_lld_library(lldMachO
   ArchHandler_arm64.cpp
   ArchHandler_x86.cpp
   ArchHandler_x86_64.cpp
+  CompactUnwindPass.cpp
   GOTPass.cpp
   MachOLinkingContext.cpp
   MachONormalizedFileBinaryReader.cpp

Added: lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=218703&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (added)
+++ lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp Tue Sep 30 16:29:54 2014
@@ -0,0 +1,456 @@
+//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+//===----------------------------------------------------------------------===//
+
+#include "ArchHandler.h"
+#include "File.h"
+#include "MachOPasses.h"
+#include "MachONormalizedFileBinaryUtils.h"
+
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/File.h"
+#include "lld/Core/LLVM.h"
+#include "lld/Core/Reference.h"
+#include "lld/Core/Simple.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
+
+#define DEBUG_TYPE "macho-compact-unwind"
+
+namespace lld {
+namespace mach_o {
+
+namespace {
+struct CompactUnwindEntry {
+  const Atom *rangeStart;
+  const Atom *personalityFunction;
+  const Atom *lsdaLocation;
+
+  uint32_t rangeLength;
+  uint32_t encoding;
+};
+
+struct UnwindInfoPage {
+  std::vector<CompactUnwindEntry> entries;
+};
+}
+
+class UnwindInfoAtom : public SimpleDefinedAtom {
+public:
+  UnwindInfoAtom(ArchHandler &archHandler, const File &file, bool swap,
+                 std::vector<uint32_t> commonEncodings,
+                 std::vector<const Atom *> personalities,
+                 std::vector<UnwindInfoPage> pages, uint32_t numLSDAs)
+      : SimpleDefinedAtom(file), _archHandler(archHandler),
+        _commonEncodingsOffset(7 * sizeof(uint32_t)),
+        _personalityArrayOffset(_commonEncodingsOffset +
+                                commonEncodings.size() * sizeof(uint32_t)),
+        _topLevelIndexOffset(_personalityArrayOffset +
+                             personalities.size() * sizeof(uint32_t)),
+        _lsdaIndexOffset(_topLevelIndexOffset +
+                         3 * (pages.size() + 1) * sizeof(uint32_t)),
+        _firstPageOffset(_lsdaIndexOffset + 2 * numLSDAs * sizeof(uint32_t)),
+        _swap(swap) {
+
+    addHeader(commonEncodings.size(), personalities.size(), pages.size());
+    addCommonEncodings(commonEncodings);
+    addPersonalityFunctions(personalities);
+    addTopLevelIndexes(pages);
+    addLSDAIndexes(pages, numLSDAs);
+    addSecondLevelPages(pages);
+  }
+
+  ContentType contentType() const override {
+    return DefinedAtom::typeProcessedUnwindInfo;
+  }
+
+  Alignment alignment() const override { return Alignment(2); }
+
+  uint64_t size() const override { return _contents.size(); }
+
+  ContentPermissions permissions() const override {
+    return DefinedAtom::permR__;
+  }
+
+  ArrayRef<uint8_t> rawContent() const override { return _contents; }
+
+  void addHeader(uint32_t numCommon, uint32_t numPersonalities,
+                 uint32_t numPages) {
+    using normalized::write32;
+
+    uint32_t headerSize = 7 * sizeof(uint32_t);
+    _contents.resize(headerSize);
+
+    int32_t *headerEntries = (int32_t *)_contents.data();
+    // version
+    write32(headerEntries[0], _swap, 1);
+    // commonEncodingsArraySectionOffset
+    write32(headerEntries[1], _swap, _commonEncodingsOffset);
+    // commonEncodingsArrayCount
+    write32(headerEntries[2], _swap, numCommon);
+    // personalityArraySectionOffset
+    write32(headerEntries[3], _swap, _personalityArrayOffset);
+    // personalityArrayCount
+    write32(headerEntries[4], _swap, numPersonalities);
+    // indexSectionOffset
+    write32(headerEntries[5], _swap, _topLevelIndexOffset);
+    // indexCount
+    write32(headerEntries[6], _swap, numPages + 1);
+  }
+
+  /// Add the list of common encodings to the section; this is simply an array
+  /// of uint32_t compact values. Size has already been specified in the header.
+  void addCommonEncodings(std::vector<uint32_t> &commonEncodings) {
+    using normalized::write32;
+
+    _contents.resize(_commonEncodingsOffset +
+                     commonEncodings.size() * sizeof(uint32_t));
+    int32_t *commonEncodingsArea =
+        (int32_t *)&_contents[_commonEncodingsOffset];
+
+    for (uint32_t encoding : commonEncodings)
+      write32(*commonEncodingsArea++, _swap, encoding);
+  }
+
+  void addPersonalityFunctions(std::vector<const Atom *> personalities) {
+    _contents.resize(_personalityArrayOffset +
+                     personalities.size() * sizeof(uint32_t));
+
+    for (unsigned i = 0; i < personalities.size(); ++i)
+      addImageReferenceIndirect(_personalityArrayOffset + i * sizeof(uint32_t),
+                                personalities[i]);
+  }
+
+  void addTopLevelIndexes(std::vector<UnwindInfoPage> &pages) {
+    using normalized::write32;
+
+    uint32_t numIndexes = pages.size() + 1;
+    _contents.resize(_topLevelIndexOffset + numIndexes * 3 * sizeof(uint32_t));
+
+    uint32_t pageLoc = _firstPageOffset;
+
+    // The most difficult job here is calculating the LSDAs; everything else
+    // follows fairly naturally, but we can't state where the first
+    int32_t *indexData = (int32_t *)&_contents[_topLevelIndexOffset];
+    uint32_t numLSDAs = 0;
+    for (unsigned i = 0; i < pages.size(); ++i) {
+      // functionOffset
+      addImageReference(_topLevelIndexOffset + 3 * i * sizeof(uint32_t),
+                        pages[i].entries[0].rangeStart);
+      // secondLevelPagesSectionOffset
+      write32(indexData[3 * i + 1], _swap, pageLoc);
+      write32(indexData[3 * i + 2], _swap,
+              _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));
+
+      for (auto &entry : pages[i].entries)
+        if (entry.lsdaLocation)
+          ++numLSDAs;
+    }
+
+    // Finally, write out the final sentinel index
+    CompactUnwindEntry &finalEntry = pages[pages.size() - 1].entries.back();
+    addImageReference(_topLevelIndexOffset +
+                          3 * pages.size() * sizeof(uint32_t),
+                      finalEntry.rangeStart, finalEntry.rangeLength);
+    // secondLevelPagesSectionOffset => 0
+    indexData[3 * pages.size() + 2] =
+        _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t);
+  }
+
+  void addLSDAIndexes(std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs) {
+    _contents.resize(_lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));
+
+    uint32_t curOffset = _lsdaIndexOffset;
+    for (auto &page : pages) {
+      for (auto &entry : page.entries) {
+        if (!entry.lsdaLocation)
+          continue;
+
+        addImageReference(curOffset, entry.rangeStart);
+        addImageReference(curOffset + sizeof(uint32_t), entry.lsdaLocation);
+        curOffset += 2 * sizeof(uint32_t);
+      }
+    }
+  }
+
+  void addSecondLevelPages(std::vector<UnwindInfoPage> &pages) {
+    for (auto &page : pages) {
+      addRegularSecondLevelPage(page);
+    }
+  }
+
+  void addRegularSecondLevelPage(const UnwindInfoPage &page) {
+    uint32_t curPageOffset = _contents.size();
+    const int16_t headerSize = sizeof(uint32_t) + 2 * sizeof(uint16_t);
+    uint32_t curPageSize =
+        headerSize + 2 * page.entries.size() * sizeof(uint32_t);
+    _contents.resize(curPageOffset + curPageSize);
+
+    using normalized::write32;
+    using normalized::write16;
+    // 2 => regular page
+    write32(*(int32_t *)&_contents[curPageOffset], _swap, 2);
+    // offset of 1st entry
+    write16(*(int16_t *)&_contents[curPageOffset + 4], _swap, headerSize);
+    write16(*(int16_t *)&_contents[curPageOffset + 6], _swap,
+            page.entries.size());
+
+    uint32_t pagePos = curPageOffset + headerSize;
+    for (auto &entry : page.entries) {
+      addImageReference(pagePos, entry.rangeStart);
+      write32(reinterpret_cast<int32_t *>(_contents.data() + pagePos)[1], _swap,
+              entry.encoding);
+      pagePos += 2 * sizeof(uint32_t);
+    }
+  }
+
+  void addImageReference(uint32_t offset, const Atom *dest,
+                         Reference::Addend addend = 0) {
+    addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
+                 _archHandler.imageOffsetKind(), offset, dest, addend);
+  }
+
+  void addImageReferenceIndirect(uint32_t offset, const Atom *dest) {
+    addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
+                 _archHandler.imageOffsetKindIndirect(), offset, dest, 0);
+  }
+
+private:
+  mach_o::ArchHandler &_archHandler;
+  std::vector<uint8_t> _contents;
+  uint32_t _commonEncodingsOffset;
+  uint32_t _personalityArrayOffset;
+  uint32_t _topLevelIndexOffset;
+  uint32_t _lsdaIndexOffset;
+  uint32_t _firstPageOffset;
+  bool _swap;
+};
+
+/// Pass for instantiating and optimizing GOT slots.
+///
+class CompactUnwindPass : public Pass {
+public:
+  CompactUnwindPass(const MachOLinkingContext &context)
+      : _context(context), _archHandler(_context.archHandler()),
+        _file("<mach-o Compact Unwind Pass>"),
+        _swap(!MachOLinkingContext::isHostEndian(_context.arch())) {}
+
+private:
+  void perform(std::unique_ptr<MutableFile> &mergedFile) override {
+    DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");
+
+    // First collect all __compact_unwind entries, addressable by the function
+    // it's referring to.
+    std::map<const Atom *, CompactUnwindEntry> unwindLocs;
+    std::vector<const Atom *> personalities;
+    uint32_t numLSDAs = 0;
+
+    collectCompactUnwindEntries(mergedFile, unwindLocs, personalities,
+                                numLSDAs);
+
+    // FIXME: if there are more than 4 personality functions then we need to
+    // defer to DWARF info for the ones we don't put in the list. They should
+    // also probably be sorted by frequency.
+    assert(personalities.size() <= 4);
+
+    // Now sort the entries by final address and fixup the compact encoding to
+    // its final form (i.e. set personality function bits & create DWARF
+    // references where needed).
+    std::vector<CompactUnwindEntry> unwindInfos =
+        createUnwindInfoEntries(mergedFile, unwindLocs, personalities);
+
+    // Finally, we can start creating pages based on these entries.
+
+    DEBUG(llvm::dbgs() << "  Splitting entries into pages\n");
+    // FIXME: we split the entries into pages naively: lots of 4k pages followed
+    // by a small one. ld64 tried to minimize space and align them to real 4k
+    // boundaries. That might be worth doing, or perhaps we could perform some
+    // minor balancing for expected number of lookups.
+    std::vector<UnwindInfoPage> pages;
+    unsigned pageStart = 0;
+    do {
+      pages.push_back(UnwindInfoPage());
+
+      // FIXME: we only create regular pages at the moment. These can hold up to
+      // 1021 entries according to the documentation.
+      unsigned entriesInPage =
+          std::min(1021U, (unsigned)unwindInfos.size() - pageStart);
+
+      std::copy(unwindInfos.begin() + pageStart,
+                unwindInfos.begin() + pageStart + entriesInPage,
+                std::back_inserter(pages.back().entries));
+      pageStart += entriesInPage;
+
+      DEBUG(llvm::dbgs()
+            << "    Page from " << pages.back().entries[0].rangeStart->name()
+            << " to " << pages.back().entries.back().rangeStart->name() << " + "
+            << llvm::format("0x%x", pages.back().entries.back().rangeLength)
+            << " has " << entriesInPage << " entries\n");
+    } while (pageStart < unwindInfos.size());
+
+    // FIXME: we should also erase all compact-unwind atoms; their job is done.
+    UnwindInfoAtom *unwind = new (_file.allocator())
+        UnwindInfoAtom(_archHandler, _file, _swap, std::vector<uint32_t>(),
+                       personalities, pages, numLSDAs);
+    mergedFile->addAtom(*unwind);
+  }
+
+  void collectCompactUnwindEntries(
+      std::unique_ptr<MutableFile> &mergedFile,
+      std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
+      std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {
+    DEBUG(llvm::dbgs() << "  Collecting __compact_unwind entries\n");
+
+    for (const DefinedAtom *atom : mergedFile->defined()) {
+      if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo)
+        continue;
+
+      auto unwindEntry = extractCompactUnwindEntry(atom);
+      unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry));
+
+      DEBUG(llvm::dbgs() << "    Entry for " << unwindEntry.rangeStart->name()
+                         << ", encoding="
+                         << llvm::format("0x%08x", unwindEntry.encoding));
+      if (unwindEntry.personalityFunction)
+        DEBUG(llvm::dbgs() << ", personality="
+                           << unwindEntry.personalityFunction->name()
+                           << ", lsdaLoc=" << unwindEntry.lsdaLocation->name());
+      DEBUG(llvm::dbgs() << '\n');
+
+      // Count number of LSDAs we see, since we need to know how big the index
+      // will be while laying out the section.
+      if (unwindEntry.lsdaLocation)
+        ++numLSDAs;
+
+      // Gather the personality functions now, so that they're in deterministic
+      // order (derived from the DefinedAtom order).
+      if (unwindEntry.personalityFunction) {
+        auto pFunc = std::find(personalities.begin(), personalities.end(),
+                               unwindEntry.personalityFunction);
+        if (pFunc == personalities.end())
+          personalities.push_back(unwindEntry.personalityFunction);
+      }
+    }
+  }
+
+  CompactUnwindEntry extractCompactUnwindEntry(const DefinedAtom *atom) {
+    CompactUnwindEntry entry = {nullptr, nullptr, nullptr, 0, 0};
+
+    for (const Reference *ref : *atom) {
+      switch (ref->offsetInAtom()) {
+      case 0:
+        // FIXME: there could legitimately be functions with multiple encoding
+        // entries. However, nothing produces them at the moment.
+        assert(ref->addend() == 0 && "unexpected offset into function");
+        entry.rangeStart = ref->target();
+        break;
+      case 0x10:
+        assert(ref->addend() == 0 && "unexpected offset into personality fn");
+        entry.personalityFunction = ref->target();
+        break;
+      case 0x18:
+        assert(ref->addend() == 0 && "unexpected offset into LSDA atom");
+        entry.lsdaLocation = ref->target();
+        break;
+      }
+    }
+
+    using normalized::read32;
+    entry.rangeLength =
+        read32(_swap, ((uint32_t *)atom->rawContent().data())[2]);
+    entry.encoding = read32(_swap, ((uint32_t *)atom->rawContent().data())[3]);
+    return entry;
+  }
+
+  /// Every atom defined in __TEXT,__text needs an entry in the final
+  /// __unwind_info section (in order). These comes from two sources:
+  ///   + Input __compact_unwind sections where possible (after adding the
+  ///      personality function offset which is only known now).
+  ///   + A synthesised reference to __eh_frame if there's no __compact_unwind
+  ///     or too many personality functions to be accommodated.
+  std::vector<CompactUnwindEntry> createUnwindInfoEntries(
+      const std::unique_ptr<MutableFile> &mergedFile,
+      const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
+      const std::vector<const Atom *> &personalities) {
+    std::vector<CompactUnwindEntry> unwindInfos;
+
+    DEBUG(llvm::dbgs() << "  Creating __unwind_info entries\n");
+    // The final order in the __unwind_info section must be derived from the
+    // order of typeCode atoms, since that's how they'll be put into the object
+    // file eventually (yuck!).
+    for (const DefinedAtom *atom : mergedFile->defined()) {
+      if (atom->contentType() != DefinedAtom::typeCode)
+        continue;
+
+      unwindInfos.push_back(
+          finalizeUnwindInfoEntryForAtom(atom, unwindLocs, personalities));
+
+      DEBUG(llvm::dbgs() << "    Entry for " << atom->name()
+                         << ", final encoding="
+                         << llvm::format("0x%08x", unwindInfos.back().encoding)
+                         << '\n');
+    }
+
+    return unwindInfos;
+  }
+
+  CompactUnwindEntry finalizeUnwindInfoEntryForAtom(
+      const DefinedAtom *function,
+      const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
+      const std::vector<const Atom *> &personalities) {
+    auto unwindLoc = unwindLocs.find(function);
+
+    // FIXME: we should synthesize a DWARF compact unwind entry before claiming
+    // there's no unwind if a __compact_unwind atom doesn't exist.
+    if (unwindLoc == unwindLocs.end()) {
+      CompactUnwindEntry entry;
+      memset(&entry, 0, sizeof(CompactUnwindEntry));
+      entry.rangeStart = function;
+      entry.rangeLength = function->size();
+      return entry;
+    }
+
+    CompactUnwindEntry entry = unwindLoc->second;
+    auto personality = std::find(personalities.begin(), personalities.end(),
+                                 entry.personalityFunction);
+    uint32_t personalityIdx = personality == personalities.end()
+                                  ? 0
+                                  : personality - personalities.begin() + 1;
+
+    // FIXME: We should also use DWARF when there isn't enough room for the
+    // personality function in the compact encoding.
+    assert(personalityIdx < 4 && "too many personality functions");
+
+    entry.encoding |= personalityIdx << 28;
+
+    if (entry.lsdaLocation)
+      entry.encoding |= 1U << 30;
+
+    return entry;
+  }
+
+  const MachOLinkingContext &_context;
+  mach_o::ArchHandler &_archHandler;
+  MachOFile _file;
+  bool _swap;
+};
+
+void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx) {
+  assert(ctx.needsCompactUnwindPass());
+  pm.add(std::unique_ptr<Pass>(new CompactUnwindPass(ctx)));
+}
+
+} // end namesapce mach_o
+} // end namesapce lld

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Sep 30 16:29:54 2014
@@ -281,6 +281,16 @@ bool MachOLinkingContext::needsGOTPass()
   }
 }
 
+bool MachOLinkingContext::needsCompactUnwindPass() const {
+  switch (_outputMachOType) {
+  case MH_EXECUTE:
+  case MH_DYLIB:
+  case MH_BUNDLE:
+    return archHandler().needsCompactUnwind();
+  default:
+    return false;
+  }
+}
 
 StringRef MachOLinkingContext::binderSymbolName() const {
   return archHandler().stubInfo().binderSymbolName;
@@ -511,6 +521,8 @@ void MachOLinkingContext::addPasses(Pass
   pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));
   if (needsStubsPass())
     mach_o::addStubsPass(pm, *this);
+  if (needsCompactUnwindPass())
+    mach_o::addCompactUnwindPass(pm, *this);
   if (needsGOTPass())
     mach_o::addGOTPass(pm, *this);
 }

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue Sep 30 16:29:54 2014
@@ -220,6 +220,7 @@ const MachOFinalSectionFromAtomType sect
   ENTRY("__TEXT", "__stub_helper",    S_REGULAR,          typeStubHelper),
   ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR,          typeLSDA),
   ENTRY("__TEXT", "__eh_frame",       S_COALESCED,        typeCFI),
+  ENTRY("__TEXT", "__unwind_info",    S_REGULAR,          typeProcessedUnwindInfo),
   ENTRY("__DATA", "__data",           S_REGULAR,          typeData),
   ENTRY("__DATA", "__const",          S_REGULAR,          typeConstData),
   ENTRY("__DATA", "__cfstring",       S_REGULAR,          typeCFString),
@@ -565,7 +566,8 @@ void Util::copySectionContent(Normalized
     for (AtomInfo &ai : si->atomsAndOffsets) {
       uint8_t *atomContent = reinterpret_cast<uint8_t*>
                                           (&sectionContent[ai.offsetInSection]);
-      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom, atomContent);
+      _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
+                                       _context.baseAddress(), atomContent);
     }
   }
 }

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h Tue Sep 30 16:29:54 2014
@@ -18,6 +18,7 @@ namespace mach_o {
 
 void addStubsPass(PassManager &pm, const MachOLinkingContext &ctx);
 void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx);
+void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx);
 
 } // namespace mach_o
 } // namespace lld

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Tue Sep 30 16:29:54 2014
@@ -439,6 +439,7 @@ template <> struct ScalarEnumerationTrai
     io.enumCase(value, "dtraceDOF",       DefinedAtom::typeDTraceDOF);
     io.enumCase(value, "lto-temp",        DefinedAtom::typeTempLTO);
     io.enumCase(value, "compact-unwind",  DefinedAtom::typeCompactUnwindInfo);
+    io.enumCase(value, "unwind-info",     DefinedAtom::typeProcessedUnwindInfo);
     io.enumCase(value, "tlv-thunk",       DefinedAtom::typeThunkTLV);
     io.enumCase(value, "tlv-data",        DefinedAtom::typeTLVInitialData);
     io.enumCase(value, "tlv-zero-fill",   DefinedAtom::typeTLVInitialZeroFill);

Modified: lld/trunk/test/mach-o/exe-offsets.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-offsets.yaml?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/test/mach-o/exe-offsets.yaml (original)
+++ lld/trunk/test/mach-o/exe-offsets.yaml Tue Sep 30 16:29:54 2014
@@ -54,6 +54,9 @@ global-symbols:
 # CHECK:     Offset: 0
 
 # CHECK-LABEL: Section {
+# CHECK:     Name: __unwind_info
+
+# CHECK-LABEL: Section {
 # CHECK:     Name: __data
 # CHECK:     Segment: __DATA
 # CHECK:     Size: 0x5

Modified: lld/trunk/test/mach-o/exe-segment-overlap.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-segment-overlap.yaml?rev=218703&r1=218702&r2=218703&view=diff
==============================================================================
--- lld/trunk/test/mach-o/exe-segment-overlap.yaml (original)
+++ lld/trunk/test/mach-o/exe-segment-overlap.yaml Tue Sep 30 16:29:54 2014
@@ -43,7 +43,10 @@ global-symbols:
 # CHECK:     Name: __text
 # CHECK:     Segment: __TEXT
 # CHECK:     Size: 0x1
-# CHECK:     Offset: 4095
+# CHECK:     Offset: 4027
+
+# CHECK-LABEL: Section {
+# CHECK:     Name: __unwind_info
 
 # CHECK-LABEL: Section {
 # CHECK:     Name: __data

Added: lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml?rev=218703&view=auto
==============================================================================
--- lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml (added)
+++ lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml Tue Sep 30 16:29:54 2014
@@ -0,0 +1,71 @@
+# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e _main %p/Inputs/libSystem.yaml
+# RUN: llvm-objdump -unwind-info %t | FileCheck %s
+
+# CHECK: Contents of __unwind_info section:
+# CHECK:   Version:                                   0x1
+# CHECK:   Common encodings array section offset:     0x1c
+# CHECK:   Number of common encodings in array:       0x0
+# CHECK:   Personality function array section offset: 0x1c
+# CHECK:   Number of personality functions in array:  0x1
+# CHECK:   Index array section offset:                0x20
+# CHECK:   Number of indices in array:                0x2
+# CHECK:   Common encodings: (count = 0)
+# CHECK:   Personality functions: (count = 1)
+# CHECK:     personality[1]: 0x00001000
+# CHECK:   Top level indices: (count = 2)
+# CHECK:     [0]: function offset=0x00000f7e, 2nd level page offset=0x00000040, LSDA offset=0x00000038
+# CHECK:     [1]: function offset=0x00000f80, 2nd level page offset=0x00000000, LSDA offset=0x00000040
+# CHECK:   LSDA descriptors:
+# CHECK:     [0]: function offset=0x00000f7e, LSDA offset=0x00000f80
+# CHECK:   Second level indices:
+# CHECK:     Second level index[0]: offset in section=0x00000040, base function offset=0x00000f7e
+# CHECK:       [0]: function offset=0x00000f7e, encoding=0x51000000
+# CHECK:       [1]: function offset=0x00000f7f, encoding=0x01000000
+
+--- !native
+path:            '<linker-internal>'
+defined-atoms:
+  - name:            GCC_except_table1
+    type:            unwind-lsda
+    content:         [ FF, 9B, A2, 80, 80, 00, 03, 1A, 08, 00, 00, 00,
+                       05, 00, 00, 00, 1A, 00, 00, 00, 01, 0D, 00, 00,
+                       00, 64, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00,
+                       04, 00, 00, 00 ]
+  - type:            compact-unwind
+    content:         [ 40, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,
+                       00, 00, 00, 41, 00, 00, 00, 00, 00, 00, 00, 00,
+                       E0, 00, 00, 00, 00, 00, 00, 00 ]
+    references:
+      - kind:            pointer64Anon
+        offset:          0
+        target:          __Z3barv
+      - kind:            pointer64
+        offset:          16
+        target:          ___gxx_personality_v0
+      - kind:            pointer64Anon
+        offset:          24
+        target:          GCC_except_table1
+  - type:            compact-unwind
+    content:         [ C0, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,
+                       00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00,
+                       00, 00, 00, 00, 00, 00, 00, 00 ]
+    references:
+      - kind:            pointer64Anon
+        offset:          0
+        target:          _main
+
+  - name:            __Z3barv
+    scope:           global
+    content:         [ C3 ]
+  - name:            _main
+    scope:           global
+    content:         [ C3 ]
+    references:
+      - kind:            branch32
+        offset:          9
+        target:          __Z3barv
+
+shared-library-atoms:
+  - name:            ___gxx_personality_v0
+    load-name:       '/usr/lib/libc++abi.dylib'
+    type:            unknown





More information about the llvm-commits mailing list