Update prebuilt Clang to r365631c1 from Android.

The version we had was segfaulting.

Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
new file mode 100644
index 0000000..8d2f641
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h
@@ -0,0 +1,80 @@
+//===--------- EHFrameSupport.h - JITLink eh-frame utils --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// EHFrame registration support for JITLink.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
+#define LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace jitlink {
+
+/// Registers all FDEs in the given eh-frame section with the current process.
+Error registerEHFrameSection(const void *EHFrameSectionAddr);
+
+/// Deregisters all FDEs in the given eh-frame section with the current process.
+Error deregisterEHFrameSection(const void *EHFrameSectionAddr);
+
+/// Supports registration/deregistration of EH-frames in a target process.
+class EHFrameRegistrar {
+public:
+  virtual ~EHFrameRegistrar();
+  virtual Error registerEHFrames(JITTargetAddress EHFrameSectionAddr) = 0;
+  virtual Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr) = 0;
+};
+
+/// Registers / Deregisters EH-frames in the current process.
+class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
+public:
+  /// Get a reference to the InProcessEHFrameRegistrar singleton.
+  static InProcessEHFrameRegistrar &getInstance();
+
+  InProcessEHFrameRegistrar(const InProcessEHFrameRegistrar &) = delete;
+  InProcessEHFrameRegistrar &
+  operator=(const InProcessEHFrameRegistrar &) = delete;
+
+  InProcessEHFrameRegistrar(InProcessEHFrameRegistrar &&) = delete;
+  InProcessEHFrameRegistrar &operator=(InProcessEHFrameRegistrar &&) = delete;
+
+  Error registerEHFrames(JITTargetAddress EHFrameSectionAddr) override {
+    return registerEHFrameSection(
+        jitTargetAddressToPointer<void *>(EHFrameSectionAddr));
+  }
+
+  Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr) override {
+    return deregisterEHFrameSection(
+        jitTargetAddressToPointer<void *>(EHFrameSectionAddr));
+  }
+
+private:
+  InProcessEHFrameRegistrar();
+};
+
+using StoreFrameAddressFunction = std::function<void(JITTargetAddress)>;
+
+/// Creates a pass that records the address of the EH frame section. If no
+/// eh-frame section is found, it will set EHFrameAddr to zero.
+///
+/// Authors of JITLinkContexts can use this function to register a post-fixup
+/// pass that records the address of the eh-frame section. This address can
+/// be used after finalization to register and deregister the frame.
+AtomGraphPassFunction
+createEHFrameRecorderPass(const Triple &TT,
+                          StoreFrameAddressFunction StoreFrameAddress);
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_EHFRAMESUPPORT_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLink.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLink.h
new file mode 100644
index 0000000..be80d44
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -0,0 +1,930 @@
+//===------------ JITLink.h - JIT linker functionality ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains generic JIT-linker types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
+#define LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
+
+#include "JITLinkMemoryManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include <map>
+#include <string>
+#include <system_error>
+
+namespace llvm {
+namespace jitlink {
+
+/// Base class for errors originating in JIT linker, e.g. missing relocation
+/// support.
+class JITLinkError : public ErrorInfo<JITLinkError> {
+public:
+  static char ID;
+
+  JITLinkError(Twine ErrMsg) : ErrMsg(ErrMsg.str()) {}
+
+  void log(raw_ostream &OS) const override;
+  const std::string &getErrorMessage() const { return ErrMsg; }
+  std::error_code convertToErrorCode() const override;
+
+private:
+  std::string ErrMsg;
+};
+
+// Forward declare the Atom class.
+class Atom;
+
+/// Edge class. Represents both object file relocations, as well as layout and
+/// keep-alive constraints.
+class Edge {
+public:
+  using Kind = uint8_t;
+
+  using GenericEdgeKind = enum : Kind {
+    Invalid,                    // Invalid edge value.
+    FirstKeepAlive,             // Keeps target alive. Offset/addend zero.
+    KeepAlive = FirstKeepAlive, // Tag first edge kind that preserves liveness.
+    LayoutNext,                 // Layout constraint. Offset/Addend zero.
+    FirstRelocation             // First architecture specific relocation.
+  };
+
+  using OffsetT = uint32_t;
+  using AddendT = int64_t;
+
+  Edge(Kind K, OffsetT Offset, Atom &Target, AddendT Addend)
+      : Target(&Target), Offset(Offset), Addend(Addend), K(K) {}
+
+  OffsetT getOffset() const { return Offset; }
+  Kind getKind() const { return K; }
+  void setKind(Kind K) { this->K = K; }
+  bool isRelocation() const { return K >= FirstRelocation; }
+  Kind getRelocation() const {
+    assert(isRelocation() && "Not a relocation edge");
+    return K - FirstRelocation;
+  }
+  bool isKeepAlive() const { return K >= FirstKeepAlive; }
+  Atom &getTarget() const { return *Target; }
+  void setTarget(Atom &Target) { this->Target = &Target; }
+  AddendT getAddend() const { return Addend; }
+  void setAddend(AddendT Addend) { this->Addend = Addend; }
+
+private:
+  Atom *Target;
+  OffsetT Offset;
+  AddendT Addend;
+  Kind K = 0;
+};
+
+using EdgeVector = std::vector<Edge>;
+
+const StringRef getGenericEdgeKindName(Edge::Kind K);
+
+/// Base Atom class. Used by absolute and undefined atoms.
+class Atom {
+  friend class AtomGraph;
+
+protected:
+  /// Create a named (as yet unresolved) atom.
+  Atom(StringRef Name)
+      : Name(Name), IsDefined(false), IsLive(false), ShouldDiscard(false),
+        IsGlobal(false), IsAbsolute(false), IsCallable(false),
+        IsExported(false), IsWeak(false), HasLayoutNext(false),
+        IsCommon(false) {}
+
+  /// Create an absolute symbol atom.
+  Atom(StringRef Name, JITTargetAddress Address)
+      : Name(Name), Address(Address), IsDefined(true), IsLive(false),
+        ShouldDiscard(false), IsGlobal(false), IsAbsolute(false),
+        IsCallable(false), IsExported(false), IsWeak(false),
+        HasLayoutNext(false), IsCommon(false) {}
+
+public:
+  /// Returns true if this atom has a name.
+  bool hasName() const { return Name != StringRef(); }
+
+  /// Returns the name of this atom.
+  StringRef getName() const { return Name; }
+
+  /// Returns the current target address of this atom.
+  /// The initial target address (for atoms that have one) will be taken from
+  /// the input object file's virtual address space. During the layout phase
+  /// of JIT linking the atom's address will be updated to point to its final
+  /// address in the JIT'd process.
+  JITTargetAddress getAddress() const { return Address; }
+
+  /// Set the current target address of this atom.
+  void setAddress(JITTargetAddress Address) { this->Address = Address; }
+
+  /// Returns true if this is a defined atom.
+  bool isDefined() const { return IsDefined; }
+
+  /// Returns true if this atom is marked as live.
+  bool isLive() const { return IsLive; }
+
+  /// Mark this atom as live.
+  ///
+  /// Note: Only defined and absolute atoms can be marked live.
+  void setLive(bool IsLive) {
+    assert((IsDefined || IsAbsolute || !IsLive) &&
+           "Only defined and absolute atoms can be marked live");
+    this->IsLive = IsLive;
+  }
+
+  /// Returns true if this atom should be discarded during pruning.
+  bool shouldDiscard() const { return ShouldDiscard; }
+
+  /// Mark this atom to be discarded.
+  ///
+  /// Note: Only defined and absolute atoms can be marked live.
+  void setShouldDiscard(bool ShouldDiscard) {
+    assert((IsDefined || IsAbsolute || !ShouldDiscard) &&
+           "Only defined and absolute atoms can be marked live");
+    this->ShouldDiscard = ShouldDiscard;
+  }
+
+  /// Returns true if this definition is global (i.e. visible outside this
+  /// linkage unit).
+  ///
+  /// Note: This is distict from Exported, which means visibile outside the
+  /// JITDylib that this graph is being linked in to.
+  bool isGlobal() const { return IsGlobal; }
+
+  /// Mark this atom as global.
+  void setGlobal(bool IsGlobal) { this->IsGlobal = IsGlobal; }
+
+  /// Returns true if this atom represents an absolute symbol.
+  bool isAbsolute() const { return IsAbsolute; }
+
+  /// Returns true if this atom is known to be callable.
+  ///
+  /// Primarily provided for easy interoperability with ORC, which uses the
+  /// JITSymbolFlags::Common flag to identify symbols that can be interposed
+  /// with stubs.
+  bool isCallable() const { return IsCallable; }
+
+  /// Mark this atom as callable.
+  void setCallable(bool IsCallable) {
+    assert((IsDefined || IsAbsolute || !IsCallable) &&
+           "Callable atoms must be defined or absolute");
+    this->IsCallable = IsCallable;
+  }
+
+  /// Returns true if this atom should appear in the symbol table of a final
+  /// linked image.
+  bool isExported() const { return IsExported; }
+
+  /// Mark this atom as exported.
+  void setExported(bool IsExported) {
+    assert((!IsExported || ((IsDefined || IsAbsolute) && hasName())) &&
+           "Exported atoms must have names");
+    this->IsExported = IsExported;
+  }
+
+  /// Returns true if this is a weak symbol.
+  bool isWeak() const { return IsWeak; }
+
+  /// Mark this atom as weak.
+  void setWeak(bool IsWeak) { this->IsWeak = IsWeak; }
+
+private:
+  StringRef Name;
+  JITTargetAddress Address = 0;
+
+  bool IsDefined : 1;
+  bool IsLive : 1;
+  bool ShouldDiscard : 1;
+
+  bool IsGlobal : 1;
+  bool IsAbsolute : 1;
+  bool IsCallable : 1;
+  bool IsExported : 1;
+  bool IsWeak : 1;
+
+protected:
+  // These flags only make sense for DefinedAtom, but we can minimize the size
+  // of DefinedAtom by defining them here.
+  bool HasLayoutNext : 1;
+  bool IsCommon : 1;
+};
+
+// Forward declare DefinedAtom.
+class DefinedAtom;
+
+raw_ostream &operator<<(raw_ostream &OS, const Atom &A);
+void printEdge(raw_ostream &OS, const Atom &FixupAtom, const Edge &E,
+               StringRef EdgeKindName);
+
+/// Represents a section address range via a pair of DefinedAtom pointers to
+/// the first and last atoms in the section.
+class SectionRange {
+public:
+  SectionRange() = default;
+  SectionRange(DefinedAtom *First, DefinedAtom *Last)
+      : First(First), Last(Last) {}
+  DefinedAtom *getFirstAtom() const {
+    assert((!Last || First) && "First can not be null if end is non-null");
+    return First;
+  }
+  DefinedAtom *getLastAtom() const {
+    assert((First || !Last) && "Last can not be null if start is non-null");
+    return Last;
+  }
+  bool isEmpty() const {
+    assert((First || !Last) && "Last can not be null if start is non-null");
+    return !First;
+  }
+  JITTargetAddress getStart() const;
+  JITTargetAddress getEnd() const;
+  uint64_t getSize() const;
+
+private:
+  DefinedAtom *First = nullptr;
+  DefinedAtom *Last = nullptr;
+};
+
+/// Represents an object file section.
+class Section {
+  friend class AtomGraph;
+
+private:
+  Section(StringRef Name, uint32_t Alignment, sys::Memory::ProtectionFlags Prot,
+          unsigned Ordinal, bool IsZeroFill)
+      : Name(Name), Alignment(Alignment), Prot(Prot), Ordinal(Ordinal),
+        IsZeroFill(IsZeroFill) {
+    assert(isPowerOf2_32(Alignment) && "Alignments must be a power of 2");
+  }
+
+  using DefinedAtomSet = DenseSet<DefinedAtom *>;
+
+public:
+  using atom_iterator = DefinedAtomSet::iterator;
+  using const_atom_iterator = DefinedAtomSet::const_iterator;
+
+  ~Section();
+  StringRef getName() const { return Name; }
+  uint32_t getAlignment() const { return Alignment; }
+  sys::Memory::ProtectionFlags getProtectionFlags() const { return Prot; }
+  unsigned getSectionOrdinal() const { return Ordinal; }
+  size_t getNextAtomOrdinal() { return ++NextAtomOrdinal; }
+
+  bool isZeroFill() const { return IsZeroFill; }
+
+  /// Returns an iterator over the atoms in the section (in no particular
+  /// order).
+  iterator_range<atom_iterator> atoms() {
+    return make_range(DefinedAtoms.begin(), DefinedAtoms.end());
+  }
+
+  /// Returns an iterator over the atoms in the section (in no particular
+  /// order).
+  iterator_range<const_atom_iterator> atoms() const {
+    return make_range(DefinedAtoms.begin(), DefinedAtoms.end());
+  }
+
+  /// Return the number of atoms in this section.
+  DefinedAtomSet::size_type atoms_size() { return DefinedAtoms.size(); }
+
+  /// Return true if this section contains no atoms.
+  bool atoms_empty() const { return DefinedAtoms.empty(); }
+
+  /// Returns the range of this section as the pair of atoms with the lowest
+  /// and highest target address. This operation is expensive, as it
+  /// must traverse all atoms in the section.
+  ///
+  /// Note: If the section is empty, both values will be null. The section
+  /// address will evaluate to null, and the size to zero. If the section
+  /// contains a single atom both values will point to it, the address will
+  /// evaluate to the address of that atom, and the size will be the size of
+  /// that atom.
+  SectionRange getRange() const;
+
+private:
+  void addAtom(DefinedAtom &DA) {
+    assert(!DefinedAtoms.count(&DA) && "Atom is already in this section");
+    DefinedAtoms.insert(&DA);
+  }
+
+  void removeAtom(DefinedAtom &DA) {
+    assert(DefinedAtoms.count(&DA) && "Atom is not in this section");
+    DefinedAtoms.erase(&DA);
+  }
+
+  StringRef Name;
+  uint32_t Alignment = 0;
+  sys::Memory::ProtectionFlags Prot;
+  unsigned Ordinal = 0;
+  unsigned NextAtomOrdinal = 0;
+  bool IsZeroFill = false;
+  DefinedAtomSet DefinedAtoms;
+};
+
+/// Defined atom class. Suitable for use by defined named and anonymous
+/// atoms.
+class DefinedAtom : public Atom {
+  friend class AtomGraph;
+
+private:
+  DefinedAtom(Section &Parent, JITTargetAddress Address, uint32_t Alignment)
+      : Atom("", Address), Parent(Parent), Ordinal(Parent.getNextAtomOrdinal()),
+        Alignment(Alignment) {
+    assert(isPowerOf2_32(Alignment) && "Alignments must be a power of two");
+  }
+
+  DefinedAtom(Section &Parent, StringRef Name, JITTargetAddress Address,
+              uint32_t Alignment)
+      : Atom(Name, Address), Parent(Parent),
+        Ordinal(Parent.getNextAtomOrdinal()), Alignment(Alignment) {
+    assert(isPowerOf2_32(Alignment) && "Alignments must be a power of two");
+  }
+
+public:
+  using edge_iterator = EdgeVector::iterator;
+
+  Section &getSection() const { return Parent; }
+
+  uint64_t getSize() const { return Size; }
+
+  StringRef getContent() const {
+    assert(!Parent.isZeroFill() && "Trying to get content for zero-fill atom");
+    assert(Size <= std::numeric_limits<size_t>::max() &&
+           "Content size too large");
+    return {ContentPtr, static_cast<size_t>(Size)};
+  }
+  void setContent(StringRef Content) {
+    assert(!Parent.isZeroFill() && "Calling setContent on zero-fill atom?");
+    ContentPtr = Content.data();
+    Size = Content.size();
+  }
+
+  bool isZeroFill() const { return Parent.isZeroFill(); }
+
+  void setZeroFill(uint64_t Size) {
+    assert(Parent.isZeroFill() && !ContentPtr &&
+           "Can't set zero-fill length of a non zero-fill atom");
+    this->Size = Size;
+  }
+
+  uint64_t getZeroFillSize() const {
+    assert(Parent.isZeroFill() &&
+           "Can't get zero-fill length of a non zero-fill atom");
+    return Size;
+  }
+
+  uint32_t getAlignment() const { return Alignment; }
+
+  bool hasLayoutNext() const { return HasLayoutNext; }
+  void setLayoutNext(DefinedAtom &Next) {
+    assert(!HasLayoutNext && "Atom already has layout-next constraint");
+    HasLayoutNext = true;
+    Edges.push_back(Edge(Edge::LayoutNext, 0, Next, 0));
+  }
+  DefinedAtom &getLayoutNext() {
+    assert(HasLayoutNext && "Atom does not have a layout-next constraint");
+    DefinedAtom *Next = nullptr;
+    for (auto &E : edges())
+      if (E.getKind() == Edge::LayoutNext) {
+        assert(E.getTarget().isDefined() &&
+               "layout-next target atom must be a defined atom");
+        Next = static_cast<DefinedAtom *>(&E.getTarget());
+        break;
+      }
+    assert(Next && "Missing LayoutNext edge");
+    return *Next;
+  }
+
+  bool isCommon() const { return IsCommon; }
+
+  void addEdge(Edge::Kind K, Edge::OffsetT Offset, Atom &Target,
+               Edge::AddendT Addend) {
+    assert(K != Edge::LayoutNext &&
+           "Layout edges should be added via setLayoutNext");
+    Edges.push_back(Edge(K, Offset, Target, Addend));
+  }
+
+  iterator_range<edge_iterator> edges() {
+    return make_range(Edges.begin(), Edges.end());
+  }
+  size_t edges_size() const { return Edges.size(); }
+  bool edges_empty() const { return Edges.empty(); }
+
+  unsigned getOrdinal() const { return Ordinal; }
+
+private:
+  void setCommon(uint64_t Size) {
+    assert(ContentPtr == 0 && "Atom already has content?");
+    IsCommon = true;
+    setZeroFill(Size);
+  }
+
+  EdgeVector Edges;
+  uint64_t Size = 0;
+  Section &Parent;
+  const char *ContentPtr = nullptr;
+  unsigned Ordinal = 0;
+  uint32_t Alignment = 0;
+};
+
+inline JITTargetAddress SectionRange::getStart() const {
+  return First ? First->getAddress() : 0;
+}
+
+inline JITTargetAddress SectionRange::getEnd() const {
+  return Last ? Last->getAddress() + Last->getSize() : 0;
+}
+
+inline uint64_t SectionRange::getSize() const { return getEnd() - getStart(); }
+
+inline SectionRange Section::getRange() const {
+  if (atoms_empty())
+    return SectionRange();
+  DefinedAtom *First = *DefinedAtoms.begin(), *Last = *DefinedAtoms.begin();
+  for (auto *DA : atoms()) {
+    if (DA->getAddress() < First->getAddress())
+      First = DA;
+    if (DA->getAddress() > Last->getAddress())
+      Last = DA;
+  }
+  return SectionRange(First, Last);
+}
+
+class AtomGraph {
+private:
+  using SectionList = std::vector<std::unique_ptr<Section>>;
+  using AddressToAtomMap = std::map<JITTargetAddress, DefinedAtom *>;
+  using NamedAtomMap = DenseMap<StringRef, Atom *>;
+  using ExternalAtomSet = DenseSet<Atom *>;
+
+public:
+  using external_atom_iterator = ExternalAtomSet::iterator;
+
+  using section_iterator = pointee_iterator<SectionList::iterator>;
+  using const_section_iterator = pointee_iterator<SectionList::const_iterator>;
+
+  template <typename SecItrT, typename AtomItrT, typename T>
+  class defined_atom_iterator_impl
+      : public iterator_facade_base<
+            defined_atom_iterator_impl<SecItrT, AtomItrT, T>,
+            std::forward_iterator_tag, T> {
+  public:
+    defined_atom_iterator_impl() = default;
+
+    defined_atom_iterator_impl(SecItrT SI, SecItrT SE)
+        : SI(SI), SE(SE),
+          AI(SI != SE ? SI->atoms().begin() : Section::atom_iterator()) {
+      moveToNextAtomOrEnd();
+    }
+
+    bool operator==(const defined_atom_iterator_impl &RHS) const {
+      return (SI == RHS.SI) && (AI == RHS.AI);
+    }
+
+    T operator*() const {
+      assert(AI != SI->atoms().end() && "Dereferencing end?");
+      return *AI;
+    }
+
+    defined_atom_iterator_impl operator++() {
+      ++AI;
+      moveToNextAtomOrEnd();
+      return *this;
+    }
+
+  private:
+    void moveToNextAtomOrEnd() {
+      while (SI != SE && AI == SI->atoms().end()) {
+        ++SI;
+        if (SI == SE)
+          AI = Section::atom_iterator();
+        else
+          AI = SI->atoms().begin();
+      }
+    }
+
+    SecItrT SI, SE;
+    AtomItrT AI;
+  };
+
+  using defined_atom_iterator =
+      defined_atom_iterator_impl<section_iterator, Section::atom_iterator,
+                                 DefinedAtom *>;
+
+  using const_defined_atom_iterator =
+      defined_atom_iterator_impl<const_section_iterator,
+                                 Section::const_atom_iterator,
+                                 const DefinedAtom *>;
+
+  AtomGraph(std::string Name, unsigned PointerSize,
+            support::endianness Endianness)
+      : Name(std::move(Name)), PointerSize(PointerSize),
+        Endianness(Endianness) {}
+
+  /// Returns the name of this graph (usually the name of the original
+  /// underlying MemoryBuffer).
+  const std::string &getName() { return Name; }
+
+  /// Returns the pointer size for use in this graph.
+  unsigned getPointerSize() const { return PointerSize; }
+
+  /// Returns the endianness of atom-content in this graph.
+  support::endianness getEndianness() const { return Endianness; }
+
+  /// Create a section with the given name, protection flags, and alignment.
+  Section &createSection(StringRef Name, uint32_t Alignment,
+                         sys::Memory::ProtectionFlags Prot, bool IsZeroFill) {
+    std::unique_ptr<Section> Sec(
+        new Section(Name, Alignment, Prot, Sections.size(), IsZeroFill));
+    Sections.push_back(std::move(Sec));
+    return *Sections.back();
+  }
+
+  /// Add an external atom representing an undefined symbol in this graph.
+  Atom &addExternalAtom(StringRef Name) {
+    assert(!NamedAtoms.count(Name) && "Duplicate named atom inserted");
+    Atom *A = reinterpret_cast<Atom *>(
+        AtomAllocator.Allocate(sizeof(Atom), alignof(Atom)));
+    new (A) Atom(Name);
+    ExternalAtoms.insert(A);
+    NamedAtoms[Name] = A;
+    return *A;
+  }
+
+  /// Add an external atom representing an absolute symbol.
+  Atom &addAbsoluteAtom(StringRef Name, JITTargetAddress Addr) {
+    assert(!NamedAtoms.count(Name) && "Duplicate named atom inserted");
+    Atom *A = reinterpret_cast<Atom *>(
+        AtomAllocator.Allocate(sizeof(Atom), alignof(Atom)));
+    new (A) Atom(Name, Addr);
+    AbsoluteAtoms.insert(A);
+    NamedAtoms[Name] = A;
+    return *A;
+  }
+
+  /// Add an anonymous defined atom to the graph.
+  ///
+  /// Anonymous atoms have content but no name. They must have an address.
+  DefinedAtom &addAnonymousAtom(Section &Parent, JITTargetAddress Address,
+                                uint32_t Alignment) {
+    DefinedAtom *A = reinterpret_cast<DefinedAtom *>(
+        AtomAllocator.Allocate(sizeof(DefinedAtom), alignof(DefinedAtom)));
+    new (A) DefinedAtom(Parent, Address, Alignment);
+    Parent.addAtom(*A);
+    getAddrToAtomMap()[A->getAddress()] = A;
+    return *A;
+  }
+
+  /// Add a defined atom to the graph.
+  ///
+  /// Allocates and constructs a DefinedAtom instance with the given parent,
+  /// name, address, and alignment.
+  DefinedAtom &addDefinedAtom(Section &Parent, StringRef Name,
+                              JITTargetAddress Address, uint32_t Alignment) {
+    assert(!NamedAtoms.count(Name) && "Duplicate named atom inserted");
+    DefinedAtom *A = reinterpret_cast<DefinedAtom *>(
+        AtomAllocator.Allocate(sizeof(DefinedAtom), alignof(DefinedAtom)));
+    new (A) DefinedAtom(Parent, Name, Address, Alignment);
+    Parent.addAtom(*A);
+    getAddrToAtomMap()[A->getAddress()] = A;
+    NamedAtoms[Name] = A;
+    return *A;
+  }
+
+  /// Add a common symbol atom to the graph.
+  ///
+  /// Adds a common-symbol atom to the graph with the given parent, name,
+  /// address, alignment and size.
+  DefinedAtom &addCommonAtom(Section &Parent, StringRef Name,
+                             JITTargetAddress Address, uint32_t Alignment,
+                             uint64_t Size) {
+    assert(!NamedAtoms.count(Name) && "Duplicate named atom inserted");
+    DefinedAtom *A = reinterpret_cast<DefinedAtom *>(
+        AtomAllocator.Allocate(sizeof(DefinedAtom), alignof(DefinedAtom)));
+    new (A) DefinedAtom(Parent, Name, Address, Alignment);
+    A->setCommon(Size);
+    Parent.addAtom(*A);
+    NamedAtoms[Name] = A;
+    return *A;
+  }
+
+  iterator_range<section_iterator> sections() {
+    return make_range(section_iterator(Sections.begin()),
+                      section_iterator(Sections.end()));
+  }
+
+  /// Returns the section with the given name if it exists, otherwise returns
+  /// null.
+  Section *findSectionByName(StringRef Name) {
+    for (auto &S : sections())
+      if (S.getName() == Name)
+        return &S;
+    return nullptr;
+  }
+
+  iterator_range<external_atom_iterator> external_atoms() {
+    return make_range(ExternalAtoms.begin(), ExternalAtoms.end());
+  }
+
+  iterator_range<external_atom_iterator> absolute_atoms() {
+    return make_range(AbsoluteAtoms.begin(), AbsoluteAtoms.end());
+  }
+
+  iterator_range<defined_atom_iterator> defined_atoms() {
+    return make_range(defined_atom_iterator(Sections.begin(), Sections.end()),
+                      defined_atom_iterator(Sections.end(), Sections.end()));
+  }
+
+  iterator_range<const_defined_atom_iterator> defined_atoms() const {
+    return make_range(
+        const_defined_atom_iterator(Sections.begin(), Sections.end()),
+        const_defined_atom_iterator(Sections.end(), Sections.end()));
+  }
+
+  /// Returns the atom with the given name, which must exist in this graph.
+  Atom &getAtomByName(StringRef Name) {
+    auto I = NamedAtoms.find(Name);
+    assert(I != NamedAtoms.end() && "Name not in NamedAtoms map");
+    return *I->second;
+  }
+
+  /// Returns the atom with the given name, which must exist in this graph and
+  /// be a DefinedAtom.
+  DefinedAtom &getDefinedAtomByName(StringRef Name) {
+    auto &A = getAtomByName(Name);
+    assert(A.isDefined() && "Atom is not a defined atom");
+    return static_cast<DefinedAtom &>(A);
+  }
+
+  /// Search for the given atom by name.
+  /// Returns the atom (if found) or an error (if no atom with this name
+  /// exists).
+  Expected<Atom &> findAtomByName(StringRef Name) {
+    auto I = NamedAtoms.find(Name);
+    if (I == NamedAtoms.end())
+      return make_error<JITLinkError>("No atom named " + Name);
+    return *I->second;
+  }
+
+  /// Search for the given defined atom by name.
+  /// Returns the defined atom (if found) or an error (if no atom with this
+  /// name exists, or if one exists but is not a defined atom).
+  Expected<DefinedAtom &> findDefinedAtomByName(StringRef Name) {
+    auto I = NamedAtoms.find(Name);
+    if (I == NamedAtoms.end())
+      return make_error<JITLinkError>("No atom named " + Name);
+    if (!I->second->isDefined())
+      return make_error<JITLinkError>("Atom " + Name +
+                                      " exists but is not a "
+                                      "defined atom");
+    return static_cast<DefinedAtom &>(*I->second);
+  }
+
+  /// Returns the atom covering the given address, or an error if no such atom
+  /// exists.
+  ///
+  /// Returns null if no atom exists at the given address.
+  DefinedAtom *getAtomByAddress(JITTargetAddress Address) {
+    refreshAddrToAtomCache();
+
+    // If there are no defined atoms, bail out early.
+    if (AddrToAtomCache->empty())
+      return nullptr;
+
+    // Find the atom *after* the given address.
+    auto I = AddrToAtomCache->upper_bound(Address);
+
+    // If this address falls before any known atom, bail out.
+    if (I == AddrToAtomCache->begin())
+      return nullptr;
+
+    // The atom we're looking for is the one before the atom we found.
+    --I;
+
+    // Otherwise range check the atom that was found.
+    assert(!I->second->getContent().empty() && "Atom content not set");
+    if (Address >= I->second->getAddress() + I->second->getContent().size())
+      return nullptr;
+
+    return I->second;
+  }
+
+  /// Like getAtomByAddress, but returns an Error if the given address is not
+  /// covered by an atom, rather than a null pointer.
+  Expected<DefinedAtom &> findAtomByAddress(JITTargetAddress Address) {
+    if (auto *DA = getAtomByAddress(Address))
+      return *DA;
+    return make_error<JITLinkError>("No atom at address " +
+                                    formatv("{0:x16}", Address));
+  }
+
+  // Remove the given external atom from the graph.
+  void removeExternalAtom(Atom &A) {
+    assert(!A.isDefined() && !A.isAbsolute() && "A is not an external atom");
+    assert(ExternalAtoms.count(&A) && "A is not in the external atoms set");
+    ExternalAtoms.erase(&A);
+    A.~Atom();
+  }
+
+  /// Remove the given absolute atom from the graph.
+  void removeAbsoluteAtom(Atom &A) {
+    assert(A.isAbsolute() && "A is not an absolute atom");
+    assert(AbsoluteAtoms.count(&A) && "A is not in the absolute atoms set");
+    AbsoluteAtoms.erase(&A);
+    A.~Atom();
+  }
+
+  /// Remove the given defined atom from the graph.
+  void removeDefinedAtom(DefinedAtom &DA) {
+    if (AddrToAtomCache) {
+      assert(AddrToAtomCache->count(DA.getAddress()) &&
+             "Cache exists, but does not contain atom");
+      AddrToAtomCache->erase(DA.getAddress());
+    }
+    if (DA.hasName()) {
+      assert(NamedAtoms.count(DA.getName()) && "Named atom not in map");
+      NamedAtoms.erase(DA.getName());
+    }
+    DA.getSection().removeAtom(DA);
+    DA.~DefinedAtom();
+  }
+
+  /// Invalidate the atom-to-address map.
+  void invalidateAddrToAtomMap() { AddrToAtomCache = None; }
+
+  /// Dump the graph.
+  ///
+  /// If supplied, the EdgeKindToName function will be used to name edge
+  /// kinds in the debug output. Otherwise raw edge kind numbers will be
+  /// displayed.
+  void dump(raw_ostream &OS,
+            std::function<StringRef(Edge::Kind)> EdegKindToName =
+                std::function<StringRef(Edge::Kind)>());
+
+private:
+  AddressToAtomMap &getAddrToAtomMap() {
+    refreshAddrToAtomCache();
+    return *AddrToAtomCache;
+  }
+
+  const AddressToAtomMap &getAddrToAtomMap() const {
+    refreshAddrToAtomCache();
+    return *AddrToAtomCache;
+  }
+
+  void refreshAddrToAtomCache() const {
+    if (!AddrToAtomCache) {
+      AddrToAtomCache = AddressToAtomMap();
+      for (auto *DA : defined_atoms())
+        (*AddrToAtomCache)[DA->getAddress()] = const_cast<DefinedAtom *>(DA);
+    }
+  }
+
+  // Put the BumpPtrAllocator first so that we don't free any of the atoms in
+  // it until all of their destructors have been run.
+  BumpPtrAllocator AtomAllocator;
+
+  std::string Name;
+  unsigned PointerSize;
+  support::endianness Endianness;
+  SectionList Sections;
+  NamedAtomMap NamedAtoms;
+  ExternalAtomSet ExternalAtoms;
+  ExternalAtomSet AbsoluteAtoms;
+  mutable Optional<AddressToAtomMap> AddrToAtomCache;
+};
+
+/// A function for mutating AtomGraphs.
+using AtomGraphPassFunction = std::function<Error(AtomGraph &)>;
+
+/// A list of atom graph passes.
+using AtomGraphPassList = std::vector<AtomGraphPassFunction>;
+
+/// An atom graph pass configuration, consisting of a list of pre-prune,
+/// post-prune, and post-fixup passes.
+struct PassConfiguration {
+
+  /// Pre-prune passes.
+  ///
+  /// These passes are called on the graph after it is built, and before any
+  /// atoms have been pruned.
+  ///
+  /// Notable use cases: Marking atoms live or should-discard.
+  AtomGraphPassList PrePrunePasses;
+
+  /// Post-prune passes.
+  ///
+  /// These passes are called on the graph after dead and should-discard atoms
+  /// have been removed, but before fixups are applied.
+  ///
+  /// Notable use cases: Building GOT, stub, and TLV atoms.
+  AtomGraphPassList PostPrunePasses;
+
+  /// Post-fixup passes.
+  ///
+  /// These passes are called on the graph after atom contents has been copied
+  /// to working memory, and fixups applied.
+  ///
+  /// Notable use cases: Testing and validation.
+  AtomGraphPassList PostFixupPasses;
+};
+
+/// A map of symbol names to resolved addresses.
+using AsyncLookupResult = DenseMap<StringRef, JITEvaluatedSymbol>;
+
+/// A function to call with a resolved symbol map (See AsyncLookupResult) or an
+/// error if resolution failed.
+using JITLinkAsyncLookupContinuation =
+    std::function<void(Expected<AsyncLookupResult> LR)>;
+
+/// An asynchronous symbol lookup. Performs a search (possibly asynchronously)
+/// for the given symbols, calling the given continuation with either the result
+/// (if the lookup succeeds), or an error (if the lookup fails).
+using JITLinkAsyncLookupFunction =
+    std::function<void(const DenseSet<StringRef> &Symbols,
+                       JITLinkAsyncLookupContinuation LookupContinuation)>;
+
+/// Holds context for a single jitLink invocation.
+class JITLinkContext {
+public:
+  /// Destroy a JITLinkContext.
+  virtual ~JITLinkContext();
+
+  /// Return the MemoryManager to be used for this link.
+  virtual JITLinkMemoryManager &getMemoryManager() = 0;
+
+  /// Returns a StringRef for the object buffer.
+  /// This method can not be called once takeObjectBuffer has been called.
+  virtual MemoryBufferRef getObjectBuffer() const = 0;
+
+  /// Notify this context that linking failed.
+  /// Called by JITLink if linking cannot be completed.
+  virtual void notifyFailed(Error Err) = 0;
+
+  /// Called by JITLink to resolve external symbols. This method is passed a
+  /// lookup continutation which it must call with a result to continue the
+  /// linking process.
+  virtual void lookup(const DenseSet<StringRef> &Symbols,
+                      JITLinkAsyncLookupContinuation LookupContinuation) = 0;
+
+  /// Called by JITLink once all defined atoms in the graph have been assigned
+  /// their final memory locations in the target process. At this point he
+  /// atom graph can be, inspected to build a symbol table however the atom
+  /// content will not generally have been copied to the target location yet.
+  virtual void notifyResolved(AtomGraph &G) = 0;
+
+  /// Called by JITLink to notify the context that the object has been
+  /// finalized (i.e. emitted to memory and memory permissions set). If all of
+  /// this objects dependencies have also been finalized then the code is ready
+  /// to run.
+  virtual void
+  notifyFinalized(std::unique_ptr<JITLinkMemoryManager::Allocation> A) = 0;
+
+  /// Called by JITLink prior to linking to determine whether default passes for
+  /// the target should be added. The default implementation returns true.
+  /// If subclasses override this method to return false for any target then
+  /// they are required to fully configure the pass pipeline for that target.
+  virtual bool shouldAddDefaultTargetPasses(const Triple &TT) const;
+
+  /// Returns the mark-live pass to be used for this link. If no pass is
+  /// returned (the default) then the target-specific linker implementation will
+  /// choose a conservative default (usually marking all atoms live).
+  /// This function is only called if shouldAddDefaultTargetPasses returns true,
+  /// otherwise the JITContext is responsible for adding a mark-live pass in
+  /// modifyPassConfig.
+  virtual AtomGraphPassFunction getMarkLivePass(const Triple &TT) const;
+
+  /// Called by JITLink to modify the pass pipeline prior to linking.
+  /// The default version performs no modification.
+  virtual Error modifyPassConfig(const Triple &TT, PassConfiguration &Config);
+};
+
+/// Marks all atoms in a graph live. This can be used as a default, conservative
+/// mark-live implementation.
+Error markAllAtomsLive(AtomGraph &G);
+
+/// Basic JITLink implementation.
+///
+/// This function will use sensible defaults for GOT and Stub handling.
+void jitLink(std::unique_ptr<JITLinkContext> Ctx);
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
new file mode 100644
index 0000000..9d0b37f
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
@@ -0,0 +1,99 @@
+//===-- JITLinkMemoryManager.h - JITLink mem manager interface --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains the JITLinkMemoryManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Memory.h"
+#include <cstdint>
+
+namespace llvm {
+namespace jitlink {
+
+/// Manages allocations of JIT memory.
+///
+/// Instances of this class may be accessed concurrently from multiple threads
+/// and their implemetations should include any necessary synchronization.
+class JITLinkMemoryManager {
+public:
+  using ProtectionFlags = sys::Memory::ProtectionFlags;
+
+  class SegmentRequest {
+  public:
+    SegmentRequest() = default;
+    SegmentRequest(size_t ContentSize, unsigned ContentAlign,
+                   uint64_t ZeroFillSize, unsigned ZeroFillAlign)
+        : ContentSize(ContentSize), ZeroFillSize(ZeroFillSize),
+          ContentAlign(ContentAlign), ZeroFillAlign(ZeroFillAlign) {}
+    size_t getContentSize() const { return ContentSize; }
+    unsigned getContentAlignment() const { return ContentAlign; }
+    uint64_t getZeroFillSize() const { return ZeroFillSize; }
+    unsigned getZeroFillAlignment() const { return ZeroFillAlign; }
+
+  private:
+    size_t ContentSize = 0;
+    uint64_t ZeroFillSize = 0;
+    unsigned ContentAlign = 0;
+    unsigned ZeroFillAlign = 0;
+  };
+
+  using SegmentsRequestMap = DenseMap<unsigned, SegmentRequest>;
+
+  /// Represents an allocation created by the memory manager.
+  ///
+  /// An allocation object is responsible for allocating and owning jit-linker
+  /// working and target memory, and for transfering from working to target
+  /// memory.
+  ///
+  class Allocation {
+  public:
+    using FinalizeContinuation = std::function<void(Error)>;
+
+    virtual ~Allocation();
+
+    /// Should return the address of linker working memory for the segment with
+    /// the given protection flags.
+    virtual MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) = 0;
+
+    /// Should return the final address in the target process where the segment
+    /// will reside.
+    virtual JITTargetAddress getTargetMemory(ProtectionFlags Seg) = 0;
+
+    /// Should transfer from working memory to target memory, and release
+    /// working memory.
+    virtual void finalizeAsync(FinalizeContinuation OnFinalize) = 0;
+
+    /// Should deallocate target memory.
+    virtual Error deallocate() = 0;
+  };
+
+  virtual ~JITLinkMemoryManager();
+
+  /// Create an Allocation object.
+  virtual Expected<std::unique_ptr<Allocation>>
+  allocate(const SegmentsRequestMap &Request) = 0;
+};
+
+/// A JITLinkMemoryManager that allocates in-process memory.
+class InProcessMemoryManager : public JITLinkMemoryManager {
+public:
+  Expected<std::unique_ptr<Allocation>>
+  allocate(const SegmentsRequestMap &Request) override;
+};
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_JITLINK_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO.h
new file mode 100644
index 0000000..7facb65
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO.h
@@ -0,0 +1,30 @@
+//===------- MachO.h - Generic JIT link function for MachO ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic jit-link functions for MachO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_MACHO_H
+#define LLVM_EXECUTIONENGINE_JITLINK_MACHO_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+
+namespace llvm {
+namespace jitlink {
+
+/// jit-link the given ObjBuffer, which must be a MachO object file.
+///
+/// Uses conservative defaults for GOT and stub handling based on the target
+/// platform.
+void jitLink_MachO(std::unique_ptr<JITLinkContext> Ctx);
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_MACHO_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
new file mode 100644
index 0000000..1d5b586
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
@@ -0,0 +1,63 @@
+//===--- MachO_x86_64.h - JIT link functions for MachO/x86-64 ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// jit-link functions for MachO/x86-64.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_MACHO_X86_64_H
+#define LLVM_EXECUTIONENGINE_JITLINK_MACHO_X86_64_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+
+namespace llvm {
+namespace jitlink {
+
+namespace MachO_x86_64_Edges {
+
+enum MachOX86RelocationKind : Edge::Kind {
+  Branch32 = Edge::FirstRelocation,
+  Pointer64,
+  Pointer64Anon,
+  PCRel32,
+  PCRel32Minus1,
+  PCRel32Minus2,
+  PCRel32Minus4,
+  PCRel32Anon,
+  PCRel32Minus1Anon,
+  PCRel32Minus2Anon,
+  PCRel32Minus4Anon,
+  PCRel32GOTLoad,
+  PCRel32GOT,
+  PCRel32TLV,
+  Delta32,
+  Delta64,
+  NegDelta32,
+  NegDelta64,
+};
+
+} // namespace MachO_x86_64_Edges
+
+/// jit-link the given object buffer, which must be a MachO x86-64 object file.
+///
+/// If PrePrunePasses is empty then a default mark-live pass will be inserted
+/// that will mark all exported atoms live. If PrePrunePasses is not empty, the
+/// caller is responsible for including a pass to mark atoms as live.
+///
+/// If PostPrunePasses is empty then a default GOT-and-stubs insertion pass will
+/// be inserted. If PostPrunePasses is not empty then the caller is responsible
+/// for including a pass to insert GOT and stub edges.
+void jitLink_MachO_x86_64(std::unique_ptr<JITLinkContext> Ctx);
+
+/// Return the string name of the given MachO x86-64 edge kind.
+StringRef getMachOX86RelocationKindName(Edge::Kind R);
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_MACHO_X86_64_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/JITSymbol.h b/linux-x64/clang/include/llvm/ExecutionEngine/JITSymbol.h
index da1352f..b14154c 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/JITSymbol.h
@@ -55,7 +55,7 @@
 class JITSymbolFlags {
 public:
   using UnderlyingType = uint8_t;
-  using TargetFlagsType = uint64_t;
+  using TargetFlagsType = uint8_t;
 
   enum FlagNames : UnderlyingType {
     None = 0,
@@ -65,15 +65,9 @@
     Absolute = 1U << 3,
     Exported = 1U << 4,
     Callable = 1U << 5,
-    Lazy = 1U << 6,
-    Materializing = 1U << 7,
-    LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Materializing)
+    LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Callable)
   };
 
-  static JITSymbolFlags stripTransientFlags(JITSymbolFlags Orig) {
-    return static_cast<FlagNames>(Orig.Flags & ~Lazy & ~Materializing);
-  }
-
   /// Default-construct a JITSymbolFlags instance.
   JITSymbolFlags() = default;
 
@@ -83,7 +77,7 @@
   /// Construct a JITSymbolFlags instance from the given flags and target
   ///        flags.
   JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags)
-    : Flags(Flags), TargetFlags(TargetFlags) {}
+      : TargetFlags(TargetFlags), Flags(Flags) {}
 
   /// Implicitly convert to bool. Returs true if any flag is set.
   explicit operator bool() const { return Flags != None || TargetFlags != 0; }
@@ -110,19 +104,6 @@
     return (Flags & HasError) == HasError;
   }
 
-  /// Returns true if this is a lazy symbol.
-  ///        This flag is used internally by the JIT APIs to track
-  ///        materialization states.
-  bool isLazy() const { return Flags & Lazy; }
-
-  /// Returns true if this symbol is in the process of being
-  ///        materialized.
-  bool isMaterializing() const { return Flags & Materializing; }
-
-  /// Returns true if this symbol is fully materialized.
-  ///        (i.e. neither lazy, nor materializing).
-  bool isMaterialized() const { return !(Flags & (Lazy | Materializing)); }
-
   /// Returns true if the Weak flag is set.
   bool isWeak() const {
     return (Flags & Weak) == Weak;
@@ -167,8 +148,8 @@
   fromObjectSymbol(const object::SymbolRef &Symbol);
 
 private:
-  FlagNames Flags = None;
   TargetFlagsType TargetFlags = 0;
+  FlagNames Flags = None;
 };
 
 inline JITSymbolFlags operator&(const JITSymbolFlags &LHS,
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index 15a6566..1585925 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -13,25 +13,17 @@
 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
 #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
 
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ExecutionEngine/ObjectCache.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/SmallVectorMemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-#include <algorithm>
 #include <memory>
 
 namespace llvm {
 
+class JITTargetMachineBuilder;
 class MCContext;
+class MemoryBuffer;
 class Module;
+class ObjectCache;
+class TargetMachine;
 
 namespace orc {
 
@@ -50,51 +42,11 @@
   void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
 
   /// Compile a Module to an ObjectFile.
-  CompileResult operator()(Module &M) {
-    CompileResult CachedObject = tryToLoadFromObjectCache(M);
-    if (CachedObject)
-      return CachedObject;
-
-    SmallVector<char, 0> ObjBufferSV;
-
-    {
-      raw_svector_ostream ObjStream(ObjBufferSV);
-
-      legacy::PassManager PM;
-      MCContext *Ctx;
-      if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
-        llvm_unreachable("Target does not support MC emission.");
-      PM.run(M);
-    }
-
-    auto ObjBuffer =
-        llvm::make_unique<SmallVectorMemoryBuffer>(std::move(ObjBufferSV));
-    auto Obj =
-        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
-
-    if (Obj) {
-      notifyObjectCompiled(M, *ObjBuffer);
-      return std::move(ObjBuffer);
-    }
-
-    // TODO: Actually report errors helpfully.
-    consumeError(Obj.takeError());
-    return nullptr;
-  }
+  CompileResult operator()(Module &M);
 
 private:
-
-  CompileResult tryToLoadFromObjectCache(const Module &M) {
-    if (!ObjCache)
-      return CompileResult();
-
-    return ObjCache->getObject(&M);
-  }
-
-  void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
-    if (ObjCache)
-      ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
-  }
+  CompileResult tryToLoadFromObjectCache(const Module &M);
+  void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer);
 
   TargetMachine &TM;
   ObjectCache *ObjCache = nullptr;
@@ -107,16 +59,11 @@
 class ConcurrentIRCompiler {
 public:
   ConcurrentIRCompiler(JITTargetMachineBuilder JTMB,
-                       ObjectCache *ObjCache = nullptr)
-      : JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
+                       ObjectCache *ObjCache = nullptr);
 
   void setObjectCache(ObjectCache *ObjCache) { this->ObjCache = ObjCache; }
 
-  std::unique_ptr<MemoryBuffer> operator()(Module &M) {
-    auto TM = cantFail(JTMB.createTargetMachine());
-    SimpleCompiler C(*TM, ObjCache);
-    return C(M);
-  }
+  std::unique_ptr<MemoryBuffer> operator()(Module &M);
 
 private:
   JITTargetMachineBuilder JTMB;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
index 299247a..016fd82 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Core.h
@@ -33,6 +33,7 @@
 class MaterializationUnit;
 class MaterializationResponsibility;
 class JITDylib;
+enum class SymbolState : uint8_t;
 
 /// VModuleKey provides a unique identifier (allocated and managed by
 /// ExecutionSessions) for a module added to the JIT.
@@ -56,6 +57,18 @@
 /// A list of (JITDylib*, bool) pairs.
 using JITDylibSearchList = std::vector<std::pair<JITDylib *, bool>>;
 
+struct SymbolAliasMapEntry {
+  SymbolAliasMapEntry() = default;
+  SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
+      : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
+
+  SymbolStringPtr Aliasee;
+  JITSymbolFlags AliasFlags;
+};
+
+/// A map of Symbols to (Symbol, Flags) pairs.
+using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
+
 /// Render a SymbolStringPtr.
 raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
 
@@ -87,12 +100,15 @@
 /// Render a JITDylibSearchList.
 raw_ostream &operator<<(raw_ostream &OS, const JITDylibSearchList &JDs);
 
+/// Render a SymbolAliasMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
+
+/// Render a SymbolState.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
+
 /// Callback to notify client that symbols have been resolved.
 using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
 
-/// Callback to notify client that symbols are ready for execution.
-using SymbolsReadyCallback = std::function<void(Error)>;
-
 /// Callback to register the dependencies for a given query.
 using RegisterDependenciesFunction =
     std::function<void(const SymbolDependenceMap &)>;
@@ -174,7 +190,7 @@
   /// Note: The returned flags may have transient flags (Lazy, Materializing)
   /// set. These should be stripped with JITSymbolFlags::stripTransientFlags
   /// before using.
-  const SymbolFlagsMap &getSymbols() { return SymbolFlags; }
+  const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
 
   /// Returns the names of any symbols covered by this
   /// MaterializationResponsibility object that have queries pending. This
@@ -188,12 +204,12 @@
   /// symbols must be ones covered by this MaterializationResponsibility
   /// instance. Individual calls to this method may resolve a subset of the
   /// symbols, but all symbols must have been resolved prior to calling emit.
-  void resolve(const SymbolMap &Symbols);
+  void notifyResolved(const SymbolMap &Symbols);
 
   /// Notifies the target JITDylib (and any pending queries on that JITDylib)
   /// that all symbols covered by this MaterializationResponsibility instance
   /// have been emitted.
-  void emit();
+  void notifyEmitted();
 
   /// Adds new symbols to the JITDylib and this responsibility instance.
   ///        JITDylib entries start out in the materializing state.
@@ -333,18 +349,6 @@
       std::move(Symbols), std::move(K));
 }
 
-struct SymbolAliasMapEntry {
-  SymbolAliasMapEntry() = default;
-  SymbolAliasMapEntry(SymbolStringPtr Aliasee, JITSymbolFlags AliasFlags)
-      : Aliasee(std::move(Aliasee)), AliasFlags(AliasFlags) {}
-
-  SymbolStringPtr Aliasee;
-  JITSymbolFlags AliasFlags;
-};
-
-/// A map of Symbols to (Symbol, Flags) pairs.
-using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
-
 /// A materialization unit for symbol aliases. Allows existing symbols to be
 /// aliased with alternate flags.
 class ReExportsMaterializationUnit : public MaterializationUnit {
@@ -418,7 +422,7 @@
   ReexportsGenerator(JITDylib &SourceJD, bool MatchNonExported = false,
                      SymbolPredicate Allow = SymbolPredicate());
 
-  SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
+  Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
 
 private:
   JITDylib &SourceJD;
@@ -426,6 +430,15 @@
   SymbolPredicate Allow;
 };
 
+/// Represents the state that a symbol has reached during materialization.
+enum class SymbolState : uint8_t {
+  Invalid,       /// No symbol should be in this state.
+  NeverSearched, /// Added to the symbol table, never queried.
+  Materializing, /// Queried, materialization begun.
+  Resolved,      /// Assigned address, still materializing.
+  Ready = 0x3f   /// Ready and safe for clients to access.
+};
+
 /// A symbol query that returns results via a callback when results are
 ///        ready.
 ///
@@ -436,38 +449,30 @@
   friend class JITSymbolResolverAdapter;
 
 public:
-
-  /// Create a query for the given symbols, notify-resolved and
-  ///        notify-ready callbacks.
+  /// Create a query for the given symbols. The NotifyComplete
+  /// callback will be called once all queried symbols reach the given
+  /// minimum state.
   AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
-                          SymbolsResolvedCallback NotifySymbolsResolved,
-                          SymbolsReadyCallback NotifySymbolsReady);
+                          SymbolState RequiredState,
+                          SymbolsResolvedCallback NotifyComplete);
 
-  /// Set the resolved symbol information for the given symbol name.
-  void resolve(const SymbolStringPtr &Name, JITEvaluatedSymbol Sym);
+  /// Notify the query that a requested symbol has reached the required state.
+  void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
+                                    JITEvaluatedSymbol Sym);
 
   /// Returns true if all symbols covered by this query have been
   ///        resolved.
-  bool isFullyResolved() const { return NotYetResolvedCount == 0; }
+  bool isComplete() const { return OutstandingSymbolsCount == 0; }
 
-  /// Call the NotifySymbolsResolved callback.
+  /// Call the NotifyComplete callback.
   ///
-  /// This should only be called if all symbols covered by the query have been
-  /// resolved.
-  void handleFullyResolved();
-
-  /// Notify the query that a requested symbol is ready for execution.
-  void notifySymbolReady();
-
-  /// Returns true if all symbols covered by this query are ready.
-  bool isFullyReady() const { return NotYetReadyCount == 0; }
-
-  /// Calls the NotifySymbolsReady callback.
-  ///
-  /// This should only be called if all symbols covered by this query are ready.
-  void handleFullyReady();
+  /// This should only be called if all symbols covered by the query have
+  /// reached the specified state.
+  void handleComplete();
 
 private:
+  SymbolState getRequiredState() { return RequiredState; }
+
   void addQueryDependence(JITDylib &JD, SymbolStringPtr Name);
 
   void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
@@ -478,12 +483,11 @@
 
   void detach();
 
-  SymbolsResolvedCallback NotifySymbolsResolved;
-  SymbolsReadyCallback NotifySymbolsReady;
+  SymbolsResolvedCallback NotifyComplete;
   SymbolDependenceMap QueryRegistrations;
   SymbolMap ResolvedSymbols;
-  size_t NotYetResolvedCount;
-  size_t NotYetReadyCount;
+  size_t OutstandingSymbolsCount;
+  SymbolState RequiredState;
 };
 
 /// A symbol table that supports asynchoronous symbol queries.
@@ -497,7 +501,7 @@
   friend class ExecutionSession;
   friend class MaterializationResponsibility;
 public:
-  using GeneratorFunction = std::function<SymbolNameSet(
+  using GeneratorFunction = std::function<Expected<SymbolNameSet>(
       JITDylib &Parent, const SymbolNameSet &Names)>;
 
   using AsynchronousSymbolQuerySet =
@@ -595,7 +599,7 @@
 
   /// Search the given JITDylib for the symbols in Symbols. If found, store
   ///        the flags for each symbol in Flags. Returns any unresolved symbols.
-  SymbolFlagsMap lookupFlags(const SymbolNameSet &Names);
+  Expected<SymbolFlagsMap> lookupFlags(const SymbolNameSet &Names);
 
   /// Dump current JITDylib state to OS.
   void dump(raw_ostream &OS);
@@ -608,8 +612,8 @@
   /// and the query will not be applied. The Query is not failed and can be
   /// re-used in a subsequent lookup once the symbols have been added, or
   /// manually failed.
-  SymbolNameSet legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q,
-                             SymbolNameSet Names);
+  Expected<SymbolNameSet>
+  legacyLookup(std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Names);
 
 private:
   using AsynchronousSymbolQueryList =
@@ -626,40 +630,92 @@
       DenseMap<SymbolStringPtr, std::shared_ptr<UnmaterializedInfo>>;
 
   struct MaterializingInfo {
-    AsynchronousSymbolQueryList PendingQueries;
     SymbolDependenceMap Dependants;
     SymbolDependenceMap UnemittedDependencies;
     bool IsEmitted = false;
+
+    void addQuery(std::shared_ptr<AsynchronousSymbolQuery> Q);
+    void removeQuery(const AsynchronousSymbolQuery &Q);
+    AsynchronousSymbolQueryList takeQueriesMeeting(SymbolState RequiredState);
+    AsynchronousSymbolQueryList takeAllQueries();
+    bool hasQueriesPending() const { return !PendingQueries.empty(); }
+    const AsynchronousSymbolQueryList &pendingQueries() const {
+      return PendingQueries;
+    }
+
+  private:
+    AsynchronousSymbolQueryList PendingQueries;
   };
 
   using MaterializingInfosMap = DenseMap<SymbolStringPtr, MaterializingInfo>;
 
-  using LookupImplActionFlags = enum {
-    None = 0,
-    NotifyFullyResolved = 1 << 0U,
-    NotifyFullyReady = 1 << 1U,
-    LLVM_MARK_AS_BITMASK_ENUM(NotifyFullyReady)
+  class SymbolTableEntry {
+  public:
+    SymbolTableEntry() = default;
+    SymbolTableEntry(JITSymbolFlags Flags)
+        : Flags(Flags), State(static_cast<uint8_t>(SymbolState::NeverSearched)),
+          MaterializerAttached(false), PendingRemoval(false) {}
+
+    JITTargetAddress getAddress() const { return Addr; }
+    JITSymbolFlags getFlags() const { return Flags; }
+    SymbolState getState() const { return static_cast<SymbolState>(State); }
+
+    bool isInMaterializationPhase() const {
+      return getState() == SymbolState::Materializing ||
+             getState() == SymbolState::Resolved;
+    }
+
+    bool hasMaterializerAttached() const { return MaterializerAttached; }
+    bool isPendingRemoval() const { return PendingRemoval; }
+
+    void setAddress(JITTargetAddress Addr) { this->Addr = Addr; }
+    void setFlags(JITSymbolFlags Flags) { this->Flags = Flags; }
+    void setState(SymbolState State) {
+      assert(static_cast<uint8_t>(State) < (1 << 6) &&
+             "State does not fit in bitfield");
+      this->State = static_cast<uint8_t>(State);
+    }
+
+    void setMaterializerAttached(bool MaterializerAttached) {
+      this->MaterializerAttached = MaterializerAttached;
+    }
+
+    void setPendingRemoval(bool PendingRemoval) {
+      this->PendingRemoval = PendingRemoval;
+    }
+
+    JITEvaluatedSymbol getSymbol() const {
+      return JITEvaluatedSymbol(Addr, Flags);
+    }
+
+  private:
+    JITTargetAddress Addr = 0;
+    JITSymbolFlags Flags;
+    uint8_t State : 6;
+    uint8_t MaterializerAttached : 1;
+    uint8_t PendingRemoval : 1;
   };
 
+  using SymbolTable = DenseMap<SymbolStringPtr, SymbolTableEntry>;
+
   JITDylib(ExecutionSession &ES, std::string Name);
 
   Error defineImpl(MaterializationUnit &MU);
 
-  SymbolNameSet lookupFlagsImpl(SymbolFlagsMap &Flags,
-                                const SymbolNameSet &Names);
+  Expected<SymbolNameSet> lookupFlagsImpl(SymbolFlagsMap &Flags,
+                                          const SymbolNameSet &Names);
 
-  void lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
-                  SymbolNameSet &Unresolved, bool MatchNonExported,
-                  MaterializationUnitList &MUs);
+  Error lodgeQuery(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+                   SymbolNameSet &Unresolved, bool MatchNonExported,
+                   MaterializationUnitList &MUs);
 
   void lodgeQueryImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
                       SymbolNameSet &Unresolved, bool MatchNonExported,
                       MaterializationUnitList &MUs);
 
-  LookupImplActionFlags
-  lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
-             std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
-             SymbolNameSet &Unresolved);
+  bool lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
+                  std::vector<std::unique_ptr<MaterializationUnit>> &MUs,
+                  SymbolNameSet &Unresolved);
 
   void detachQueryHelper(AsynchronousSymbolQuery &Q,
                          const SymbolNameSet &QuerySymbols);
@@ -685,7 +741,7 @@
 
   ExecutionSession &ES;
   std::string JITDylibName;
-  SymbolMap Symbols;
+  SymbolTable Symbols;
   UnmaterializedInfosMap UnmaterializedInfos;
   MaterializingInfosMap MaterializingInfos;
   GeneratorFunction DefGenerator;
@@ -726,7 +782,15 @@
   /// the ExecutionSession.
   JITDylib &getMainJITDylib();
 
+  /// Return a pointer to the "name" JITDylib.
+  /// Ownership of JITDylib remains within Execution Session
+  JITDylib *getJITDylibByName(StringRef Name);
+
   /// Add a new JITDylib to this ExecutionSession.
+  ///
+  /// The JITDylib Name is required to be unique. Clients should verify that
+  /// names are not being re-used (e.g. by calling getJITDylibByName) if names
+  /// are based on user input.
   JITDylib &createJITDylib(std::string Name,
                            bool AddToMainDylibSearchOrder = true);
 
@@ -768,7 +832,7 @@
   /// Do not use -- this will be removed soon.
   Expected<SymbolMap>
   legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names,
-               bool WaiUntilReady,
+               SymbolState RequiredState,
                RegisterDependenciesFunction RegisterDependencies);
 
   /// Search the given JITDylib list for the given symbols.
@@ -778,11 +842,8 @@
   /// (hidden visibility) symbols in that dylib (true means match against
   /// non-exported symbols, false means do not match).
   ///
-  /// The OnResolve callback will be called once all requested symbols are
-  /// resolved, or if an error occurs prior to resolution.
-  ///
-  /// The OnReady callback will be called once all requested symbols are ready,
-  /// or if an error occurs after resolution but before all symbols are ready.
+  /// The NotifyComplete callback will be called once all requested symbols
+  /// reach the required state.
   ///
   /// If all symbols are found, the RegisterDependencies function will be called
   /// while the session lock is held. This gives clients a chance to register
@@ -794,7 +855,7 @@
   /// client to get an address to call) then the value NoDependenciesToRegister
   /// can be used.
   void lookup(const JITDylibSearchList &SearchOrder, SymbolNameSet Symbols,
-              SymbolsResolvedCallback OnResolve, SymbolsReadyCallback OnReady,
+              SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete,
               RegisterDependenciesFunction RegisterDependencies);
 
   /// Blocking version of lookup above. Returns the resolved symbol map.
@@ -806,9 +867,9 @@
   /// error will be reported via reportErrors.
   Expected<SymbolMap> lookup(const JITDylibSearchList &SearchOrder,
                              const SymbolNameSet &Symbols,
+                             SymbolState RequiredState = SymbolState::Ready,
                              RegisterDependenciesFunction RegisterDependencies =
-                                 NoDependenciesToRegister,
-                             bool WaitUntilReady = true);
+                                 NoDependenciesToRegister);
 
   /// Convenience version of blocking lookup.
   /// Searches each of the JITDylibs in the search order in turn for the given
@@ -831,10 +892,11 @@
   /// Materialize the given unit.
   void dispatchMaterialization(JITDylib &JD,
                                std::unique_ptr<MaterializationUnit> MU) {
-    LLVM_DEBUG(runSessionLocked([&]() {
-                 dbgs() << "Compiling, for " << JD.getName() << ", " << *MU
-                        << "\n";
-               }););
+    LLVM_DEBUG({
+      runSessionLocked([&]() {
+        dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n";
+      });
+    });
     DispatchMaterialization(JD, std::move(MU));
   }
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index 40dd415..ae3ab8c 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -217,28 +217,29 @@
 
   /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
   /// given sys::DynamicLibrary.
+  ///
   /// If the Allow predicate is given then only symbols matching the predicate
-  /// will be searched for in the DynamicLibrary. If the predicate is not given
-  /// then all symbols will be searched for.
-  DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, const DataLayout &DL,
+  /// will be searched for. If the predicate is not given then all symbols will
+  /// be searched for.
+  DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix,
                                 SymbolPredicate Allow = SymbolPredicate());
 
   /// Permanently loads the library at the given path and, on success, returns
   /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
   /// in the library. On failure returns the reason the library failed to load.
   static Expected<DynamicLibrarySearchGenerator>
-  Load(const char *FileName, const DataLayout &DL,
+  Load(const char *FileName, char GlobalPrefix,
        SymbolPredicate Allow = SymbolPredicate());
 
   /// Creates a DynamicLibrarySearchGenerator that searches for symbols in
   /// the current process.
   static Expected<DynamicLibrarySearchGenerator>
-  GetForCurrentProcess(const DataLayout &DL,
+  GetForCurrentProcess(char GlobalPrefix,
                        SymbolPredicate Allow = SymbolPredicate()) {
-    return Load(nullptr, DL, std::move(Allow));
+    return Load(nullptr, GlobalPrefix, std::move(Allow));
   }
 
-  SymbolNameSet operator()(JITDylib &JD, const SymbolNameSet &Names);
+  Expected<SymbolNameSet> operator()(JITDylib &JD, const SymbolNameSet &Names);
 
 private:
   sys::DynamicLibrary Dylib;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index 2ea9ac1..a7ed537 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -146,13 +146,13 @@
     std::error_code EC;
     auto TrampolineBlock =
         sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
-            sys::Process::getPageSize(), nullptr,
+            sys::Process::getPageSizeEstimate(), nullptr,
             sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
     if (EC)
       return errorCodeToError(EC);
 
     unsigned NumTrampolines =
-        (sys::Process::getPageSize() - ORCABI::PointerSize) /
+        (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) /
         ORCABI::TrampolineSize;
 
     uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
index b0ef20d..b54c7d8 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -20,35 +20,49 @@
 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
 #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
-#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
 #include "llvm/Support/ThreadPool.h"
 
 namespace llvm {
 namespace orc {
 
+class LLJITBuilderState;
+class LLLazyJITBuilderState;
+
 /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
+///
+/// Create instances using LLJITBuilder.
 class LLJIT {
+  template <typename, typename, typename> friend class LLJITBuilderSetters;
+
 public:
+  static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
 
   /// Destruct this instance. If a multi-threaded instance, waits for all
   /// compile threads to complete.
   ~LLJIT();
 
-  /// Create an LLJIT instance.
-  /// If NumCompileThreads is not equal to zero, creates a multi-threaded
-  /// LLJIT with the given number of compile threads.
-  static Expected<std::unique_ptr<LLJIT>>
-  Create(JITTargetMachineBuilder JTMB, DataLayout DL,
-         unsigned NumCompileThreads = 0);
-
   /// Returns the ExecutionSession for this instance.
   ExecutionSession &getExecutionSession() { return *ES; }
 
+  /// Returns a reference to the DataLayout for this instance.
+  const DataLayout &getDataLayout() const { return DL; }
+
   /// Returns a reference to the JITDylib representing the JIT'd main program.
   JITDylib &getMainJITDylib() { return Main; }
 
+  /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
+  /// that name exists.
+  JITDylib *getJITDylibByName(StringRef Name) {
+    return ES->getJITDylibByName(Name);
+  }
+
   /// Create a new JITDylib with the given name and return a reference to it.
+  ///
+  /// JITDylib names must be unique. If the given name is derived from user
+  /// input or elsewhere in the environment then the client should check
+  /// (e.g. by calling getJITDylibByName) that the given name is not already in
+  /// use.
   JITDylib &createJITDylib(std::string Name) {
     return ES->createJITDylib(std::move(Name));
   }
@@ -56,8 +70,6 @@
   /// Convenience method for defining an absolute symbol.
   Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
 
-  /// Convenience method for defining an
-
   /// Adds an IR module to the given JITDylib.
   Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
 
@@ -103,17 +115,14 @@
   Error runDestructors() { return DtorRunner.run(); }
 
   /// Returns a reference to the ObjLinkingLayer
-  RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; }
+  ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
 
 protected:
+  static std::unique_ptr<ObjectLayer>
+  createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
 
   /// Create an LLJIT instance with a single compile thread.
-  LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
-        DataLayout DL);
-
-  /// Create an LLJIT instance with multiple compile threads.
-  LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
-        DataLayout DL, unsigned NumCompileThreads);
+  LLJIT(LLJITBuilderState &S, Error &Err);
 
   std::string mangle(StringRef UnmangledName);
 
@@ -127,8 +136,8 @@
   DataLayout DL;
   std::unique_ptr<ThreadPool> CompileThreads;
 
-  RTDyldObjectLinkingLayer ObjLinkingLayer;
-  IRCompileLayer CompileLayer;
+  std::unique_ptr<ObjectLayer> ObjLinkingLayer;
+  std::unique_ptr<IRCompileLayer> CompileLayer;
 
   CtorDtorRunner CtorRunner, DtorRunner;
 };
@@ -136,25 +145,20 @@
 /// An extended version of LLJIT that supports lazy function-at-a-time
 /// compilation of LLVM IR.
 class LLLazyJIT : public LLJIT {
-public:
+  template <typename, typename, typename> friend class LLJITBuilderSetters;
 
-  /// Create an LLLazyJIT instance.
-  /// If NumCompileThreads is not equal to zero, creates a multi-threaded
-  /// LLLazyJIT with the given number of compile threads.
-  static Expected<std::unique_ptr<LLLazyJIT>>
-  Create(JITTargetMachineBuilder JTMB, DataLayout DL,
-         JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0);
+public:
 
   /// Set an IR transform (e.g. pass manager pipeline) to run on each function
   /// when it is compiled.
   void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
-    TransformLayer.setTransform(std::move(Transform));
+    TransformLayer->setTransform(std::move(Transform));
   }
 
   /// Sets the partition function.
   void
   setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
-    CODLayer.setPartitionFunction(std::move(Partition));
+    CODLayer->setPartitionFunction(std::move(Partition));
   }
 
   /// Add a module to be lazily compiled to JITDylib JD.
@@ -168,24 +172,144 @@
 private:
 
   // Create a single-threaded LLLazyJIT instance.
-  LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
-            std::unique_ptr<TargetMachine> TM, DataLayout DL,
-            std::unique_ptr<LazyCallThroughManager> LCTMgr,
-            std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
-
-  // Create a multi-threaded LLLazyJIT instance.
-  LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
-            DataLayout DL, unsigned NumCompileThreads,
-            std::unique_ptr<LazyCallThroughManager> LCTMgr,
-            std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
+  LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
 
   std::unique_ptr<LazyCallThroughManager> LCTMgr;
-  std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
-
-  IRTransformLayer TransformLayer;
-  CompileOnDemandLayer CODLayer;
+  std::unique_ptr<IRTransformLayer> TransformLayer;
+  std::unique_ptr<CompileOnDemandLayer> CODLayer;
 };
 
+class LLJITBuilderState {
+public:
+  using CreateObjectLinkingLayerFunction =
+      std::function<std::unique_ptr<ObjectLayer>(ExecutionSession &)>;
+
+  std::unique_ptr<ExecutionSession> ES;
+  Optional<JITTargetMachineBuilder> JTMB;
+  CreateObjectLinkingLayerFunction CreateObjectLinkingLayer;
+  unsigned NumCompileThreads = 0;
+
+  /// Called prior to JIT class construcion to fix up defaults.
+  Error prepareForConstruction();
+};
+
+template <typename JITType, typename SetterImpl, typename State>
+class LLJITBuilderSetters {
+public:
+  /// Set the JITTargetMachineBuilder for this instance.
+  ///
+  /// If this method is not called, JITTargetMachineBuilder::detectHost will be
+  /// used to construct a default target machine builder for the host platform.
+  SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
+    impl().JTMB = std::move(JTMB);
+    return impl();
+  }
+
+  /// Return a reference to the JITTargetMachineBuilder.
+  ///
+  Optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
+    return impl().JTMB;
+  }
+
+  /// Set an ObjectLinkingLayer creation function.
+  ///
+  /// If this method is not called, a default creation function will be used
+  /// that will construct an RTDyldObjectLinkingLayer.
+  SetterImpl &setCreateObjectLinkingLayer(
+      LLJITBuilderState::CreateObjectLinkingLayerFunction
+          CreateObjectLinkingLayer) {
+    impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
+    return impl();
+  }
+
+  /// Set the number of compile threads to use.
+  ///
+  /// If set to zero, compilation will be performed on the execution thread when
+  /// JITing in-process. If set to any other number N, a thread pool of N
+  /// threads will be created for compilation.
+  ///
+  /// If this method is not called, behavior will be as if it were called with
+  /// a zero argument.
+  SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
+    impl().NumCompileThreads = NumCompileThreads;
+    return impl();
+  }
+
+  /// Create an instance of the JIT.
+  Expected<std::unique_ptr<JITType>> create() {
+    if (auto Err = impl().prepareForConstruction())
+      return std::move(Err);
+
+    Error Err = Error::success();
+    std::unique_ptr<JITType> J(new JITType(impl(), Err));
+    if (Err)
+      return std::move(Err);
+    return std::move(J);
+  }
+
+protected:
+  SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
+};
+
+/// Constructs LLJIT instances.
+class LLJITBuilder
+    : public LLJITBuilderState,
+      public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
+
+class LLLazyJITBuilderState : public LLJITBuilderState {
+  friend class LLLazyJIT;
+
+public:
+  using IndirectStubsManagerBuilderFunction =
+      std::function<std::unique_ptr<IndirectStubsManager>()>;
+
+  Triple TT;
+  JITTargetAddress LazyCompileFailureAddr = 0;
+  std::unique_ptr<LazyCallThroughManager> LCTMgr;
+  IndirectStubsManagerBuilderFunction ISMBuilder;
+
+  Error prepareForConstruction();
+};
+
+template <typename JITType, typename SetterImpl, typename State>
+class LLLazyJITBuilderSetters
+    : public LLJITBuilderSetters<JITType, SetterImpl, State> {
+public:
+  /// Set the address in the target address to call if a lazy compile fails.
+  ///
+  /// If this method is not called then the value will default to 0.
+  SetterImpl &setLazyCompileFailureAddr(JITTargetAddress Addr) {
+    this->impl().LazyCompileFailureAddr = Addr;
+    return this->impl();
+  }
+
+  /// Set the lazy-callthrough manager.
+  ///
+  /// If this method is not called then a default, in-process lazy callthrough
+  /// manager for the host platform will be used.
+  SetterImpl &
+  setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
+    this->impl().LCTMgr = std::move(LCTMgr);
+    return this->impl();
+  }
+
+  /// Set the IndirectStubsManager builder function.
+  ///
+  /// If this method is not called then a default, in-process
+  /// IndirectStubsManager builder for the host platform will be used.
+  SetterImpl &setIndirectStubsManagerBuilder(
+      LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
+    this->impl().ISMBuilder = std::move(ISMBuilder);
+    return this->impl();
+  }
+};
+
+/// Constructs LLLazyJIT instances.
+class LLLazyJITBuilder
+    : public LLLazyJITBuilderState,
+      public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
+                                     LLLazyJITBuilderState> {};
+
 } // End namespace orc
 } // End namespace llvm
 
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index fdf64d0..e5c5feb 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -34,8 +34,8 @@
 
 /// Lazy-emitting IR layer.
 ///
-///   This layer accepts LLVM IR Modules (via addModule), but does not
-/// immediately emit them the layer below. Instead, emissing to the base layer
+///   This layer accepts LLVM IR Modules (via addModule) but does not
+/// immediately emit them the layer below. Instead, emission to the base layer
 /// is deferred until the first time the client requests the address (via
 /// JITSymbol::getAddress) for a symbol contained in this layer.
 template <typename BaseLayerT> class LazyEmittingLayer {
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
index e0e5526..f9cbbf6 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/Legacy.h
@@ -148,8 +148,8 @@
   for (auto &S : Symbols) {
     if (JITSymbol Sym = FindSymbol(*S)) {
       if (auto Addr = Sym.getAddress()) {
-        Query.resolve(S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
-        Query.notifySymbolReady();
+        Query.notifySymbolMetRequiredState(
+            S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
         NewSymbolsResolved = true;
       } else {
         ES.legacyFailQuery(Query, Addr.takeError());
@@ -162,11 +162,8 @@
       SymbolsNotFound.insert(S);
   }
 
-  if (NewSymbolsResolved && Query.isFullyResolved())
-    Query.handleFullyResolved();
-
-  if (NewSymbolsResolved && Query.isFullyReady())
-    Query.handleFullyReady();
+  if (NewSymbolsResolved && Query.isComplete())
+    Query.handleComplete();
 
   return SymbolsNotFound;
 }
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
new file mode 100644
index 0000000..c1e7d27
--- /dev/null
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -0,0 +1,165 @@
+//===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains the definition for an JITLink-based, in-process object linking
+// layer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+#define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Layer.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <list>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+namespace jitlink {
+class EHFrameRegistrar;
+} // namespace jitlink
+
+namespace object {
+class ObjectFile;
+} // namespace object
+
+namespace orc {
+
+class ObjectLinkingLayerJITLinkContext;
+
+/// An ObjectLayer implementation built on JITLink.
+///
+/// Clients can use this class to add relocatable object files to an
+/// ExecutionSession, and it typically serves as the base layer (underneath
+/// a compiling layer like IRCompileLayer) for the rest of the JIT.
+class ObjectLinkingLayer : public ObjectLayer {
+  friend class ObjectLinkingLayerJITLinkContext;
+
+public:
+  /// Plugin instances can be added to the ObjectLinkingLayer to receive
+  /// callbacks when code is loaded or emitted, and when JITLink is being
+  /// configured.
+  class Plugin {
+  public:
+    virtual ~Plugin();
+    virtual void modifyPassConfig(MaterializationResponsibility &MR,
+                                  const Triple &TT,
+                                  jitlink::PassConfiguration &Config) {}
+    virtual void notifyLoaded(MaterializationResponsibility &MR) {}
+    virtual Error notifyEmitted(MaterializationResponsibility &MR) {
+      return Error::success();
+    }
+    virtual Error notifyRemovingModule(VModuleKey K) {
+      return Error::success();
+    }
+    virtual Error notifyRemovingAllModules() { return Error::success(); }
+  };
+
+  /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
+  /// and NotifyEmitted functors.
+  ObjectLinkingLayer(ExecutionSession &ES,
+                     jitlink::JITLinkMemoryManager &MemMgr);
+
+  /// Destruct an ObjectLinkingLayer.
+  ~ObjectLinkingLayer();
+
+  /// Add a pass-config modifier.
+  ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
+    std::lock_guard<std::mutex> Lock(LayerMutex);
+    Plugins.push_back(std::move(P));
+    return *this;
+  }
+
+  /// Emit the object.
+  void emit(MaterializationResponsibility R,
+            std::unique_ptr<MemoryBuffer> O) override;
+
+  /// Instructs this ObjectLinkingLayer instance to override the symbol flags
+  /// found in the AtomGraph with the flags supplied by the
+  /// MaterializationResponsibility instance. This is a workaround to support
+  /// symbol visibility in COFF, which does not use the libObject's
+  /// SF_Exported flag. Use only when generating / adding COFF object files.
+  ///
+  /// FIXME: We should be able to remove this if/when COFF properly tracks
+  /// exported symbols.
+  ObjectLinkingLayer &
+  setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
+    this->OverrideObjectFlags = OverrideObjectFlags;
+    return *this;
+  }
+
+  /// If set, this ObjectLinkingLayer instance will claim responsibility
+  /// for any symbols provided by a given object file that were not already in
+  /// the MaterializationResponsibility instance. Setting this flag allows
+  /// higher-level program representations (e.g. LLVM IR) to be added based on
+  /// only a subset of the symbols they provide, without having to write
+  /// intervening layers to scan and add the additional symbols. This trades
+  /// diagnostic quality for convenience however: If all symbols are enumerated
+  /// up-front then clashes can be detected and reported early (and usually
+  /// deterministically). If this option is set, clashes for the additional
+  /// symbols may not be detected until late, and detection may depend on
+  /// the flow of control through JIT'd code. Use with care.
+  ObjectLinkingLayer &
+  setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
+    this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
+    return *this;
+  }
+
+private:
+  using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
+
+  void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+                        jitlink::PassConfiguration &PassConfig);
+  void notifyLoaded(MaterializationResponsibility &MR);
+  Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
+
+  Error removeModule(VModuleKey K);
+  Error removeAllModules();
+
+  mutable std::mutex LayerMutex;
+  jitlink::JITLinkMemoryManager &MemMgr;
+  bool OverrideObjectFlags = false;
+  bool AutoClaimObjectSymbols = false;
+  DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
+  std::vector<AllocPtr> UntrackedAllocs;
+  std::vector<std::unique_ptr<Plugin>> Plugins;
+};
+
+class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
+public:
+  EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
+  Error notifyEmitted(MaterializationResponsibility &MR) override;
+  void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+                        jitlink::PassConfiguration &PassConfig) override;
+  Error notifyRemovingModule(VModuleKey K) override;
+  Error notifyRemovingAllModules() override;
+
+private:
+  jitlink::EHFrameRegistrar &Registrar;
+  DenseMap<MaterializationResponsibility *, JITTargetAddress> InProcessLinks;
+  DenseMap<VModuleKey, JITTargetAddress> TrackedEHFrameAddrs;
+  std::vector<JITTargetAddress> UntrackedEHFrameAddrs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 9684481..4c8e2ea 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -299,13 +299,13 @@
     std::error_code EC;
     auto TrampolineBlock =
         sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
-            sys::Process::getPageSize(), nullptr,
+            sys::Process::getPageSizeEstimate(), nullptr,
             sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
     if (EC)
       return errorCodeToError(EC);
 
     uint32_t NumTrampolines =
-        (sys::Process::getPageSize() - TargetT::PointerSize) /
+        (sys::Process::getPageSizeEstimate() - TargetT::PointerSize) /
         TargetT::TrampolineSize;
 
     uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
@@ -335,7 +335,7 @@
   handleGetRemoteInfo() {
     std::string ProcessTriple = sys::getProcessTriple();
     uint32_t PointerSize = TargetT::PointerSize;
-    uint32_t PageSize = sys::Process::getPageSize();
+    uint32_t PageSize = sys::Process::getPageSizeEstimate();
     uint32_t TrampolineSize = TargetT::TrampolineSize;
     uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
     LLVM_DEBUG(dbgs() << "  Remote info:\n"
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index cd9ec36..479658b 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -43,22 +43,34 @@
                          const RuntimeDyld::LoadedObjectInfo &)>;
 
   /// Functor for receiving finalization notifications.
-  using NotifyEmittedFunction = std::function<void(VModuleKey)>;
+  using NotifyEmittedFunction =
+      std::function<void(VModuleKey, std::unique_ptr<MemoryBuffer>)>;
 
   using GetMemoryManagerFunction =
       std::function<std::unique_ptr<RuntimeDyld::MemoryManager>()>;
 
   /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
   ///        and NotifyEmitted functors.
-  RTDyldObjectLinkingLayer(
-      ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager,
-      NotifyLoadedFunction NotifyLoaded = NotifyLoadedFunction(),
-      NotifyEmittedFunction NotifyEmitted = NotifyEmittedFunction());
+  RTDyldObjectLinkingLayer(ExecutionSession &ES,
+                           GetMemoryManagerFunction GetMemoryManager);
 
   /// Emit the object.
   void emit(MaterializationResponsibility R,
             std::unique_ptr<MemoryBuffer> O) override;
 
+  /// Set the NotifyLoaded callback.
+  RTDyldObjectLinkingLayer &setNotifyLoaded(NotifyLoadedFunction NotifyLoaded) {
+    this->NotifyLoaded = std::move(NotifyLoaded);
+    return *this;
+  }
+
+  /// Set the NotifyEmitted callback.
+  RTDyldObjectLinkingLayer &
+  setNotifyEmitted(NotifyEmittedFunction NotifyEmitted) {
+    this->NotifyEmitted = std::move(NotifyEmitted);
+    return *this;
+  }
+
   /// Set the 'ProcessAllSections' flag.
   ///
   /// If set to true, all sections in each object file will be allocated using
@@ -108,7 +120,8 @@
                   std::map<StringRef, JITEvaluatedSymbol> Resolved,
                   std::set<StringRef> &InternalSymbols);
 
-  void onObjEmit(VModuleKey K, MaterializationResponsibility &R, Error Err);
+  void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
+                 MaterializationResponsibility &R, Error Err);
 
   mutable std::mutex RTDyldLayerMutex;
   GetMemoryManagerFunction GetMemoryManager;
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
index 39fa74b..c354f6c 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -50,25 +50,20 @@
 class SymbolStringPtr {
   friend class SymbolStringPool;
   friend struct DenseMapInfo<SymbolStringPtr>;
-  friend bool operator==(const SymbolStringPtr &LHS,
-                         const SymbolStringPtr &RHS);
-  friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
-
-  static SymbolStringPool::PoolMapEntry Tombstone;
 
 public:
   SymbolStringPtr() = default;
   SymbolStringPtr(const SymbolStringPtr &Other)
     : S(Other.S) {
-    if (S)
+    if (isRealPoolEntry(S))
       ++S->getValue();
   }
 
   SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
-    if (S)
+    if (isRealPoolEntry(S))
       --S->getValue();
     S = Other.S;
-    if (S)
+    if (isRealPoolEntry(S))
       ++S->getValue();
     return *this;
   }
@@ -78,7 +73,7 @@
   }
 
   SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
-    if (S)
+    if (isRealPoolEntry(S))
       --S->getValue();
     S = nullptr;
     std::swap(S, Other.S);
@@ -86,35 +81,65 @@
   }
 
   ~SymbolStringPtr() {
-    if (S)
+    if (isRealPoolEntry(S))
       --S->getValue();
   }
 
   StringRef operator*() const { return S->first(); }
 
+  friend bool operator==(const SymbolStringPtr &LHS,
+                         const SymbolStringPtr &RHS) {
+    return LHS.S == RHS.S;
+  }
+
+  friend bool operator!=(const SymbolStringPtr &LHS,
+                         const SymbolStringPtr &RHS) {
+    return !(LHS == RHS);
+  }
+
+  friend bool operator<(const SymbolStringPtr &LHS,
+                        const SymbolStringPtr &RHS) {
+    return LHS.S < RHS.S;
+  }
+
 private:
+  using PoolEntryPtr = SymbolStringPool::PoolMapEntry *;
 
   SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
       : S(S) {
-    if (S)
+    if (isRealPoolEntry(S))
       ++S->getValue();
   }
 
-  SymbolStringPool::PoolMapEntry *S = nullptr;
+  // Returns false for null, empty, and tombstone values, true otherwise.
+  bool isRealPoolEntry(PoolEntryPtr P) {
+    return ((reinterpret_cast<uintptr_t>(P) - 1) & InvalidPtrMask) !=
+           InvalidPtrMask;
+  }
+
+  static SymbolStringPtr getEmptyVal() {
+    return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(EmptyBitPattern));
+  }
+
+  static SymbolStringPtr getTombstoneVal() {
+    return SymbolStringPtr(reinterpret_cast<PoolEntryPtr>(TombstoneBitPattern));
+  }
+
+  constexpr static uintptr_t EmptyBitPattern =
+      std::numeric_limits<uintptr_t>::max()
+      << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+  constexpr static uintptr_t TombstoneBitPattern =
+      (std::numeric_limits<uintptr_t>::max() - 1)
+      << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+  constexpr static uintptr_t InvalidPtrMask =
+      (std::numeric_limits<uintptr_t>::max() - 3)
+      << PointerLikeTypeTraits<PoolEntryPtr>::NumLowBitsAvailable;
+
+  PoolEntryPtr S = nullptr;
 };
 
-inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
-  return LHS.S == RHS.S;
-}
-
-inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
-  return !(LHS == RHS);
-}
-
-inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
-  return LHS.S < RHS.S;
-}
-
 inline SymbolStringPool::~SymbolStringPool() {
 #ifndef NDEBUG
   clearDeadEntries();
@@ -150,16 +175,15 @@
 struct DenseMapInfo<orc::SymbolStringPtr> {
 
   static orc::SymbolStringPtr getEmptyKey() {
-    return orc::SymbolStringPtr();
+    return orc::SymbolStringPtr::getEmptyVal();
   }
 
   static orc::SymbolStringPtr getTombstoneKey() {
-    return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone);
+    return orc::SymbolStringPtr::getTombstoneVal();
   }
 
-  static unsigned getHashValue(orc::SymbolStringPtr V) {
-    uintptr_t IV = reinterpret_cast<uintptr_t>(V.S);
-    return unsigned(IV) ^ unsigned(IV >> 9);
+  static unsigned getHashValue(const orc::SymbolStringPtr &V) {
+    return DenseMapInfo<orc::SymbolStringPtr::PoolEntryPtr>::getHashValue(V.S);
   }
 
   static bool isEqual(const orc::SymbolStringPtr &LHS,
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyld.h b/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyld.h
index 2af9203..b2b4eba 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -52,18 +52,19 @@
   std::string ErrMsg;
 };
 
-class RuntimeDyldCheckerImpl;
 class RuntimeDyldImpl;
 
 class RuntimeDyld {
-  friend class RuntimeDyldCheckerImpl;
-
 protected:
   // Change the address associated with a section when resolving relocations.
   // Any relocations already associated with the symbol will be re-resolved.
   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
 
 public:
+  using NotifyStubEmittedFunction = std::function<void(
+      StringRef FileName, StringRef SectionName, StringRef SymbolName,
+      unsigned SectionID, uint32_t StubOffset)>;
+
   /// Information about the loaded object.
   class LoadedObjectInfo : public llvm::LoadedObjectInfo {
     friend class RuntimeDyldImpl;
@@ -184,6 +185,9 @@
   /// and resolve relocatons based on where they put it).
   void *getSymbolLocalAddress(StringRef Name) const;
 
+  /// Get the section ID for the section containing the given symbol.
+  unsigned getSymbolSectionID(StringRef Name) const;
+
   /// Get the target address and flags for the named symbol.
   /// This address is the one used for relocation.
   JITEvaluatedSymbol getSymbol(StringRef Name) const;
@@ -204,6 +208,19 @@
   /// This is the address which will be used for relocation resolution.
   void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
 
+  /// Returns the section's working memory.
+  StringRef getSectionContent(unsigned SectionID) const;
+
+  /// If the section was loaded, return the section's load address,
+  /// otherwise return None.
+  uint64_t getSectionLoadAddress(unsigned SectionID) const;
+
+  /// Set the NotifyStubEmitted callback. This is used for debugging
+  /// purposes. A callback is made for each stub that is generated.
+  void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted) {
+    this->NotifyStubEmitted = std::move(NotifyStubEmitted);
+  }
+
   /// Register any EH frame sections that have been loaded but not previously
   /// registered with the memory manager.  Note, RuntimeDyld is responsible
   /// for identifying the EH frame and calling the memory manager with the
@@ -265,7 +282,7 @@
   MemoryManager &MemMgr;
   JITSymbolResolver &Resolver;
   bool ProcessAllSections;
-  RuntimeDyldCheckerImpl *Checker;
+  NotifyStubEmittedFunction NotifyStubEmitted;
 };
 
 // Asynchronous JIT link for ORC.
diff --git a/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index ee925c2..93ea091 100644
--- a/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/linux-x64/clang/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -9,7 +9,10 @@
 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/Support/Endian.h"
 
 #include <cstdint>
 #include <memory>
@@ -57,7 +60,8 @@
 ///
 /// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')'
 ///            | 'next_pc'        '(' symbol ')'
-///            | 'stub_addr' '(' file-name ',' section-name ',' symbol ')'
+///            | 'stub_addr' '(' stub-container-name ',' symbol ')'
+///            | 'got_addr' '(' stub-container-name ',' symbol ')'
 ///            | symbol
 ///
 /// binary_expr = expr '+' expr
@@ -69,16 +73,85 @@
 ///
 class RuntimeDyldChecker {
 public:
-  RuntimeDyldChecker(RuntimeDyld &RTDyld, MCDisassembler *Disassembler,
-                     MCInstPrinter *InstPrinter, raw_ostream &ErrStream);
+  class MemoryRegionInfo {
+  public:
+    MemoryRegionInfo() = default;
+
+    /// Constructor for symbols/sections with content.
+    MemoryRegionInfo(StringRef Content, JITTargetAddress TargetAddress)
+        : ContentPtr(Content.data()), Size(Content.size()),
+          TargetAddress(TargetAddress) {}
+
+    /// Constructor for zero-fill symbols/sections.
+    MemoryRegionInfo(uint64_t Size, JITTargetAddress TargetAddress)
+        : Size(Size), TargetAddress(TargetAddress) {}
+
+    /// Returns true if this is a zero-fill symbol/section.
+    bool isZeroFill() const {
+      assert(Size && "setContent/setZeroFill must be called first");
+      return !ContentPtr;
+    }
+
+    /// Set the content for this memory region.
+    void setContent(StringRef Content) {
+      assert(!ContentPtr && !Size && "Content/zero-fill already set");
+      ContentPtr = Content.data();
+      Size = Content.size();
+    }
+
+    /// Set a zero-fill length for this memory region.
+    void setZeroFill(uint64_t Size) {
+      assert(!ContentPtr && !this->Size && "Content/zero-fill already set");
+      this->Size = Size;
+    }
+
+    /// Returns the content for this section if there is any.
+    StringRef getContent() const {
+      assert(!isZeroFill() && "Can't get content for a zero-fill section");
+      return StringRef(ContentPtr, static_cast<size_t>(Size));
+    }
+
+    /// Returns the zero-fill length for this section.
+    uint64_t getZeroFillLength() const {
+      assert(isZeroFill() && "Can't get zero-fill length for content section");
+      return Size;
+    }
+
+    /// Set the target address for this region.
+    void setTargetAddress(JITTargetAddress TargetAddress) {
+      assert(!this->TargetAddress && "TargetAddress already set");
+      this->TargetAddress = TargetAddress;
+    }
+
+    /// Return the target address for this region.
+    JITTargetAddress getTargetAddress() const { return TargetAddress; }
+
+  private:
+    const char *ContentPtr = 0;
+    uint64_t Size = 0;
+    JITTargetAddress TargetAddress = 0;
+  };
+
+  using IsSymbolValidFunction = std::function<bool(StringRef Symbol)>;
+  using GetSymbolInfoFunction =
+      std::function<Expected<MemoryRegionInfo>(StringRef SymbolName)>;
+  using GetSectionInfoFunction = std::function<Expected<MemoryRegionInfo>(
+      StringRef FileName, StringRef SectionName)>;
+  using GetStubInfoFunction = std::function<Expected<MemoryRegionInfo>(
+      StringRef StubContainer, StringRef TargetName)>;
+  using GetGOTInfoFunction = std::function<Expected<MemoryRegionInfo>(
+      StringRef GOTContainer, StringRef TargetName)>;
+
+  RuntimeDyldChecker(IsSymbolValidFunction IsSymbolValid,
+                     GetSymbolInfoFunction GetSymbolInfo,
+                     GetSectionInfoFunction GetSectionInfo,
+                     GetStubInfoFunction GetStubInfo,
+                     GetGOTInfoFunction GetGOTInfo,
+                     support::endianness Endianness,
+                     MCDisassembler *Disassembler, MCInstPrinter *InstPrinter,
+                     raw_ostream &ErrStream);
   ~RuntimeDyldChecker();
 
-  // Get the associated RTDyld instance.
-  RuntimeDyld& getRTDyld();
-
-  // Get the associated RTDyld instance.
-  const RuntimeDyld& getRTDyld() const;
-
   /// Check a single expression against the attached RuntimeDyld
   ///        instance.
   bool check(StringRef CheckExpr) const;
@@ -99,7 +172,7 @@
                                                   bool LocalAddress);
 
   /// If there is a section at the given local address, return its load
-  ///        address, otherwise return none.
+  /// address, otherwise return none.
   Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
 
 private: