Update LLVM for 3.5 rebase (r209712).

Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
index 1d0e9b3..8546571 100644
--- a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
@@ -45,7 +45,7 @@
   // We put information about the JITed function in this global, which the
   // debugger reads.  Make sure to specify the version statically, because the
   // debugger checks the version before we can set it during runtime.
-  struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
+  struct jit_descriptor __jit_debug_descriptor = { 1, 0, nullptr, nullptr };
 
   // Debuggers puts a breakpoint in this function.
   LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
@@ -108,10 +108,10 @@
   __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
 
   // Insert this entry at the head of the list.
-  JITCodeEntry->prev_entry = NULL;
+  JITCodeEntry->prev_entry = nullptr;
   jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
   JITCodeEntry->next_entry = NextEntry;
-  if (NextEntry != NULL) {
+  if (NextEntry) {
     NextEntry->prev_entry = JITCodeEntry;
   }
   __jit_debug_descriptor.first_entry = JITCodeEntry;
@@ -142,11 +142,10 @@
          "Second attempt to perform debug registration.");
   jit_code_entry* JITCodeEntry = new jit_code_entry();
 
-  if (JITCodeEntry == 0) {
+  if (!JITCodeEntry) {
     llvm::report_fatal_error(
       "Allocation failed when registering a JIT entry!\n");
-  }
-  else {
+  } else {
     JITCodeEntry->symfile_addr = Buffer;
     JITCodeEntry->symfile_size = Size;
 
@@ -198,7 +197,7 @@
   }
 
   delete JITCodeEntry;
-  JITCodeEntry = NULL;
+  JITCodeEntry = nullptr;
 }
 
 llvm::ManagedStatic<GDBJITRegistrar> TheRegistrar;
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
index 3693c69..4917b93 100644
--- a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
+++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
@@ -18,6 +18,8 @@
 #include "llvm/ExecutionEngine/ObjectImage.h"
 #include "llvm/Object/ObjectFile.h"
 
+#include <memory>
+
 namespace llvm {
 
 namespace object {
@@ -30,13 +32,13 @@
   void anchor() override;
 
 protected:
-  object::ObjectFile *ObjFile;
+  std::unique_ptr<object::ObjectFile> ObjFile;
 
   // This form of the constructor allows subclasses to use
   // format-specific subclasses of ObjectFile directly
-  ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj)
+  ObjectImageCommon(ObjectBuffer *Input, std::unique_ptr<object::ObjectFile> Obj)
   : ObjectImage(Input), // saves Input as Buffer and takes ownership
-    ObjFile(Obj)
+    ObjFile(std::move(Obj))
   {
   }
 
@@ -44,12 +46,13 @@
   ObjectImageCommon(ObjectBuffer* Input)
   : ObjectImage(Input) // saves Input as Buffer and takes ownership
   {
-    ObjFile =
-        object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get();
+    // FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
+    // and should probably be checked for failure.
+    ObjFile.reset(object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get());
   }
-  ObjectImageCommon(object::ObjectFile* Input)
-  : ObjectImage(NULL), ObjFile(Input)  {}
-  virtual ~ObjectImageCommon() { delete ObjFile; }
+  ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)
+  : ObjectImage(nullptr), ObjFile(std::move(Input))  {}
+  virtual ~ObjectImageCommon() { }
 
   object::symbol_iterator begin_symbols() const override
       { return ObjFile->symbol_begin(); }
@@ -66,7 +69,7 @@
 
   StringRef getData() const override { return ObjFile->getData(); }
 
-  object::ObjectFile* getObjectFile() const override { return ObjFile; }
+  object::ObjectFile* getObjectFile() const override { return ObjFile.get(); }
 
   // Subclasses can override these methods to update the image with loaded
   // addresses for sections and common symbols
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 986d3a0..c1eb0fd 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -11,7 +11,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "dyld"
 #include "llvm/ExecutionEngine/RuntimeDyld.h"
 #include "JITRegistrar.h"
 #include "ObjectImageCommon.h"
@@ -25,6 +24,8 @@
 using namespace llvm;
 using namespace llvm::object;
 
+#define DEBUG_TYPE "dyld"
+
 // Empty out-of-line virtual destructor as the key function.
 RuntimeDyldImpl::~RuntimeDyldImpl() {}
 
@@ -72,12 +73,40 @@
   llvm_unreachable("Attempting to remap address of unknown section!");
 }
 
+static error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
+  uint64_t Address;
+  if (error_code EC = Sym.getAddress(Address))
+    return EC;
+
+  if (Address == UnknownAddressOrSize) {
+    Result = UnknownAddressOrSize;
+    return object_error::success;
+  }
+
+  const ObjectFile *Obj = Sym.getObject();
+  section_iterator SecI(Obj->section_begin());
+  if (error_code EC = Sym.getSection(SecI))
+    return EC;
+
+ if (SecI == Obj->section_end()) {
+   Result = UnknownAddressOrSize;
+   return object_error::success;
+ }
+
+  uint64_t SectionAddress;
+  if (error_code EC = SecI->getAddress(SectionAddress))
+    return EC;
+
+  Result = Address - SectionAddress;
+  return object_error::success;
+}
+
 ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
   MutexGuard locked(lock);
 
   std::unique_ptr<ObjectImage> Obj(InputObject);
   if (!Obj)
-    return NULL;
+    return nullptr;
 
   // Save information about our target
   Arch = (Triple::ArchType)Obj->getArch();
@@ -115,36 +144,33 @@
     bool IsCommon = Flags & SymbolRef::SF_Common;
     if (IsCommon) {
       // Add the common symbols to a list.  We'll allocate them all below.
-      uint32_t Align;
-      Check(I->getAlignment(Align));
-      uint64_t Size = 0;
-      Check(I->getSize(Size));
-      CommonSize += Size + Align;
-      CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
+      if (!GlobalSymbolTable.count(Name)) {
+        uint32_t Align;
+        Check(I->getAlignment(Align));
+        uint64_t Size = 0;
+        Check(I->getSize(Size));
+        CommonSize += Size + Align;
+        CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
+      }
     } else {
       if (SymType == object::SymbolRef::ST_Function ||
           SymType == object::SymbolRef::ST_Data ||
           SymType == object::SymbolRef::ST_Unknown) {
-        uint64_t FileOffset;
+        uint64_t SectOffset;
         StringRef SectionData;
         bool IsCode;
         section_iterator SI = Obj->end_sections();
-        Check(I->getFileOffset(FileOffset));
+        Check(getOffset(*I, SectOffset));
         Check(I->getSection(SI));
         if (SI == Obj->end_sections())
           continue;
         Check(SI->getContents(SectionData));
         Check(SI->isText(IsCode));
-        const uint8_t *SymPtr =
-            (const uint8_t *)Obj->getData().data() + (uintptr_t)FileOffset;
-        uintptr_t SectOffset =
-            (uintptr_t)(SymPtr - (const uint8_t *)SectionData.begin());
         unsigned SectionID =
             findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
         LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
-        DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
-                     << " flags: " << Flags << " SID: " << SectionID
-                     << " Offset: " << format("%p", SectOffset));
+        DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
+                     << " flags: " << Flags << " SID: " << SectionID);
         GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
       }
     }
@@ -153,7 +179,7 @@
 
   // Allocate common symbols
   if (CommonSize != 0)
-    emitCommonSymbols(*Obj, CommonSymbols, CommonSize, LocalSymbols);
+    emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
 
   // Parse and process relocations
   DEBUG(dbgs() << "Parse relocations:\n");
@@ -163,7 +189,10 @@
     StubMap Stubs;
     section_iterator RelocatedSection = SI->getRelocatedSection();
 
-    if (SI->relocation_empty() && !ProcessAllSections)
+    relocation_iterator I = SI->relocation_begin();
+    relocation_iterator E = SI->relocation_end();
+
+    if (I == E && !ProcessAllSections)
       continue;
 
     bool IsCode = false;
@@ -172,14 +201,13 @@
         findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
     DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
 
-    for (relocation_iterator I = SI->relocation_begin(),
-         E = SI->relocation_end(); I != E;)
+    for (; I != E;)
       I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols,
                                Stubs);
   }
 
   // Give the subclasses a chance to tie-up any loose ends.
-  finalizeLoad(LocalSections);
+  finalizeLoad(*Obj, LocalSections);
 
   return Obj.release();
 }
@@ -400,7 +428,7 @@
   uintptr_t Allocate;
   unsigned SectionID = Sections.size();
   uint8_t *Addr;
-  const char *pData = 0;
+  const char *pData = nullptr;
 
   // Some sections, such as debug info, don't need to be loaded for execution.
   // Leave those where they are.
@@ -441,7 +469,7 @@
     // to handle later processing (and by 'handle' I mean don't do anything
     // with these sections).
     Allocate = 0;
-    Addr = 0;
+    Addr = nullptr;
     DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
                  << " obj addr: " << format("%p", data.data()) << " new addr: 0"
                  << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
@@ -490,7 +518,8 @@
 }
 
 uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
-  if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) {
+  if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be ||
+      Arch == Triple::arm64 || Arch == Triple::arm64_be) {
     // This stub has to be able to access the full address space,
     // since symbol lookup won't necessarily find a handy, in-range,
     // PLT stub for functions which could be anywhere.
@@ -560,6 +589,8 @@
     *Addr      = 0xFF; // jmp
     *(Addr+1)  = 0x25; // rip
     // 32-bit PC-relative address of the GOT entry will be stored at Addr+2
+  } else if (Arch == Triple::x86) {
+    *Addr      = 0xE9; // 32-bit pc-relative jump.
   }
   return Addr;
 }
@@ -586,7 +617,7 @@
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
     const RelocationEntry &RE = Relocs[i];
     // Ignore relocations for sections that were not loaded
-    if (Sections[RE.SectionID].Address == 0)
+    if (Sections[RE.SectionID].Address == nullptr)
       continue;
     resolveRelocation(RE, Value);
   }
@@ -651,7 +682,7 @@
   // though the public class spawns a new 'impl' instance for each load,
   // they share a single memory manager.  This can become a problem when page
   // permissions are applied.
-  Dyld = 0;
+  Dyld = nullptr;
   MM = mm;
   ProcessAllSections = false;
 }
@@ -672,21 +703,23 @@
   return Dyld;
 }
 
-ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) {
+ObjectImage *RuntimeDyld::loadObject(std::unique_ptr<ObjectFile> InputObject) {
   std::unique_ptr<ObjectImage> InputImage;
 
+  ObjectFile &Obj = *InputObject;
+
   if (InputObject->isELF()) {
-    InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(InputObject));
+    InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject)));
     if (!Dyld)
       Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release();
   } else if (InputObject->isMachO()) {
-    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(InputObject));
+    InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject)));
     if (!Dyld)
       Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release();
   } else
     report_fatal_error("Incompatible object format!");
 
-  if (!Dyld->isCompatibleFile(InputObject))
+  if (!Dyld->isCompatibleFile(&Obj))
     report_fatal_error("Incompatible object format!");
 
   Dyld->loadObject(InputImage.get());
@@ -740,7 +773,7 @@
 
 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
   if (!Dyld)
-    return NULL;
+    return nullptr;
   return Dyld->getSymbolAddress(Name);
 }
 
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 3204b81..6ba24b9 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -11,7 +11,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "dyld"
 #include "RuntimeDyldELF.h"
 #include "JITRegistrar.h"
 #include "ObjectImageCommon.h"
@@ -29,6 +28,8 @@
 using namespace llvm;
 using namespace llvm::object;
 
+#define DEBUG_TYPE "dyld"
+
 namespace {
 
 static inline error_code check(error_code Err) {
@@ -50,7 +51,12 @@
 
   typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
 
+  std::unique_ptr<ObjectFile> UnderlyingFile;
+
 public:
+  DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+                MemoryBuffer *Wrapper, error_code &ec);
+
   DyldELFObject(MemoryBuffer *Wrapper, error_code &ec);
 
   void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
@@ -67,13 +73,11 @@
 };
 
 template <class ELFT> class ELFObjectImage : public ObjectImageCommon {
-protected:
-  DyldELFObject<ELFT> *DyldObj;
   bool Registered;
 
 public:
-  ELFObjectImage(ObjectBuffer *Input, DyldELFObject<ELFT> *Obj)
-      : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {}
+  ELFObjectImage(ObjectBuffer *Input, std::unique_ptr<DyldELFObject<ELFT>> Obj)
+      : ObjectImageCommon(Input, std::move(Obj)), Registered(false) {}
 
   virtual ~ELFObjectImage() {
     if (Registered)
@@ -83,11 +87,13 @@
   // Subclasses can override these methods to update the image with loaded
   // addresses for sections and common symbols
   void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) override {
-    DyldObj->updateSectionAddress(Sec, Addr);
+    static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+        ->updateSectionAddress(Sec, Addr);
   }
 
   void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) override {
-    DyldObj->updateSymbolAddress(Sym, Addr);
+    static_cast<DyldELFObject<ELFT>*>(getObjectFile())
+        ->updateSymbolAddress(Sym, Addr);
   }
 
   void registerWithDebugger() override {
@@ -109,6 +115,14 @@
 }
 
 template <class ELFT>
+DyldELFObject<ELFT>::DyldELFObject(std::unique_ptr<ObjectFile> UnderlyingFile,
+                                   MemoryBuffer *Wrapper, error_code &ec)
+    : ELFObjectFile<ELFT>(Wrapper, ec),
+      UnderlyingFile(std::move(UnderlyingFile)) {
+  this->isDyldELFObject = true;
+}
+
+template <class ELFT>
 void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec,
                                                uint64_t Addr) {
   DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
@@ -164,30 +178,36 @@
 }
 
 ObjectImage *
-RuntimeDyldELF::createObjectImageFromFile(object::ObjectFile *ObjFile) {
+RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr<object::ObjectFile> ObjFile) {
   if (!ObjFile)
-    return NULL;
+    return nullptr;
 
   error_code ec;
   MemoryBuffer *Buffer =
       MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false);
 
   if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) {
-    DyldELFObject<ELFType<support::little, 2, false>> *Obj =
-        new DyldELFObject<ELFType<support::little, 2, false>>(Buffer, ec);
-    return new ELFObjectImage<ELFType<support::little, 2, false>>(NULL, Obj);
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 2, false>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::little, 2, false>>(
+        nullptr, std::move(Obj));
   } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) {
-    DyldELFObject<ELFType<support::big, 2, false>> *Obj =
-        new DyldELFObject<ELFType<support::big, 2, false>>(Buffer, ec);
-    return new ELFObjectImage<ELFType<support::big, 2, false>>(NULL, Obj);
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::big, 2, false>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::big, 2, false>>(nullptr, std::move(Obj));
   } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) {
-    DyldELFObject<ELFType<support::big, 2, true>> *Obj =
-        new DyldELFObject<ELFType<support::big, 2, true>>(Buffer, ec);
-    return new ELFObjectImage<ELFType<support::big, 2, true>>(NULL, Obj);
+    auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 2, true>>>(
+        std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::big, 2, true>>(nullptr,
+                                                              std::move(Obj));
   } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) {
-    DyldELFObject<ELFType<support::little, 2, true>> *Obj =
-        new DyldELFObject<ELFType<support::little, 2, true>>(Buffer, ec);
-    return new ELFObjectImage<ELFType<support::little, 2, true>>(NULL, Obj);
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 2, true>>>(
+            std::move(ObjFile), Buffer, ec);
+    return new ELFObjectImage<ELFType<support::little, 2, true>>(
+        nullptr, std::move(Obj));
   } else
     llvm_unreachable("Unexpected ELF format");
 }
@@ -201,28 +221,29 @@
   error_code ec;
 
   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
-    DyldELFObject<ELFType<support::little, 4, false>> *Obj =
-        new DyldELFObject<ELFType<support::little, 4, false>>(
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 4, false>>>(
             Buffer->getMemBuffer(), ec);
-    return new ELFObjectImage<ELFType<support::little, 4, false>>(Buffer, Obj);
+    return new ELFObjectImage<ELFType<support::little, 4, false>>(
+        Buffer, std::move(Obj));
   } else if (Ident.first == ELF::ELFCLASS32 &&
              Ident.second == ELF::ELFDATA2MSB) {
-    DyldELFObject<ELFType<support::big, 4, false>> *Obj =
-        new DyldELFObject<ELFType<support::big, 4, false>>(
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::big, 4, false>>>(
             Buffer->getMemBuffer(), ec);
-    return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer, Obj);
+    return new ELFObjectImage<ELFType<support::big, 4, false>>(Buffer,
+                                                               std::move(Obj));
   } else if (Ident.first == ELF::ELFCLASS64 &&
              Ident.second == ELF::ELFDATA2MSB) {
-    DyldELFObject<ELFType<support::big, 8, true>> *Obj =
-        new DyldELFObject<ELFType<support::big, 8, true>>(
-            Buffer->getMemBuffer(), ec);
-    return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, Obj);
+    auto Obj = llvm::make_unique<DyldELFObject<ELFType<support::big, 8, true>>>(
+        Buffer->getMemBuffer(), ec);
+    return new ELFObjectImage<ELFType<support::big, 8, true>>(Buffer, std::move(Obj));
   } else if (Ident.first == ELF::ELFCLASS64 &&
              Ident.second == ELF::ELFDATA2LSB) {
-    DyldELFObject<ELFType<support::little, 8, true>> *Obj =
-        new DyldELFObject<ELFType<support::little, 8, true>>(
+    auto Obj =
+        llvm::make_unique<DyldELFObject<ELFType<support::little, 8, true>>>(
             Buffer->getMemBuffer(), ec);
-    return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, Obj);
+    return new ELFObjectImage<ELFType<support::little, 8, true>>(Buffer, std::move(Obj));
   } else
     llvm_unreachable("Unexpected ELF format");
 }
@@ -845,6 +866,8 @@
     break;
   case Triple::aarch64:
   case Triple::aarch64_be:
+  case Triple::arm64:
+  case Triple::arm64_be:
     resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
     break;
   case Triple::arm: // Fall through.
@@ -950,7 +973,8 @@
 
   DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
                << "\n");
-  if (Arch == Triple::aarch64 &&
+  if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be ||
+       Arch == Triple::arm64 || Arch == Triple::arm64_be) &&
       (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26)) {
     // This is an AArch64 branch relocation, need to use a stub function.
     DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
@@ -1151,7 +1175,7 @@
       // Extra check to avoid relocation againt empty symbols (usually
       // the R_PPC64_TOC).
       if (SymType != SymbolRef::ST_Unknown && TargetName.empty())
-        Value.SymbolName = NULL;
+        Value.SymbolName = nullptr;
 
       if (Value.SymbolName)
         addRelocationForSymbol(RE, Value.SymbolName);
@@ -1283,7 +1307,8 @@
   for (it = GOTs.begin(); it != end; ++it) {
     GOTRelocations &GOTEntries = it->second;
     for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
-      if (GOTEntries[i].SymbolName != 0 && GOTEntries[i].SymbolName == Name) {
+      if (GOTEntries[i].SymbolName != nullptr &&
+          GOTEntries[i].SymbolName == Name) {
         GOTEntries[i].Offset = Addr;
       }
     }
@@ -1297,6 +1322,9 @@
   switch (Arch) {
   case Triple::x86_64:
   case Triple::aarch64:
+  case Triple::aarch64_be:
+  case Triple::arm64:
+  case Triple::arm64_be:
   case Triple::ppc64:
   case Triple::ppc64le:
   case Triple::systemz:
@@ -1331,7 +1359,7 @@
     // Find the matching entry in our vector.
     uint64_t SymbolOffset = 0;
     for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
-      if (GOTEntries[i].SymbolName == 0) {
+      if (!GOTEntries[i].SymbolName) {
         if (getSectionLoadAddress(GOTEntries[i].SectionID) == LoadAddress &&
             GOTEntries[i].Offset == Offset) {
           GOTIndex = i;
@@ -1369,7 +1397,8 @@
   return 0;
 }
 
-void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
+                                  ObjSectionToIDMap &SectionMap) {
   // If necessary, allocate the global offset table
   if (MemMgr) {
     // Allocate the GOT if necessary
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index 27db5cd..a526073 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -59,7 +59,8 @@
                                 uint64_t Value, uint32_t Type, int64_t Addend);
 
   unsigned getMaxStubSize() override {
-    if (Arch == Triple::aarch64)
+    if (Arch == Triple::aarch64 || Arch == Triple::arm64 ||
+        Arch == Triple::aarch64_be || Arch == Triple::arm64_be)
       return 20; // movz; movk; movk; movk; br
     if (Arch == Triple::arm || Arch == Triple::thumb)
       return 8; // 32-bit instruction and 32-bit address
@@ -115,11 +116,12 @@
   bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
   void registerEHFrames() override;
   void deregisterEHFrames() override;
-  void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
+  void finalizeLoad(ObjectImage &ObjImg,
+                    ObjSectionToIDMap &SectionMap) override;
   virtual ~RuntimeDyldELF();
 
   static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
-  static ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj);
+  static ObjectImage *createObjectImageFromFile(std::unique_ptr<object::ObjectFile> Obj);
 };
 
 } // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index c153ee1..412cf20 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -90,9 +90,17 @@
   /// used to make a relocation section relative instead of symbol relative.
   int64_t Addend;
 
+  struct SectionPair {
+      uint32_t SectionA;
+      uint32_t SectionB;
+  };
+
   /// SymOffset - Section offset of the relocation entry's symbol (used for GOT
   /// lookup).
-  uint64_t SymOffset;
+  union {
+    uint64_t SymOffset;
+    SectionPair Sections;
+  };
 
   /// True if this is a PCRel relocation (MachO specific).
   bool IsPCRel;
@@ -113,6 +121,16 @@
                   bool IsPCRel, unsigned Size)
       : SectionID(id), Offset(offset), RelType(type), Addend(addend),
         SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
+
+  RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
+                  unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB,
+                  uint64_t SectionBOffset, bool IsPCRel, unsigned Size)
+      : SectionID(id), Offset(offset), RelType(type),
+        Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel),
+        Size(Size) {
+    Sections.SectionA = SectionA;
+    Sections.SectionB = SectionB;
+  }
 };
 
 class RelocationValueRef {
@@ -121,7 +139,8 @@
   uint64_t Offset;
   int64_t Addend;
   const char *SymbolName;
-  RelocationValueRef() : SectionID(0), Offset(0), Addend(0), SymbolName(0) {}
+  RelocationValueRef() : SectionID(0), Offset(0), Addend(0),
+                         SymbolName(nullptr) {}
 
   inline bool operator==(const RelocationValueRef &Other) const {
     return SectionID == Other.SectionID && Offset == Other.Offset &&
@@ -335,7 +354,7 @@
     // Work in progress.
     SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
     if (pos == GlobalSymbolTable.end())
-      return 0;
+      return nullptr;
     SymbolLoc Loc = pos->second;
     return getSectionAddress(Loc.first) + Loc.second;
   }
@@ -372,7 +391,7 @@
 
   virtual void deregisterEHFrames();
 
-  virtual void finalizeLoad(ObjSectionToIDMap &SectionMap) {}
+  virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {}
 };
 
 } // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 7eae9c2..2b425fb 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -11,17 +11,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "dyld"
 #include "RuntimeDyldMachO.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 using namespace llvm;
 using namespace llvm::object;
 
+#define DEBUG_TYPE "dyld"
+
 namespace llvm {
 
 static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
                                  intptr_t DeltaForEH) {
+  DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
+               << ", Delta for EH: " << DeltaForEH << "\n");
   uint32_t Length = *((uint32_t *)P);
   P += 4;
   unsigned char *Ret = P + Length;
@@ -66,7 +69,7 @@
       continue;
     SectionEntry *Text = &Sections[SectionInfo.TextSID];
     SectionEntry *EHFrame = &Sections[SectionInfo.EHFrameSID];
-    SectionEntry *ExceptTab = NULL;
+    SectionEntry *ExceptTab = nullptr;
     if (SectionInfo.ExceptTabSID != RTDYLD_INVALID_SECTION_ID)
       ExceptTab = &Sections[SectionInfo.ExceptTabSID];
 
@@ -87,7 +90,8 @@
   UnregisteredEHFrameSections.clear();
 }
 
-void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
+void RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg,
+                                    ObjSectionToIDMap &SectionMap) {
   unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
   unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
   unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
@@ -102,6 +106,12 @@
       TextSID = i->second;
     else if (Name == "__gcc_except_tab")
       ExceptTabSID = i->second;
+    else if (Name == "__jump_table")
+      populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+                        Section, i->second);
+    else if (Name == "__pointers")
+      populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
+                              Section, i->second);
   }
   UnregisteredEHFrameSections.push_back(
       EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
@@ -129,91 +139,87 @@
 // symbol in the target address space.
 void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
                                          uint64_t Value) {
-  const SectionEntry &Section = Sections[RE.SectionID];
-  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
-                           RE.IsPCRel, RE.Size);
-}
+  DEBUG (
+    const SectionEntry &Section = Sections[RE.SectionID];
+    uint8_t* LocalAddress = Section.Address + RE.Offset;
+    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
 
-void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
-                                         uint64_t Offset, uint64_t Value,
-                                         uint32_t Type, int64_t Addend,
-                                         bool isPCRel, unsigned LogSize) {
-  uint8_t *LocalAddress = Section.Address + Offset;
-  uint64_t FinalAddress = Section.LoadAddress + Offset;
-  unsigned MachoType = Type;
-  unsigned Size = 1 << LogSize;
-
-  DEBUG(dbgs() << "resolveRelocation LocalAddress: "
-               << format("%p", LocalAddress)
-               << " FinalAddress: " << format("%p", FinalAddress)
-               << " Value: " << format("%p", Value) << " Addend: " << Addend
-               << " isPCRel: " << isPCRel << " MachoType: " << MachoType
-               << " Size: " << Size << "\n");
+    dbgs() << "resolveRelocation Section: " << RE.SectionID
+           << " LocalAddress: " << format("%p", LocalAddress)
+           << " FinalAddress: " << format("%p", FinalAddress)
+           << " Value: " << format("%p", Value)
+           << " Addend: " << RE.Addend
+           << " isPCRel: " << RE.IsPCRel
+           << " MachoType: " << RE.RelType
+           << " Size: " << (1 << RE.Size) << "\n";
+  );
 
   // This just dispatches to the proper target specific routine.
   switch (Arch) {
   default:
     llvm_unreachable("Unsupported CPU type!");
   case Triple::x86_64:
-    resolveX86_64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
-                            isPCRel, MachoType, Size, Addend);
+    resolveX86_64Relocation(RE, Value);
     break;
   case Triple::x86:
-    resolveI386Relocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
-                          MachoType, Size, Addend);
+    resolveI386Relocation(RE, Value);
     break;
   case Triple::arm: // Fall through.
   case Triple::thumb:
-    resolveARMRelocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
-                         MachoType, Size, Addend);
+    resolveARMRelocation(RE, Value);
     break;
+  case Triple::aarch64:
   case Triple::arm64:
-    resolveARM64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
-                           isPCRel, MachoType, Size, Addend);
+    resolveAArch64Relocation(RE, Value);
     break;
   }
 }
 
-bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
-                                             uint64_t FinalAddress,
-                                             uint64_t Value, bool isPCRel,
-                                             unsigned Type, unsigned Size,
-                                             int64_t Addend) {
-  if (isPCRel)
-    Value -= FinalAddress + 4; // see resolveX86_64Relocation
+bool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE,
+                                             uint64_t Value) {
+  const SectionEntry &Section = Sections[RE.SectionID];
+  uint8_t* LocalAddress = Section.Address + RE.Offset;
 
-  switch (Type) {
-  default:
-    llvm_unreachable("Invalid relocation type!");
-  case MachO::GENERIC_RELOC_VANILLA: {
-    uint8_t *p = LocalAddress;
-    uint64_t ValueToWrite = Value + Addend;
-    for (unsigned i = 0; i < Size; ++i) {
-      *p++ = (uint8_t)(ValueToWrite & 0xff);
-      ValueToWrite >>= 8;
-    }
-    return false;
+  if (RE.IsPCRel) {
+    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+    Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
   }
-  case MachO::GENERIC_RELOC_SECTDIFF:
-  case MachO::GENERIC_RELOC_LOCAL_SECTDIFF:
-  case MachO::GENERIC_RELOC_PB_LA_PTR:
-    return Error("Relocation type not implemented yet!");
+
+  switch (RE.RelType) {
+    default:
+      llvm_unreachable("Invalid relocation type!");
+    case MachO::GENERIC_RELOC_VANILLA:
+      return applyRelocationValue(LocalAddress, Value + RE.Addend,
+                                  1 << RE.Size);
+    case MachO::GENERIC_RELOC_SECTDIFF:
+    case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
+      uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress;
+      uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress;
+      assert((Value == SectionABase || Value == SectionBBase) &&
+             "Unexpected SECTDIFF relocation value.");
+      Value = SectionABase - SectionBBase + RE.Addend;
+      return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
+    }
+    case MachO::GENERIC_RELOC_PB_LA_PTR:
+      return Error("Relocation type not implemented yet!");
   }
 }
 
-bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
-                                               uint64_t FinalAddress,
-                                               uint64_t Value, bool isPCRel,
-                                               unsigned Type, unsigned Size,
-                                               int64_t Addend) {
+bool RuntimeDyldMachO::resolveX86_64Relocation(const RelocationEntry &RE,
+                                               uint64_t Value) {
+  const SectionEntry &Section = Sections[RE.SectionID];
+  uint8_t* LocalAddress = Section.Address + RE.Offset;
+
   // If the relocation is PC-relative, the value to be encoded is the
   // pointer difference.
-  if (isPCRel)
+  if (RE.IsPCRel) {
     // FIXME: It seems this value needs to be adjusted by 4 for an effective PC
     // address. Is that expected? Only for branches, perhaps?
-    Value -= FinalAddress + 4;
+    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+    Value -= FinalAddress + 4; // see MachOX86_64::resolveRelocation.
+  }
 
-  switch (Type) {
+  switch (RE.RelType) {
   default:
     llvm_unreachable("Invalid relocation type!");
   case MachO::X86_64_RELOC_SIGNED_1:
@@ -221,17 +227,8 @@
   case MachO::X86_64_RELOC_SIGNED_4:
   case MachO::X86_64_RELOC_SIGNED:
   case MachO::X86_64_RELOC_UNSIGNED:
-  case MachO::X86_64_RELOC_BRANCH: {
-    Value += Addend;
-    // Mask in the target value a byte at a time (we don't have an alignment
-    // guarantee for the target address, so this is safest).
-    uint8_t *p = (uint8_t *)LocalAddress;
-    for (unsigned i = 0; i < Size; ++i) {
-      *p++ = (uint8_t)Value;
-      Value >>= 8;
-    }
-    return false;
-  }
+  case MachO::X86_64_RELOC_BRANCH:
+    return applyRelocationValue(LocalAddress, Value + RE.Addend, 1 << RE.Size);
   case MachO::X86_64_RELOC_GOT_LOAD:
   case MachO::X86_64_RELOC_GOT:
   case MachO::X86_64_RELOC_SUBTRACTOR:
@@ -240,14 +237,15 @@
   }
 }
 
-bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
-                                            uint64_t FinalAddress,
-                                            uint64_t Value, bool isPCRel,
-                                            unsigned Type, unsigned Size,
-                                            int64_t Addend) {
+bool RuntimeDyldMachO::resolveARMRelocation(const RelocationEntry &RE,
+                                            uint64_t Value) {
+  const SectionEntry &Section = Sections[RE.SectionID];
+  uint8_t* LocalAddress = Section.Address + RE.Offset;
+
   // If the relocation is PC-relative, the value to be encoded is the
   // pointer difference.
-  if (isPCRel) {
+  if (RE.IsPCRel) {
+    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
     Value -= FinalAddress;
     // ARM PCRel relocations have an effective-PC offset of two instructions
     // (four bytes in Thumb mode, 8 bytes in ARM mode).
@@ -255,19 +253,11 @@
     Value -= 8;
   }
 
-  switch (Type) {
+  switch (RE.RelType) {
   default:
     llvm_unreachable("Invalid relocation type!");
-  case MachO::ARM_RELOC_VANILLA: {
-    // Mask in the target value a byte at a time (we don't have an alignment
-    // guarantee for the target address, so this is safest).
-    uint8_t *p = (uint8_t *)LocalAddress;
-    for (unsigned i = 0; i < Size; ++i) {
-      *p++ = (uint8_t)Value;
-      Value >>= 8;
-    }
-    break;
-  }
+  case MachO::ARM_RELOC_VANILLA:
+    return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
   case MachO::ARM_RELOC_BR24: {
     // Mask the value into the target address. We know instructions are
     // 32-bit aligned, so we can do it all at once.
@@ -275,13 +265,16 @@
     // The low two bits of the value are not encoded.
     Value >>= 2;
     // Mask the value to 24 bits.
-    Value &= 0xffffff;
+    uint64_t FinalValue = Value & 0xffffff;
+    // Check for overflow.
+    if (Value != FinalValue)
+      return Error("ARM BR24 relocation out of range.");
     // FIXME: If the destination is a Thumb function (and the instruction
     // is a non-predicated BL instruction), we need to change it to a BLX
     // instruction instead.
 
     // Insert the value into the instruction.
-    *p = (*p & ~0xffffff) | Value;
+    *p = (*p & ~0xffffff) | FinalValue;
     break;
   }
   case MachO::ARM_THUMB_RELOC_BR22:
@@ -297,29 +290,23 @@
   return false;
 }
 
-bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress,
-                                              uint64_t FinalAddress,
-                                              uint64_t Value, bool isPCRel,
-                                              unsigned Type, unsigned Size,
-                                              int64_t Addend) {
+bool RuntimeDyldMachO::resolveAArch64Relocation(const RelocationEntry &RE,
+                                                uint64_t Value) {
+  const SectionEntry &Section = Sections[RE.SectionID];
+  uint8_t* LocalAddress = Section.Address + RE.Offset;
+
   // If the relocation is PC-relative, the value to be encoded is the
   // pointer difference.
-  if (isPCRel)
+  if (RE.IsPCRel) {
+    uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
     Value -= FinalAddress;
+  }
 
-  switch (Type) {
+  switch (RE.RelType) {
   default:
     llvm_unreachable("Invalid relocation type!");
-  case MachO::ARM64_RELOC_UNSIGNED: {
-    // Mask in the target value a byte at a time (we don't have an alignment
-    // guarantee for the target address, so this is safest).
-    uint8_t *p = (uint8_t *)LocalAddress;
-    for (unsigned i = 0; i < Size; ++i) {
-      *p++ = (uint8_t)Value;
-      Value >>= 8;
-    }
-    break;
-  }
+  case MachO::ARM64_RELOC_UNSIGNED:
+    return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
   case MachO::ARM64_RELOC_BRANCH26: {
     // Mask the value into the target address. We know instructions are
     // 32-bit aligned, so we can do it all at once.
@@ -327,9 +314,12 @@
     // The low two bits of the value are not encoded.
     Value >>= 2;
     // Mask the value to 26 bits.
-    Value &= 0x3ffffff;
+    uint64_t FinalValue = Value & 0x3ffffff;
+    // Check for overflow.
+    if (FinalValue != Value)
+      return Error("ARM64 BRANCH26 relocation out of range.");
     // Insert the value into the instruction.
-    *p = (*p & ~0x3ffffff) | Value;
+    *p = (*p & ~0x3ffffff) | FinalValue;
     break;
   }
   case MachO::ARM64_RELOC_SUBTRACTOR:
@@ -346,6 +336,198 @@
   return false;
 }
 
+void RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj,
+                                         const SectionRef &JTSection,
+                                         unsigned JTSectionID) {
+  assert(!Obj.is64Bit() &&
+         "__jump_table section not supported in 64-bit MachO.");
+
+  MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
+  MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());
+  uint32_t JTSectionSize = Sec32.size;
+  unsigned FirstIndirectSymbol = Sec32.reserved1;
+  unsigned JTEntrySize = Sec32.reserved2;
+  unsigned NumJTEntries = JTSectionSize / JTEntrySize;
+  uint8_t* JTSectionAddr = getSectionAddress(JTSectionID);
+  unsigned JTEntryOffset = 0;
+
+  assert((JTSectionSize % JTEntrySize) == 0 &&
+         "Jump-table section does not contain a whole number of stubs?");
+
+  for (unsigned i = 0; i < NumJTEntries; ++i) {
+    unsigned SymbolIndex =
+      Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
+    symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
+    StringRef IndirectSymbolName;
+    SI->getName(IndirectSymbolName);
+    uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset;
+    createStubFunction(JTEntryAddr);
+    RelocationEntry RE(JTSectionID, JTEntryOffset + 1,
+                       MachO::GENERIC_RELOC_VANILLA, 0, true, 2);
+    addRelocationForSymbol(RE, IndirectSymbolName);
+    JTEntryOffset += JTEntrySize;
+  }
+}
+
+void RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj,
+                                               const SectionRef &PTSection,
+                                               unsigned PTSectionID) {
+  assert(!Obj.is64Bit() &&
+         "__pointers section not supported in 64-bit MachO.");
+
+  MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
+  MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl());
+  uint32_t PTSectionSize = Sec32.size;
+  unsigned FirstIndirectSymbol = Sec32.reserved1;
+  const unsigned PTEntrySize = 4;
+  unsigned NumPTEntries = PTSectionSize / PTEntrySize;
+  unsigned PTEntryOffset = 0;
+
+  assert((PTSectionSize % PTEntrySize) == 0 &&
+         "Pointers section does not contain a whole number of stubs?");
+
+  DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID
+               << ", " << NumPTEntries << " entries, "
+               << PTEntrySize << " bytes each:\n");
+
+  for (unsigned i = 0; i < NumPTEntries; ++i) {
+    unsigned SymbolIndex =
+      Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
+    symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
+    StringRef IndirectSymbolName;
+    SI->getName(IndirectSymbolName);
+    DEBUG(dbgs() << "  " << IndirectSymbolName << ": index " << SymbolIndex
+          << ", PT offset: " << PTEntryOffset << "\n");
+    RelocationEntry RE(PTSectionID, PTEntryOffset,
+                       MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
+    addRelocationForSymbol(RE, IndirectSymbolName);
+    PTEntryOffset += PTEntrySize;
+  }
+}
+
+
+section_iterator getSectionByAddress(const MachOObjectFile &Obj,
+                                     uint64_t Addr) {
+  section_iterator SI = Obj.section_begin();
+  section_iterator SE = Obj.section_end();
+
+  for (; SI != SE; ++SI) {
+    uint64_t SAddr, SSize;
+    SI->getAddress(SAddr);
+    SI->getSize(SSize);
+    if ((Addr >= SAddr) && (Addr < SAddr + SSize))
+      return SI;
+  }
+
+  return SE;
+}
+
+relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
+                                            unsigned SectionID,
+                                            relocation_iterator RelI,
+                                            ObjectImage &Obj,
+                                            ObjSectionToIDMap &ObjSectionToID) {
+  const MachOObjectFile *MachO =
+    static_cast<const MachOObjectFile*>(Obj.getObjectFile());
+  MachO::any_relocation_info RE =
+    MachO->getRelocation(RelI->getRawDataRefImpl());
+
+  SectionEntry &Section = Sections[SectionID];
+  uint32_t RelocType = MachO->getAnyRelocationType(RE);
+  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+  unsigned Size = MachO->getAnyRelocationLength(RE);
+  uint64_t Offset;
+  RelI->getOffset(Offset);
+  uint8_t *LocalAddress = Section.Address + Offset;
+  unsigned NumBytes = 1 << Size;
+  int64_t Addend = 0;
+  memcpy(&Addend, LocalAddress, NumBytes);
+
+  ++RelI;
+  MachO::any_relocation_info RE2 =
+    MachO->getRelocation(RelI->getRawDataRefImpl());
+
+  uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
+  section_iterator SAI = getSectionByAddress(*MachO, AddrA);
+  assert(SAI != MachO->section_end() && "Can't find section for address A");
+  uint64_t SectionABase;
+  SAI->getAddress(SectionABase);
+  uint64_t SectionAOffset = AddrA - SectionABase;
+  SectionRef SectionA = *SAI;
+  bool IsCode;
+  SectionA.isText(IsCode);
+  uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode,
+                                          ObjSectionToID);
+
+  uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
+  section_iterator SBI = getSectionByAddress(*MachO, AddrB);
+  assert(SBI != MachO->section_end() && "Can't find section for address B");
+  uint64_t SectionBBase;
+  SBI->getAddress(SectionBBase);
+  uint64_t SectionBOffset = AddrB - SectionBBase;
+  SectionRef SectionB = *SBI;
+  uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode,
+                                          ObjSectionToID);
+
+  if (Addend != AddrA - AddrB)
+    Error("Unexpected SECTDIFF relocation addend.");
+
+  DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB
+               << ", Addend: " << Addend << ", SectionA ID: "
+               << SectionAID << ", SectionAOffset: " << SectionAOffset
+               << ", SectionB ID: " << SectionBID << ", SectionBOffset: "
+               << SectionBOffset << "\n");
+  RelocationEntry R(SectionID, Offset, RelocType, 0,
+                    SectionAID, SectionAOffset, SectionBID, SectionBOffset,
+                    IsPCRel, Size);
+
+  addRelocationForSection(R, SectionAID);
+  addRelocationForSection(R, SectionBID);
+
+  return ++RelI;
+}
+
+relocation_iterator RuntimeDyldMachO::processI386ScatteredVANILLA(
+                                            unsigned SectionID,
+                                            relocation_iterator RelI,
+                                            ObjectImage &Obj,
+                                            ObjSectionToIDMap &ObjSectionToID) {
+  const MachOObjectFile *MachO =
+    static_cast<const MachOObjectFile*>(Obj.getObjectFile());
+  MachO::any_relocation_info RE =
+    MachO->getRelocation(RelI->getRawDataRefImpl());
+
+  SectionEntry &Section = Sections[SectionID];
+  uint32_t RelocType = MachO->getAnyRelocationType(RE);
+  bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
+  unsigned Size = MachO->getAnyRelocationLength(RE);
+  uint64_t Offset;
+  RelI->getOffset(Offset);
+  uint8_t *LocalAddress = Section.Address + Offset;
+  unsigned NumBytes = 1 << Size;
+  int64_t Addend = 0;
+  memcpy(&Addend, LocalAddress, NumBytes);
+
+  unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE);
+  section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr);
+  assert(TargetSI != MachO->section_end() && "Can't find section for symbol");
+  uint64_t SectionBaseAddr;
+  TargetSI->getAddress(SectionBaseAddr);
+  SectionRef TargetSection = *TargetSI;
+  bool IsCode;
+  TargetSection.isText(IsCode);
+  uint32_t TargetSectionID = findOrEmitSection(Obj, TargetSection, IsCode,
+                                               ObjSectionToID);
+
+  Addend -= SectionBaseAddr;
+  RelocationEntry R(SectionID, Offset, RelocType, Addend,
+                    IsPCRel, Size);
+
+  addRelocationForSection(R, TargetSectionID);
+
+  return ++RelI;
+}
+
 relocation_iterator RuntimeDyldMachO::processRelocationRef(
     unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
     ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
@@ -358,18 +540,28 @@
   uint32_t RelType = MachO->getAnyRelocationType(RE);
 
   // FIXME: Properly handle scattered relocations.
-  //        For now, optimistically skip these: they can often be ignored, as
-  //        the static linker will already have applied the relocation, and it
-  //        only needs to be reapplied if symbols move relative to one another.
-  //        Note: This will fail horribly where the relocations *do* need to be
-  //        applied, but that was already the case.
-  if (MachO->isRelocationScattered(RE))
-    return ++RelI;
+  //        Special case the couple of scattered relocations that we know how
+  //        to handle: SECTDIFF relocations, and scattered VANILLA relocations
+  //        on I386.
+  //        For all other scattered relocations, just bail out and hope for the
+  //        best, since the offsets computed by scattered relocations have often
+  //        been optimisticaly filled in by the compiler. This will fail
+  //        horribly where the relocations *do* need to be applied, but that was
+  //        already the case.
+  if (MachO->isRelocationScattered(RE)) {
+    if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
+        RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
+      return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
+    else if (Arch == Triple::x86 && RelType == MachO::GENERIC_RELOC_VANILLA)
+      return processI386ScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID);
+    else
+      return ++RelI;
+  }
 
   RelocationValueRef Value;
   SectionEntry &Section = Sections[SectionID];
 
-  bool isExtern = MachO->getPlainRelocationExternal(RE);
+  bool IsExtern = MachO->getPlainRelocationExternal(RE);
   bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
   unsigned Size = MachO->getAnyRelocationLength(RE);
   uint64_t Offset;
@@ -379,7 +571,7 @@
   uint64_t Addend = 0;
   memcpy(&Addend, LocalAddress, NumBytes);
 
-  if (isExtern) {
+  if (IsExtern) {
     // Obtain the symbol name which is referenced in the relocation
     symbol_iterator Symbol = RelI->getSymbol();
     StringRef TargetName;
@@ -401,6 +593,17 @@
         Value.Addend = Addend;
       }
     }
+
+    // Addends for external, PC-rel relocations on i386 point back to the zero
+    // offset. Calculate the final offset from the relocation target instead.
+    // This allows us to use the same logic for both external and internal
+    // relocations in resolveI386RelocationRef.
+    if (Arch == Triple::x86 && IsPCRel) {
+      uint64_t RelocAddr = 0;
+      RelI->getAddress(RelocAddr);
+      Value.Addend += RelocAddr + 4;
+    }
+
   } else {
     SectionRef Sec = MachO->getRelocationSection(RE);
     bool IsCode = false;
@@ -417,6 +620,10 @@
                                  RelType == MachO::X86_64_RELOC_GOT_LOAD)) {
     assert(IsPCRel);
     assert(Size == 2);
+
+    // FIXME: Teach the generic code above not to prematurely conflate
+    //        relocation addends and symbol offsets.
+    Value.Addend -= Addend;
     StubMap::const_iterator i = Stubs.find(Value);
     uint8_t *Addr;
     if (i != Stubs.end()) {
@@ -424,41 +631,45 @@
     } else {
       Stubs[Value] = Section.StubOffset;
       uint8_t *GOTEntry = Section.Address + Section.StubOffset;
-      RelocationEntry RE(SectionID, Section.StubOffset,
-                         MachO::X86_64_RELOC_UNSIGNED, 0, false, 3);
+      RelocationEntry GOTRE(SectionID, Section.StubOffset,
+                            MachO::X86_64_RELOC_UNSIGNED, Value.Addend, false,
+                            3);
       if (Value.SymbolName)
-        addRelocationForSymbol(RE, Value.SymbolName);
+        addRelocationForSymbol(GOTRE, Value.SymbolName);
       else
-        addRelocationForSection(RE, Value.SectionID);
+        addRelocationForSection(GOTRE, Value.SectionID);
       Section.StubOffset += 8;
       Addr = GOTEntry;
     }
-    resolveRelocation(Section, Offset, (uint64_t)Addr,
-                      MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2);
+    RelocationEntry TargetRE(SectionID, Offset,
+                             MachO::X86_64_RELOC_UNSIGNED, Addend, true,
+                             2);
+    resolveRelocation(TargetRE, (uint64_t)Addr);
   } else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
     // This is an ARM branch relocation, need to use a stub function.
 
     //  Look up for existing stub.
     StubMap::const_iterator i = Stubs.find(Value);
-    if (i != Stubs.end())
-      resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second,
-                        RelType, 0, IsPCRel, Size);
-    else {
+    uint8_t *Addr;
+    if (i != Stubs.end()) {
+      Addr = Section.Address + i->second;
+    } else {
       // Create a new stub function.
       Stubs[Value] = Section.StubOffset;
       uint8_t *StubTargetAddr =
           createStubFunction(Section.Address + Section.StubOffset);
-      RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
-                         MachO::GENERIC_RELOC_VANILLA, Value.Addend);
+      RelocationEntry StubRE(SectionID, StubTargetAddr - Section.Address,
+                             MachO::GENERIC_RELOC_VANILLA, Value.Addend);
       if (Value.SymbolName)
-        addRelocationForSymbol(RE, Value.SymbolName);
+        addRelocationForSymbol(StubRE, Value.SymbolName);
       else
-        addRelocationForSection(RE, Value.SectionID);
-      resolveRelocation(Section, Offset,
-                        (uint64_t)Section.Address + Section.StubOffset, RelType,
-                        0, IsPCRel, Size);
+        addRelocationForSection(StubRE, Value.SectionID);
+      Addr = Section.Address + Section.StubOffset;
       Section.StubOffset += getMaxStubSize();
     }
+    RelocationEntry TargetRE(Value.SectionID, Offset, RelType, 0, IsPCRel,
+                             Size);
+    resolveRelocation(TargetRE, (uint64_t)Addr);
   } else {
     RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size);
     if (Value.SymbolName)
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 1006176..060eb8c 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -25,22 +25,31 @@
 
 namespace llvm {
 class RuntimeDyldMachO : public RuntimeDyldImpl {
-  bool resolveI386Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
-                             uint64_t Value, bool isPCRel, unsigned Type,
-                             unsigned Size, int64_t Addend);
-  bool resolveX86_64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
-                               uint64_t Value, bool isPCRel, unsigned Type,
-                               unsigned Size, int64_t Addend);
-  bool resolveARMRelocation(uint8_t *LocalAddress, uint64_t FinalAddress,
-                            uint64_t Value, bool isPCRel, unsigned Type,
-                            unsigned Size, int64_t Addend);
-  bool resolveARM64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
-                              uint64_t Value, bool IsPCRel, unsigned Type,
-                              unsigned Size, int64_t Addend);
+private:
 
-  void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
-                         uint64_t Value, uint32_t Type, int64_t Addend,
-                         bool isPCRel, unsigned Size);
+  /// Write the least significant 'Size' bytes in 'Value' out at the address
+  /// pointed to by Addr.
+  bool applyRelocationValue(uint8_t *Addr, uint64_t Value, unsigned Size) {
+    for (unsigned i = 0; i < Size; ++i) {
+      *Addr++ = (uint8_t)Value;
+      Value >>= 8;
+    }
+
+    return false;
+  }
+
+  bool resolveI386Relocation(const RelocationEntry &RE, uint64_t Value);
+  bool resolveX86_64Relocation(const RelocationEntry &RE, uint64_t Value);
+  bool resolveARMRelocation(const RelocationEntry &RE, uint64_t Value);
+  bool resolveAArch64Relocation(const RelocationEntry &RE, uint64_t Value);
+
+  // Populate stubs in __jump_table section.
+  void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection,
+                         unsigned JTSectionID);
+
+  // Populate __pointers section.
+  void populatePointersSection(MachOObjectFile &Obj, const SectionRef &PTSection,
+                               unsigned PTSectionID);
 
   unsigned getMaxStubSize() override {
     if (Arch == Triple::arm || Arch == Triple::thumb)
@@ -53,6 +62,18 @@
 
   unsigned getStubAlignment() override { return 1; }
 
+  relocation_iterator processSECTDIFFRelocation(
+                                             unsigned SectionID,
+                                             relocation_iterator RelI,
+                                             ObjectImage &ObjImg,
+                                             ObjSectionToIDMap &ObjSectionToID);
+
+  relocation_iterator processI386ScatteredVANILLA(
+					     unsigned SectionID,
+					     relocation_iterator RelI,
+					     ObjectImage &ObjImg,
+					     ObjSectionToIDMap &ObjSectionToID);
+
   struct EHFrameRelatedSections {
     EHFrameRelatedSections()
         : EHFrameSID(RTDYLD_INVALID_SECTION_ID),
@@ -81,15 +102,16 @@
   bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
   bool isCompatibleFile(const object::ObjectFile *Obj) const override;
   void registerEHFrames() override;
-  void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
+  void finalizeLoad(ObjectImage &ObjImg,
+                    ObjSectionToIDMap &SectionMap) override;
 
   static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
     return new ObjectImageCommon(InputBuffer);
   }
 
   static ObjectImage *
-  createObjectImageFromFile(object::ObjectFile *InputObject) {
-    return new ObjectImageCommon(InputObject);
+  createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject) {
+    return new ObjectImageCommon(std::move(InputObject));
   }
 };