Importing rustc-1.45.2

Change-Id: Idd187dd729f3089d9529753a17db5fbb40bacdeb
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
index 1610ca4..84d1cf9 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_library(LLVMDebugInfoCodeView
+add_llvm_component_library(LLVMDebugInfoCodeView
   AppendingTypeTableBuilder.cpp
   CodeViewError.cpp
   CodeViewRecordIO.cpp
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index ec4773d..dd6f75f 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -209,14 +209,6 @@
     }
   }
 
-  VisitHelper(TypeVisitorCallbackPipeline &Callbacks, VisitorDataSource Source)
-      : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
-    if (Source == VDS_BytesPresent) {
-      Pipeline = Callbacks;
-      Pipeline.addCallbackToPipelineFront(Deserializer);
-    }
-  }
-
   TypeDeserializer Deserializer;
   TypeVisitorCallbackPipeline Pipeline;
   CVTypeVisitor Visitor;
@@ -230,13 +222,6 @@
   return V.Visitor.visitTypeRecord(Record, Index);
 }
 
-Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
-                                      TypeVisitorCallbackPipeline &Callbacks,
-                                      VisitorDataSource Source) {
-  VisitHelper V(Callbacks, Source);
-  return V.Visitor.visitTypeRecord(Record, Index);
-}
-
 Error llvm::codeview::visitTypeRecord(CVType &Record,
                                       TypeVisitorCallbacks &Callbacks,
                                       VisitorDataSource Source) {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 2f49474..36a384b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -20,7 +20,6 @@
   Limit.MaxLength = MaxLength;
   Limit.BeginOffset = getCurrentOffset();
   Limits.push_back(Limit);
-  resetStreamedLen();
   return Error::success();
 }
 
@@ -50,6 +49,7 @@
       Streamer->EmitBytes(BytesSR);
       --PaddingBytes;
     }
+    resetStreamedLen();
   }
   return Error::success();
 }
@@ -126,7 +126,11 @@
 
 Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
   if (isStreaming()) {
-    emitComment(Comment);
+    std::string TypeNameStr = Streamer->getTypeName(TypeInd);
+    if (!TypeNameStr.empty())
+      emitComment(Comment + ": " + TypeNameStr);
+    else
+      emitComment(Comment);
     Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
     incrStreamedLen(sizeof(TypeInd.getIndex()));
   } else if (isWriting()) {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
index 54e68ae..82f6713 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -300,6 +300,128 @@
         CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
         CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
 
+static const EnumEntry<uint16_t> ClassOptionNames[] = {
+    CV_ENUM_CLASS_ENT(ClassOptions, Packed),
+    CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
+    CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
+    CV_ENUM_CLASS_ENT(ClassOptions, Nested),
+    CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
+    CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
+    CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
+    CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
+    CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
+    CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
+    CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
+    CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
+};
+
+static const EnumEntry<uint8_t> MemberAccessNames[] = {
+    CV_ENUM_CLASS_ENT(MemberAccess, None),
+    CV_ENUM_CLASS_ENT(MemberAccess, Private),
+    CV_ENUM_CLASS_ENT(MemberAccess, Protected),
+    CV_ENUM_CLASS_ENT(MemberAccess, Public),
+};
+
+static const EnumEntry<uint16_t> MethodOptionNames[] = {
+    CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
+    CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
+    CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
+    CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
+    CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
+};
+
+static const EnumEntry<uint16_t> MemberKindNames[] = {
+    CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
+    CV_ENUM_CLASS_ENT(MethodKind, Virtual),
+    CV_ENUM_CLASS_ENT(MethodKind, Static),
+    CV_ENUM_CLASS_ENT(MethodKind, Friend),
+    CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
+    CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
+    CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
+};
+
+static const EnumEntry<uint8_t> PtrKindNames[] = {
+    CV_ENUM_CLASS_ENT(PointerKind, Near16),
+    CV_ENUM_CLASS_ENT(PointerKind, Far16),
+    CV_ENUM_CLASS_ENT(PointerKind, Huge16),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
+    CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
+    CV_ENUM_CLASS_ENT(PointerKind, Near32),
+    CV_ENUM_CLASS_ENT(PointerKind, Far32),
+    CV_ENUM_CLASS_ENT(PointerKind, Near64),
+};
+
+static const EnumEntry<uint8_t> PtrModeNames[] = {
+    CV_ENUM_CLASS_ENT(PointerMode, Pointer),
+    CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
+    CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
+    CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
+    CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
+};
+
+static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceFunction),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+                      MultipleInheritanceFunction),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+                      VirtualInheritanceFunction),
+    CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
+};
+
+static const EnumEntry<uint16_t> TypeModifierNames[] = {
+    CV_ENUM_CLASS_ENT(ModifierOptions, Const),
+    CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
+    CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
+};
+
+static const EnumEntry<uint8_t> CallingConventions[] = {
+    CV_ENUM_CLASS_ENT(CallingConvention, NearC),
+    CV_ENUM_CLASS_ENT(CallingConvention, FarC),
+    CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
+    CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
+    CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
+    CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
+    CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, Generic),
+    CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
+    CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
+    CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
+    CV_ENUM_CLASS_ENT(CallingConvention, Inline),
+    CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
+};
+
+static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
+    CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
+    CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
+    CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
+};
+
+static const EnumEntry<uint16_t> LabelTypeEnum[] = {
+    CV_ENUM_CLASS_ENT(LabelType, Near),
+    CV_ENUM_CLASS_ENT(LabelType, Far),
+};
+
 namespace llvm {
 namespace codeview {
 
@@ -379,5 +501,49 @@
   return makeArrayRef(ImageSectionCharacteristicNames);
 }
 
+ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
+  return makeArrayRef(ClassOptionNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
+  return makeArrayRef(MemberAccessNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() {
+  return makeArrayRef(MethodOptionNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() {
+  return makeArrayRef(MemberKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() {
+  return makeArrayRef(PtrKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() {
+  return makeArrayRef(PtrModeNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() {
+  return makeArrayRef(PtrMemberRepNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() {
+  return makeArrayRef(TypeModifierNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getCallingConventions() {
+  return makeArrayRef(CallingConventions);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() {
+  return makeArrayRef(FunctionOptionEnum);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() {
+  return makeArrayRef(LabelTypeEnum);
+}
+
 } // end namespace codeview
 } // end namespace llvm
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
index 4d7cd46..6924b0e 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
@@ -90,7 +90,9 @@
 TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash,
                                                   ArrayRef<uint8_t> &Record) {
   assert(Record.size() < UINT32_MAX && "Record too big");
-  assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!");
+  assert(Record.size() % 4 == 0 &&
+         "The type record size is not a multiple of 4 bytes which will cause "
+         "misalignment in the output TPI stream!");
 
   LocallyHashedType WeakHash{Hash, Record};
   auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex());
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 27cb7e3..45b6398 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -315,7 +315,7 @@
 
 Error CVSymbolDumperImpl::visitKnownRecord(
     CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
-  W.printNumber("Offset", DefRangeFramePointerRel.Offset);
+  W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
   printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
                               DefRangeFramePointerRel.getRelocationOffset());
   printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
index 51a5a9e..2562c63 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
@@ -14,7 +14,7 @@
 using namespace llvm;
 using namespace llvm::codeview;
 
-template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
+template <typename RecordT> static RecordT createRecord(const CVSymbol &sym) {
   RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
   cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
   return record;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 7088983..3b62793 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -229,7 +229,7 @@
 Error SymbolRecordMapping::visitKnownRecord(
     CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
 
-  error(IO.mapInteger(DefRangeFramePointerRel.Offset));
+  error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
   error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
   error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index 47928c2..1aded58 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -7,24 +7,125 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
 
+namespace {
+
 #define error(X)                                                               \
   if (auto EC = X)                                                             \
     return EC;
 
-namespace {
+static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
+#define CV_TYPE(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+
+static StringRef getLeafTypeName(TypeLeafKind LT) {
+  switch (LT) {
+#define TYPE_RECORD(ename, value, name)                                        \
+  case ename:                                                                  \
+    return #name;
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+  default:
+    break;
+  }
+  return "UnknownLeaf";
+}
+
+template <typename T>
+static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
+  return lhs.Name < rhs.Name;
+}
+
+template <typename T, typename TFlag>
+static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
+                                ArrayRef<EnumEntry<TFlag>> Flags) {
+  if (!IO.isStreaming())
+    return std::string("");
+  typedef EnumEntry<TFlag> FlagEntry;
+  typedef SmallVector<FlagEntry, 10> FlagVector;
+  FlagVector SetFlags;
+  for (const auto &Flag : Flags) {
+    if (Flag.Value == 0)
+      continue;
+    if ((Value & Flag.Value) == Flag.Value) {
+      SetFlags.push_back(Flag);
+    }
+  }
+
+  llvm::sort(SetFlags, &compEnumNames<TFlag>);
+
+  std::string FlagLabel;
+  bool FirstOcc = true;
+  for (const auto &Flag : SetFlags) {
+    if (FirstOcc)
+      FirstOcc = false;
+    else
+      FlagLabel += (" | ");
+
+    FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
+  }
+
+  if (!FlagLabel.empty()) {
+    std::string LabelWithBraces(" ( ");
+    LabelWithBraces += FlagLabel + " )";
+    return LabelWithBraces;
+  } else
+    return FlagLabel;
+}
+
+template <typename T, typename TEnum>
+static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
+                             ArrayRef<EnumEntry<TEnum>> EnumValues) {
+  if (!IO.isStreaming())
+    return "";
+  StringRef Name;
+  for (const auto &EnumItem : EnumValues) {
+    if (EnumItem.Value == Value) {
+      Name = EnumItem.Name;
+      break;
+    }
+  }
+
+  return Name;
+}
+
+static std::string getMemberAttributes(CodeViewRecordIO &IO,
+                                       MemberAccess Access, MethodKind Kind,
+                                       MethodOptions Options) {
+  if (!IO.isStreaming())
+    return "";
+  std::string AccessSpecifier =
+      getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames()));
+  std::string MemberAttrs(AccessSpecifier);
+  if (Kind != MethodKind::Vanilla) {
+    std::string MethodKind =
+        getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames()));
+    MemberAttrs += ", " + MethodKind;
+  }
+  if (Options != MethodOptions::None) {
+    std::string MethodOptions = getFlagNames(
+        IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
+    MemberAttrs += ", " + MethodOptions;
+  }
+  return MemberAttrs;
+}
+
 struct MapOneMethodRecord {
   explicit MapOneMethodRecord(bool IsFromOverloadList)
       : IsFromOverloadList(IsFromOverloadList) {}
 
   Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
-    error(IO.mapInteger(Method.Attrs.Attrs, "AccessSpecifier"));
+    std::string Attrs = getMemberAttributes(
+        IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
+    error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
     if (IsFromOverloadList) {
       uint16_t Padding = 0;
-      error(IO.mapInteger(Padding, "Padding"));
+      error(IO.mapInteger(Padding));
     }
     error(IO.mapInteger(Method.Type, "Type"));
     if (Method.isIntroducingVirtual()) {
@@ -41,7 +142,7 @@
 private:
   bool IsFromOverloadList;
 };
-}
+} // namespace
 
 static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
                                   StringRef &UniqueName, bool HasUniqueName) {
@@ -96,10 +197,22 @@
     MaxLen = MaxRecordLength - sizeof(RecordPrefix);
   error(IO.beginRecord(MaxLen));
   TypeKind = CVR.kind();
+
+  if (IO.isStreaming()) {
+    auto RecordKind = CVR.kind();
+    uint16_t RecordLen = CVR.length() - 2;
+    std::string RecordKindName =
+        getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames));
+    error(IO.mapInteger(RecordLen, "Record length"));
+    error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
+  }
   return Error::success();
 }
 
 Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
+  if (IO.isStreaming())
+    IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
+                      utohexstr(Index.getIndex()) + ")");
   return visitTypeBegin(CVR);
 }
 
@@ -121,11 +234,21 @@
   // followed by the subrecord, followed by a continuation, and that entire
   // sequence spaws `MaxRecordLength` bytes.  So the record's length is
   // calculated as follows.
+
   constexpr uint32_t ContinuationLength = 8;
   error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
                        ContinuationLength));
 
   MemberKind = Record.Kind;
+  if (IO.isStreaming()) {
+    std::string MemberKindName = getLeafTypeName(Record.Kind);
+    MemberKindName +=
+        " ( " +
+        (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
+            .str() +
+        " )";
+    error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
+  }
   return Error::success();
 }
 
@@ -144,16 +267,24 @@
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
+  std::string ModifierNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
+                   makeArrayRef(getTypeModifierNames()));
   error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
-  error(IO.mapEnum(Record.Modifiers, "Modifiers"));
+  error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
   return Error::success();
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                           ProcedureRecord &Record) {
+  std::string CallingConvName = getEnumName(
+      IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
+  std::string FuncOptionNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+                   makeArrayRef(getFunctionOptionEnum()));
   error(IO.mapInteger(Record.ReturnType, "ReturnType"));
-  error(IO.mapEnum(Record.CallConv, "CallingConvention"));
-  error(IO.mapEnum(Record.Options, "FunctionOptions"));
+  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
   error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
   error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
 
@@ -162,11 +293,16 @@
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                           MemberFunctionRecord &Record) {
+  std::string CallingConvName = getEnumName(
+      IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
+  std::string FuncOptionNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+                   makeArrayRef(getFunctionOptionEnum()));
   error(IO.mapInteger(Record.ReturnType, "ReturnType"));
   error(IO.mapInteger(Record.ClassType, "ClassType"));
   error(IO.mapInteger(Record.ThisType, "ThisType"));
-  error(IO.mapEnum(Record.CallConv, "CallingConvention"));
-  error(IO.mapEnum(Record.Options, "FunctionOptions"));
+  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
   error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
   error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
   error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
@@ -197,8 +333,40 @@
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
+
+  SmallString<128> Attr("Attrs: ");
+
+  if (IO.isStreaming()) {
+    std::string PtrType = getEnumName(IO, unsigned(Record.getPointerKind()),
+                                      makeArrayRef(getPtrKindNames()));
+    Attr += "[ Type: " + PtrType;
+
+    std::string PtrMode = getEnumName(IO, unsigned(Record.getMode()),
+                                      makeArrayRef(getPtrModeNames()));
+    Attr += ", Mode: " + PtrMode;
+
+    auto PtrSizeOf = Record.getSize();
+    Attr += ", SizeOf: " + itostr(PtrSizeOf);
+
+    if (Record.isFlat())
+      Attr += ", isFlat";
+    if (Record.isConst())
+      Attr += ", isConst";
+    if (Record.isVolatile())
+      Attr += ", isVolatile";
+    if (Record.isUnaligned())
+      Attr += ", isUnaligned";
+    if (Record.isRestrict())
+      Attr += ", isRestricted";
+    if (Record.isLValueReferenceThisPtr())
+      Attr += ", isThisPtr&";
+    if (Record.isRValueReferenceThisPtr())
+      Attr += ", isThisPtr&&";
+    Attr += " ]";
+  }
+
   error(IO.mapInteger(Record.ReferentType, "PointeeType"));
-  error(IO.mapInteger(Record.Attrs, "Attributes"));
+  error(IO.mapInteger(Record.Attrs, Attr));
 
   if (Record.isPointerToMember()) {
     if (IO.isReading())
@@ -206,7 +374,10 @@
 
     MemberPointerInfo &M = *Record.MemberInfo;
     error(IO.mapInteger(M.ContainingType, "ClassType"));
-    error(IO.mapEnum(M.Representation, "Representation"));
+    std::string PtrMemberGetRepresentation = getEnumName(
+        IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames()));
+    error(IO.mapEnum(M.Representation,
+                     "Representation: " + PtrMemberGetRepresentation));
   }
 
   return Error::success();
@@ -226,8 +397,11 @@
          (CVR.kind() == TypeLeafKind::LF_CLASS) ||
          (CVR.kind() == TypeLeafKind::LF_INTERFACE));
 
+  std::string PropertiesNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+                   makeArrayRef(getClassOptionNames()));
   error(IO.mapInteger(Record.MemberCount, "MemberCount"));
-  error(IO.mapEnum(Record.Options, "Properties"));
+  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.FieldList, "FieldList"));
   error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
   error(IO.mapInteger(Record.VTableShape, "VShape"));
@@ -239,8 +413,11 @@
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
+  std::string PropertiesNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+                   makeArrayRef(getClassOptionNames()));
   error(IO.mapInteger(Record.MemberCount, "MemberCount"));
-  error(IO.mapEnum(Record.Options, "Properties"));
+  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.FieldList, "FieldList"));
   error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
   error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
@@ -250,8 +427,11 @@
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
+  std::string PropertiesNames =
+      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+                   makeArrayRef(getClassOptionNames()));
   error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
-  error(IO.mapEnum(Record.Options, "Properties"));
+  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
   error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
   error(IO.mapInteger(Record.FieldList, "FieldListType"));
   error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
@@ -383,7 +563,11 @@
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                           FieldListRecord &Record) {
-  error(IO.mapByteVectorTail(Record.Data));
+  if (IO.isStreaming()) {
+    if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
+      return EC;
+  } else
+    error(IO.mapByteVectorTail(Record.Data));
 
   return Error::success();
 }
@@ -397,13 +581,17 @@
 }
 
 Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) {
-  error(IO.mapEnum(Record.Mode, "Mode"));
+  std::string ModeName =
+      getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum()));
+  error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
   return Error::success();
 }
 
 Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                           BaseClassRecord &Record) {
-  error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+  std::string Attrs = getMemberAttributes(
+      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
   error(IO.mapInteger(Record.Type, "BaseType"));
   error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
 
@@ -412,7 +600,9 @@
 
 Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                           EnumeratorRecord &Record) {
-  error(IO.mapInteger(Record.Attrs.Attrs));
+  std::string Attrs = getMemberAttributes(
+      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
 
   // FIXME: Handle full APInt such as __int128.
   error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
@@ -423,7 +613,9 @@
 
 Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                           DataMemberRecord &Record) {
-  error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+  std::string Attrs = getMemberAttributes(
+      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
   error(IO.mapInteger(Record.Type, "Type"));
   error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
   error(IO.mapStringZ(Record.Name, "Name"));
@@ -460,7 +652,9 @@
 Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                           StaticDataMemberRecord &Record) {
 
-  error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+  std::string Attrs = getMemberAttributes(
+      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
   error(IO.mapInteger(Record.Type, "Type"));
   error(IO.mapStringZ(Record.Name, "Name"));
 
@@ -470,7 +664,9 @@
 Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                           VirtualBaseClassRecord &Record) {
 
-  error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+  std::string Attrs = getMemberAttributes(
+      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
   error(IO.mapInteger(Record.BaseType, "BaseType"));
   error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
   error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
diff --git a/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index aba0e96..c233db5 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
 #include "llvm/Support/Error.h"
 
 using namespace llvm;
@@ -202,21 +203,6 @@
 
 const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
 
-static bool isIdRecord(TypeLeafKind K) {
-  switch (K) {
-  case TypeLeafKind::LF_FUNC_ID:
-  case TypeLeafKind::LF_MFUNC_ID:
-  case TypeLeafKind::LF_STRING_ID:
-  case TypeLeafKind::LF_SUBSTR_LIST:
-  case TypeLeafKind::LF_BUILDINFO:
-  case TypeLeafKind::LF_UDT_SRC_LINE:
-  case TypeLeafKind::LF_UDT_MOD_SRC_LINE:
-    return true;
-  default:
-    return false;
-  }
-}
-
 void TypeStreamMerger::addMapping(TypeIndex Idx) {
   if (!IsSecondPass) {
     assert(IndexMap.size() == slotForIndex(CurIndex) &&
@@ -374,16 +360,18 @@
         [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
       return remapIndices(Type, Storage);
     };
+    unsigned AlignedSize = alignTo(Type.RecordData.size(), 4);
+
     if (LLVM_LIKELY(UseGlobalHashes)) {
       GlobalTypeTableBuilder &Dest =
           isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
       GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
-      DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize);
+      DestIdx = Dest.insertRecordAs(H, AlignedSize, DoSerialize);
     } else {
       MergingTypeTableBuilder &Dest =
           isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
 
-      RemapStorage.resize(Type.RecordData.size());
+      RemapStorage.resize(AlignedSize);
       ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
       if (!Result.empty())
         DestIdx = Dest.insertRecordBytes(Result);
@@ -400,9 +388,15 @@
 ArrayRef<uint8_t>
 TypeStreamMerger::remapIndices(const CVType &OriginalType,
                                MutableArrayRef<uint8_t> Storage) {
+  unsigned Align = OriginalType.RecordData.size() & 3;
+  unsigned AlignedSize = alignTo(OriginalType.RecordData.size(), 4);
+  assert(Storage.size() == AlignedSize &&
+         "The storage buffer size is not a multiple of 4 bytes which will "
+         "cause misalignment in the output TPI stream!");
+
   SmallVector<TiReference, 4> Refs;
   discoverTypeIndices(OriginalType.RecordData, Refs);
-  if (Refs.empty())
+  if (Refs.empty() && Align == 0)
     return OriginalType.RecordData;
 
   ::memcpy(Storage.data(), OriginalType.RecordData.data(),
@@ -422,6 +416,16 @@
         return {};
     }
   }
+
+  if (Align > 0) {
+    RecordPrefix *StorageHeader =
+        reinterpret_cast<RecordPrefix *>(Storage.data());
+    StorageHeader->RecordLen += 4 - Align;
+
+    DestContent = Storage.data() + OriginalType.RecordData.size();
+    for (; Align < 4; ++Align)
+      *DestContent++ = LF_PAD4 - Align;
+  }
   return Storage;
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
index b4770e5..3fe9904 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_library(LLVMDebugInfoDWARF
+add_llvm_component_library(LLVMDebugInfoDWARF
   DWARFAbbreviationDeclaration.cpp
   DWARFAddressRange.cpp
   DWARFAcceleratorTable.cpp
@@ -22,6 +22,7 @@
   DWARFFormValue.cpp
   DWARFGdbIndex.cpp
   DWARFListTable.cpp
+  DWARFLocationExpression.cpp
   DWARFTypeUnit.cpp
   DWARFUnitIndex.cpp
   DWARFUnit.cpp
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index f4dd799..abbea3a 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -38,9 +38,9 @@
 
 bool
 DWARFAbbreviationDeclaration::extract(DataExtractor Data,
-                                      uint32_t* OffsetPtr) {
+                                      uint64_t* OffsetPtr) {
   clear();
-  const uint32_t Offset = *OffsetPtr;
+  const uint64_t Offset = *OffsetPtr;
   Code = Data.getULEB128(OffsetPtr);
   if (Code == 0) {
     return false;
@@ -148,7 +148,7 @@
 }
 
 Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
-    const uint32_t DIEOffset, const dwarf::Attribute Attr,
+    const uint64_t DIEOffset, const dwarf::Attribute Attr,
     const DWARFUnit &U) const {
   Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
   if (!MatchAttrIndex)
@@ -158,7 +158,7 @@
 
   // Add the byte size of ULEB that for the abbrev Code so we can start
   // skipping the attribute data.
-  uint32_t Offset = DIEOffset + CodeByteSize;
+  uint64_t Offset = DIEOffset + CodeByteSize;
   uint32_t AttrIndex = 0;
   for (const auto &Spec : AttributeSpecs) {
     if (*MatchAttrIndex == AttrIndex) {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 0721efb..575edba 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -42,7 +42,7 @@
 DWARFAcceleratorTable::~DWARFAcceleratorTable() = default;
 
 Error AppleAcceleratorTable::extract() {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
 
   // Check that we can at least read the header.
   if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
@@ -111,15 +111,15 @@
   return true;
 }
 
-std::pair<uint32_t, dwarf::Tag>
-AppleAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
-  uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
+std::pair<uint64_t, dwarf::Tag>
+AppleAcceleratorTable::readAtoms(uint64_t *HashDataOffset) {
+  uint64_t DieOffset = dwarf::DW_INVALID_OFFSET;
   dwarf::Tag DieTag = dwarf::DW_TAG_null;
   dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
 
   for (auto Atom : getAtomsDesc()) {
     DWARFFormValue FormValue(Atom.second);
-    FormValue.extractValue(AccelSection, &HashDataOffset, FormParams);
+    FormValue.extractValue(AccelSection, HashDataOffset, FormParams);
     switch (Atom.first) {
     case dwarf::DW_ATOM_die_offset:
       DieOffset = *FormValue.getAsUnsignedConstant();
@@ -163,19 +163,19 @@
 
 bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
                                      SmallVectorImpl<DWARFFormValue> &AtomForms,
-                                     uint32_t *DataOffset) const {
+                                     uint64_t *DataOffset) const {
   dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
-  uint32_t NameOffset = *DataOffset;
+  uint64_t NameOffset = *DataOffset;
   if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) {
     W.printString("Incorrectly terminated list.");
     return false;
   }
-  unsigned StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
+  uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
   if (!StringOffset)
     return false; // End of list
 
   DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str());
-  W.startLine() << format("String: 0x%08x", StringOffset);
+  W.startLine() << format("String: 0x%08" PRIx64, StringOffset);
   W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n";
 
   unsigned NumData = AccelSection.getU32(DataOffset);
@@ -223,9 +223,9 @@
   }
 
   // Now go through the actual tables and dump them.
-  uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
-  unsigned HashesBase = Offset + Hdr.BucketCount * 4;
-  unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4;
+  uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+  uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
+  uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
 
   for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
     unsigned Index = AccelSection.getU32(&Offset);
@@ -237,14 +237,14 @@
     }
 
     for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
-      unsigned HashOffset = HashesBase + HashIdx*4;
-      unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
+      uint64_t HashOffset = HashesBase + HashIdx*4;
+      uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
       uint32_t Hash = AccelSection.getU32(&HashOffset);
 
       if (Hash % Hdr.BucketCount != Bucket)
         break;
 
-      unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
+      uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
       ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str());
       if (!AccelSection.isValidOffset(DataOffset)) {
         W.printString("Invalid section offset");
@@ -265,7 +265,7 @@
 }
 
 void AppleAcceleratorTable::Entry::extract(
-    const AppleAcceleratorTable &AccelTable, uint32_t *Offset) {
+    const AppleAcceleratorTable &AccelTable, uint64_t *Offset) {
 
   dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0,
                                   dwarf::DwarfFormat::DWARF32};
@@ -277,7 +277,7 @@
 AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const {
   assert(HdrData && "Dereferencing end iterator?");
   assert(HdrData->Atoms.size() == Values.size());
-  for (const auto &Tuple : zip_first(HdrData->Atoms, Values)) {
+  for (auto Tuple : zip_first(HdrData->Atoms, Values)) {
     if (std::get<0>(Tuple).first == Atom)
       return std::get<1>(Tuple);
   }
@@ -302,7 +302,7 @@
 }
 
 AppleAcceleratorTable::ValueIterator::ValueIterator(
-    const AppleAcceleratorTable &AccelTable, unsigned Offset)
+    const AppleAcceleratorTable &AccelTable, uint64_t Offset)
     : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) {
   if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
     return;
@@ -333,25 +333,25 @@
   // Find the bucket.
   unsigned HashValue = djbHash(Key);
   unsigned Bucket = HashValue % Hdr.BucketCount;
-  unsigned BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
-  unsigned HashesBase = BucketBase + Hdr.BucketCount * 4;
-  unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4;
+  uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
+  uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
+  uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
 
-  unsigned BucketOffset = BucketBase + Bucket * 4;
+  uint64_t BucketOffset = BucketBase + Bucket * 4;
   unsigned Index = AccelSection.getU32(&BucketOffset);
 
   // Search through all hashes in the bucket.
   for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
-    unsigned HashOffset = HashesBase + HashIdx * 4;
-    unsigned OffsetsOffset = OffsetsBase + HashIdx * 4;
+    uint64_t HashOffset = HashesBase + HashIdx * 4;
+    uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
     uint32_t Hash = AccelSection.getU32(&HashOffset);
 
     if (Hash % Hdr.BucketCount != Bucket)
       // We are already in the next bucket.
       break;
 
-    unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
-    unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
+    uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
+    uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
     if (!StringOffset)
       break;
 
@@ -377,7 +377,7 @@
 }
 
 Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
-                                             uint32_t *Offset) {
+                                             uint64_t *Offset) {
   // Check that we can read the fixed-size part.
   if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1))
     return createStringError(errc::illegal_byte_sequence,
@@ -437,7 +437,7 @@
 }
 
 Expected<DWARFDebugNames::AttributeEncoding>
-DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) {
   if (*Offset >= EntriesBase) {
     return createStringError(errc::illegal_byte_sequence,
                              "Incorrectly terminated abbreviation table.");
@@ -449,7 +449,7 @@
 }
 
 Expected<std::vector<DWARFDebugNames::AttributeEncoding>>
-DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) {
   std::vector<AttributeEncoding> Result;
   for (;;) {
     auto AttrEncOr = extractAttributeEncoding(Offset);
@@ -463,7 +463,7 @@
 }
 
 Expected<DWARFDebugNames::Abbrev>
-DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) {
   if (*Offset >= EntriesBase) {
     return createStringError(errc::illegal_byte_sequence,
                              "Incorrectly terminated abbreviation table.");
@@ -482,7 +482,7 @@
 
 Error DWARFDebugNames::NameIndex::extract() {
   const DWARFDataExtractor &AS = Section.AccelSection;
-  uint32_t Offset = Base;
+  uint64_t Offset = Base;
   if (Error E = Hdr.extract(AS, &Offset))
     return E;
 
@@ -531,7 +531,7 @@
 Optional<DWARFFormValue>
 DWARFDebugNames::Entry::lookup(dwarf::Index Index) const {
   assert(Abbr->Attributes.size() == Values.size());
-  for (const auto &Tuple : zip_first(Abbr->Attributes, Values)) {
+  for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
     if (std::get<0>(Tuple).Index == Index)
       return std::get<1>(Tuple);
   }
@@ -565,7 +565,7 @@
   W.printHex("Abbrev", Abbr->Code);
   W.startLine() << formatv("Tag: {0}\n", Abbr->Tag);
   assert(Abbr->Attributes.size() == Values.size());
-  for (const auto &Tuple : zip_first(Abbr->Attributes, Values)) {
+  for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
     W.startLine() << formatv("{0}: ", std::get<0>(Tuple).Index);
     std::get<1>(Tuple).dump(W.getOStream());
     W.getOStream() << '\n';
@@ -577,27 +577,27 @@
   return inconvertibleErrorCode();
 }
 
-uint32_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
+uint64_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
   assert(CU < Hdr.CompUnitCount);
-  uint32_t Offset = CUsBase + 4 * CU;
+  uint64_t Offset = CUsBase + 4 * CU;
   return Section.AccelSection.getRelocatedValue(4, &Offset);
 }
 
-uint32_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
+uint64_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
   assert(TU < Hdr.LocalTypeUnitCount);
-  uint32_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU);
+  uint64_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU);
   return Section.AccelSection.getRelocatedValue(4, &Offset);
 }
 
 uint64_t DWARFDebugNames::NameIndex::getForeignTUSignature(uint32_t TU) const {
   assert(TU < Hdr.ForeignTypeUnitCount);
-  uint32_t Offset =
+  uint64_t Offset =
       CUsBase + 4 * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
   return Section.AccelSection.getU64(&Offset);
 }
 
 Expected<DWARFDebugNames::Entry>
-DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
+DWARFDebugNames::NameIndex::getEntry(uint64_t *Offset) const {
   const DWARFDataExtractor &AS = Section.AccelSection;
   if (!AS.isValidOffset(*Offset))
     return createStringError(errc::illegal_byte_sequence,
@@ -625,12 +625,12 @@
 DWARFDebugNames::NameTableEntry
 DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const {
   assert(0 < Index && Index <= Hdr.NameCount);
-  uint32_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1);
-  uint32_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1);
+  uint64_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1);
+  uint64_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1);
   const DWARFDataExtractor &AS = Section.AccelSection;
 
-  uint32_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset);
-  uint32_t EntryOffset = AS.getU32(&EntryOffsetOffset);
+  uint64_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset);
+  uint64_t EntryOffset = AS.getU32(&EntryOffsetOffset);
   EntryOffset += EntriesBase;
   return {Section.StringSection, Index, StringOffset, EntryOffset};
 }
@@ -638,13 +638,13 @@
 uint32_t
 DWARFDebugNames::NameIndex::getBucketArrayEntry(uint32_t Bucket) const {
   assert(Bucket < Hdr.BucketCount);
-  uint32_t BucketOffset = BucketsBase + 4 * Bucket;
+  uint64_t BucketOffset = BucketsBase + 4 * Bucket;
   return Section.AccelSection.getU32(&BucketOffset);
 }
 
 uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const {
   assert(0 < Index && Index <= Hdr.NameCount);
-  uint32_t HashOffset = HashesBase + 4 * (Index - 1);
+  uint64_t HashOffset = HashesBase + 4 * (Index - 1);
   return Section.AccelSection.getU32(&HashOffset);
 }
 
@@ -653,8 +653,8 @@
 // it's not possible to recover this entry list (but the other lists may still
 // parse OK).
 bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W,
-                                           uint32_t *Offset) const {
-  uint32_t EntryId = *Offset;
+                                           uint64_t *Offset) const {
+  uint64_t EntryId = *Offset;
   auto EntryOr = getEntry(Offset);
   if (!EntryOr) {
     handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {},
@@ -674,10 +674,10 @@
   if (Hash)
     W.printHex("Hash", *Hash);
 
-  W.startLine() << format("String: 0x%08x", NTE.getStringOffset());
+  W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset());
   W.getOStream() << " \"" << NTE.getString() << "\"\n";
 
-  uint32_t EntryOffset = NTE.getEntryOffset();
+  uint64_t EntryOffset = NTE.getEntryOffset();
   while (dumpEntry(W, &EntryOffset))
     /*empty*/;
 }
@@ -685,7 +685,7 @@
 void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const {
   ListScope CUScope(W, "Compilation Unit offsets");
   for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU)
-    W.startLine() << format("CU[%u]: 0x%08x\n", CU, getCUOffset(CU));
+    W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU));
 }
 
 void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
@@ -694,7 +694,8 @@
 
   ListScope TUScope(W, "Local Type Unit offsets");
   for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
-    W.startLine() << format("LocalTU[%u]: 0x%08x\n", TU, getLocalTUOffset(TU));
+    W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU,
+                            getLocalTUOffset(TU));
 }
 
 void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const {
@@ -756,7 +757,7 @@
 }
 
 Error DWARFDebugNames::extract() {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   while (AccelSection.isValidOffset(Offset)) {
     NameIndex Next(*this, Offset);
     if (Error E = Next.extract())
@@ -778,7 +779,7 @@
     NI.dump(W);
 }
 
-Optional<uint32_t>
+Optional<uint64_t>
 DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
   const Header &Hdr = CurrentIndex->Hdr;
   if (Hdr.BucketCount == 0) {
@@ -822,7 +823,7 @@
 }
 
 bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
-  Optional<uint32_t> Offset = findEntryOffsetInCurrentIndex();
+  Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex();
   if (!Offset)
     return false;
   DataOffset = *Offset;
@@ -877,7 +878,7 @@
 }
 
 const DWARFDebugNames::NameIndex *
-DWARFDebugNames::getCUNameIndex(uint32_t CUOffset) {
+DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) {
   if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
     for (const auto &NI : *this) {
       for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index ef6da08..ddf307d 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -7,19 +7,23 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
-
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
 void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
-                             DIDumpOptions DumpOpts) const {
+                             DIDumpOptions DumpOpts,
+                             const DWARFObject *Obj) const {
 
   OS << (DumpOpts.DisplayRawContents ? " " : "[");
   OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
      << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC);
   OS << (DumpOpts.DisplayRawContents ? "" : ")");
+
+  if (Obj)
+    DWARFFormValue::dumpAddressSection(*Obj, OS, DumpOpts, SectionIndex);
 }
 
 raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 74cce42..f59e492 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -15,16 +15,18 @@
 using namespace llvm;
 
 void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
-  OS << format("0x%08x", getOffset()) << ": Compile Unit:"
-     << " length = " << format("0x%08x", getLength())
+  OS << format("0x%08" PRIx64, getOffset()) << ": Compile Unit:"
+     << " length = " << format("0x%08" PRIx64, getLength())
      << " version = " << format("0x%04x", getVersion());
   if (getVersion() >= 5)
     OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
-  OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
+  OS << " abbr_offset = "
+     << format("0x%04" PRIx64, getAbbreviations()->getOffset())
      << " addr_size = " << format("0x%02x", getAddressByteSize());
   if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
     OS << " DWO_id = " << format("0x%016" PRIx64, *getDWOId());
-  OS << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
+  OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+     << ")\n";
 
   if (DWARFDie CUDie = getUnitDIE(false))
     CUDie.dump(OS, 0, DumpOpts);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 5ede9bf..aaa6d52 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -138,7 +138,7 @@
   DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
   DataExtractor StrData(StringSection, LittleEndian, 0);
   uint64_t SectionSize = StringOffsetsSection.Data.size();
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   for (auto &Contribution : Contributions) {
     // Report an ill-formed contribution.
     if (!Contribution) {
@@ -166,10 +166,10 @@
     }
     // Report a gap in the table.
     if (Offset < ContributionHeader) {
-      OS << format("0x%8.8x: Gap, length = ", Offset);
+      OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
       OS << (ContributionHeader - Offset) << "\n";
     }
-    OS << format("0x%8.8x: ", (uint32_t)ContributionHeader);
+    OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
     // In DWARF v5 the contribution size in the descriptor does not equal
     // the originally encoded length (it does not contain the length of the
     // version field and the padding, a total of 4 bytes). Add them back in
@@ -181,26 +181,19 @@
     Offset = Contribution->Base;
     unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
     while (Offset - Contribution->Base < Contribution->Size) {
-      OS << format("0x%8.8x: ", Offset);
-      // FIXME: We can only extract strings if the offset fits in 32 bits.
+      OS << format("0x%8.8" PRIx64 ": ", Offset);
       uint64_t StringOffset =
           StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
-      // Extract the string if we can and display it. Otherwise just report
-      // the offset.
-      if (StringOffset <= std::numeric_limits<uint32_t>::max()) {
-        uint32_t StringOffset32 = (uint32_t)StringOffset;
-        OS << format("%8.8x ", StringOffset32);
-        const char *S = StrData.getCStr(&StringOffset32);
-        if (S)
-          OS << format("\"%s\"", S);
-      } else
-        OS << format("%16.16" PRIx64 " ", StringOffset);
+      OS << format("%8.8" PRIx64 " ", StringOffset);
+      const char *S = StrData.getCStr(&StringOffset);
+      if (S)
+        OS << format("\"%s\"", S);
       OS << "\n";
     }
   }
   // Report a gap at the end of the table.
   if (Offset < SectionSize) {
-    OS << format("0x%8.8x: Gap, length = ", Offset);
+    OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
     OS << (SectionSize - Offset) << "\n";
   }
 }
@@ -225,7 +218,7 @@
                                     StringSection, Units, LittleEndian);
   else {
     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
-    uint32_t offset = 0;
+    uint64_t offset = 0;
     uint64_t size = StringOffsetsSection.Data.size();
     // Ensure that size is a multiple of the size of an entry.
     if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
@@ -235,9 +228,9 @@
     }
     DataExtractor StrData(StringSection, LittleEndian, 0);
     while (offset < size) {
-      OS << format("0x%8.8x: ", offset);
-      uint32_t StringOffset = strOffsetExt.getU32(&offset);
-      OS << format("%8.8x  ", StringOffset);
+      OS << format("0x%8.8" PRIx64 ": ", offset);
+      uint64_t StringOffset = strOffsetExt.getU32(&offset);
+      OS << format("%8.8" PRIx64 "  ", StringOffset);
       const char *S = StrData.getCStr(&StringOffset);
       if (S)
         OS << format("\"%s\"", S);
@@ -250,10 +243,10 @@
 static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
                             DIDumpOptions DumpOpts, uint16_t Version,
                             uint8_t AddrSize) {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   while (AddrData.isValidOffset(Offset)) {
     DWARFDebugAddrTable AddrTable;
-    uint32_t TableOffset = Offset;
+    uint64_t TableOffset = Offset;
     if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
                                       DWARFContext::dumpWarning)) {
       WithColor::error() << toString(std::move(Err)) << '\n';
@@ -261,8 +254,7 @@
       // could be read. If it couldn't, stop reading the section.
       if (!AddrTable.hasValidLength())
         break;
-      uint64_t Length = AddrTable.getLength();
-      Offset = TableOffset + Length;
+      Offset = TableOffset + AddrTable.getLength();
     } else {
       AddrTable.dump(OS, DumpOpts);
     }
@@ -275,10 +267,10 @@
     llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
         LookupPooledAddress,
     DIDumpOptions DumpOpts) {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   while (rnglistData.isValidOffset(Offset)) {
     llvm::DWARFDebugRnglistTable Rnglists;
-    uint32_t TableOffset = Offset;
+    uint64_t TableOffset = Offset;
     if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
       WithColor::error() << toString(std::move(Err)) << '\n';
       uint64_t Length = Rnglists.length();
@@ -296,22 +288,35 @@
 static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
                                 DWARFDataExtractor Data,
                                 const MCRegisterInfo *MRI,
+                                const DWARFObject &Obj,
                                 Optional<uint64_t> DumpOffset) {
-  uint32_t Offset = 0;
-  DWARFDebugLoclists Loclists;
+  uint64_t Offset = 0;
 
-  DWARFListTableHeader Header(".debug_loclists", "locations");
-  if (Error E = Header.extract(Data, &Offset)) {
-    WithColor::error() << toString(std::move(E)) << '\n';
-    return;
+  while (Data.isValidOffset(Offset)) {
+    DWARFListTableHeader Header(".debug_loclists", "locations");
+    if (Error E = Header.extract(Data, &Offset)) {
+      WithColor::error() << toString(std::move(E)) << '\n';
+      return;
+    }
+
+    Header.dump(OS, DumpOpts);
+
+    uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
+    Data.setAddressSize(Header.getAddrSize());
+    DWARFDebugLoclists Loc(Data, Header.getVersion());
+    if (DumpOffset) {
+      if (DumpOffset >= Offset && DumpOffset < EndOffset) {
+        Offset = *DumpOffset;
+        Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr,
+                             DumpOpts, /*Indent=*/0);
+        OS << "\n";
+        return;
+      }
+    } else {
+      Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts);
+    }
+    Offset = EndOffset;
   }
-
-  Header.dump(OS, DumpOpts);
-  DataExtractor LocData(Data.getData().drop_front(Offset),
-                        Data.isLittleEndian(), Header.getAddrSize());
-
-  Loclists.parse(LocData, Header.getVersion());
-  Loclists.dump(OS, 0, MRI, DumpOffset);
 }
 
 void DWARFContext::dump(
@@ -384,42 +389,69 @@
       dumpDebugType(".debug_types.dwo", dwo_types_section_units());
   }
 
+  DIDumpOptions LLDumpOpts = DumpOpts;
+  if (LLDumpOpts.Verbose)
+    LLDumpOpts.DisplayRawContents = true;
+
   if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
                                    DObj->getLocSection().Data)) {
-    getDebugLoc()->dump(OS, getRegisterInfo(), *Off);
+    getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off);
   }
   if (const auto *Off =
           shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
                      DObj->getLoclistsSection().Data)) {
     DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
                             0);
-    dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off);
+    dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
   }
   if (const auto *Off =
+          shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
+                     DObj->getLoclistsDWOSection().Data)) {
+    DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
+                            isLittleEndian(), 0);
+    dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
+  }
+
+  if (const auto *Off =
           shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
                      DObj->getLocDWOSection().Data)) {
-    getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off);
+    DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
+                            4);
+    DWARFDebugLoclists Loc(Data, /*Version=*/4);
+    if (*Off) {
+      uint64_t Offset = **Off;
+      Loc.dumpLocationList(&Offset, OS,
+                           /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr,
+                           LLDumpOpts, /*Indent=*/0);
+      OS << "\n";
+    } else {
+      Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj,
+                    LLDumpOpts);
+    }
   }
 
   if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
-                                   DObj->getDebugFrameSection()))
+                                   DObj->getFrameSection().Data))
     getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
 
   if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
-                                   DObj->getEHFrameSection()))
+                                   DObj->getEHFrameSection().Data))
     getEHFrame()->dump(OS, getRegisterInfo(), *Off);
 
   if (DumpType & DIDT_DebugMacro) {
     if (Explicit || !getDebugMacro()->empty()) {
       OS << "\n.debug_macinfo contents:\n";
       getDebugMacro()->dump(OS);
+    } else if (ExplicitDWO || !getDebugMacroDWO()->empty()) {
+      OS << "\n.debug_macinfo.dwo contents:\n";
+      getDebugMacroDWO()->dump(OS);
     }
   }
 
   if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
-                 DObj->getARangeSection())) {
-    uint32_t offset = 0;
-    DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
+                 DObj->getArangesSection())) {
+    uint64_t offset = 0;
+    DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0);
     DWARFDebugArangeSet set;
     while (set.extract(arangesData, &offset))
       set.dump(OS);
@@ -433,7 +465,8 @@
         Parser.skip(dumpWarning);
         continue;
       }
-      OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
+      OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
+         << "]\n";
       if (DumpOpts.Verbose) {
         Parser.parseNext(dumpWarning, dumpWarning, &OS);
       } else {
@@ -474,32 +507,32 @@
   }
 
   if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
-                 DObj->getStringSection())) {
-    DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
-    uint32_t offset = 0;
-    uint32_t strOffset = 0;
+                 DObj->getStrSection())) {
+    DataExtractor strData(DObj->getStrSection(), isLittleEndian(), 0);
+    uint64_t offset = 0;
+    uint64_t strOffset = 0;
     while (const char *s = strData.getCStr(&offset)) {
-      OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
+      OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strOffset, s);
       strOffset = offset;
     }
   }
   if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
-                 DObj->getStringDWOSection())) {
-    DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
-    uint32_t offset = 0;
-    uint32_t strDWOOffset = 0;
+                 DObj->getStrDWOSection())) {
+    DataExtractor strDWOData(DObj->getStrDWOSection(), isLittleEndian(), 0);
+    uint64_t offset = 0;
+    uint64_t strDWOOffset = 0;
     while (const char *s = strDWOData.getCStr(&offset)) {
-      OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
+      OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strDWOOffset, s);
       strDWOOffset = offset;
     }
   }
   if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
-                 DObj->getLineStringSection())) {
-    DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
-    uint32_t offset = 0;
-    uint32_t strOffset = 0;
+                 DObj->getLineStrSection())) {
+    DataExtractor strData(DObj->getLineStrSection(), isLittleEndian(), 0);
+    uint64_t offset = 0;
+    uint64_t strOffset = 0;
     while (const char *s = strData.getCStr(&offset)) {
-      OS << format("0x%8.8x: \"", strOffset);
+      OS << format("0x%8.8" PRIx64 ": \"", strOffset);
       OS.write_escaped(s);
       OS << "\"\n";
       strOffset = offset;
@@ -514,11 +547,11 @@
   }
 
   if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
-                 DObj->getRangeSection().Data)) {
+                 DObj->getRangesSection().Data)) {
     uint8_t savedAddressByteSize = getCUAddrSize();
-    DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
+    DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
                                   isLittleEndian(), savedAddressByteSize);
-    uint32_t offset = 0;
+    uint64_t offset = 0;
     DWARFDebugRangeList rangeList;
     while (rangesData.isValidOffset(offset)) {
       if (Error E = rangeList.extract(rangesData, &offset)) {
@@ -552,38 +585,38 @@
   }
 
   if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
-                 DObj->getPubNamesSection().Data))
-    DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false)
+                 DObj->getPubnamesSection().Data))
+    DWARFDebugPubTable(*DObj, DObj->getPubnamesSection(), isLittleEndian(), false)
         .dump(OS);
 
   if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
-                 DObj->getPubTypesSection().Data))
-    DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false)
+                 DObj->getPubtypesSection().Data))
+    DWARFDebugPubTable(*DObj, DObj->getPubtypesSection(), isLittleEndian(), false)
         .dump(OS);
 
   if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
-                 DObj->getGnuPubNamesSection().Data))
-    DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(),
+                 DObj->getGnuPubnamesSection().Data))
+    DWARFDebugPubTable(*DObj, DObj->getGnuPubnamesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump(OS);
 
   if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
-                 DObj->getGnuPubTypesSection().Data))
-    DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(),
+                 DObj->getGnuPubtypesSection().Data))
+    DWARFDebugPubTable(*DObj, DObj->getGnuPubtypesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump(OS);
 
   if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
-                 DObj->getStringOffsetSection().Data))
+                 DObj->getStrOffsetsSection().Data))
     dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
-                             DObj->getStringOffsetSection(),
-                             DObj->getStringSection(), normal_units(),
+                             DObj->getStrOffsetsSection(),
+                             DObj->getStrSection(), normal_units(),
                              isLittleEndian(), getMaxVersion());
   if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
-                 DObj->getStringOffsetDWOSection().Data))
+                 DObj->getStrOffsetsDWOSection().Data))
     dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
-                             DObj->getStringOffsetDWOSection(),
-                             DObj->getStringDWOSection(), dwo_units(),
+                             DObj->getStrOffsetsDWOSection(),
+                             DObj->getStrDWOSection(), dwo_units(),
                              isLittleEndian(), getMaxDWOVersion());
 
   if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
@@ -607,7 +640,7 @@
                  DObj->getAppleObjCSection().Data))
     getAppleObjC().dump(OS);
   if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
-                 DObj->getDebugNamesSection().Data))
+                 DObj->getNamesSection().Data))
     getDebugNames().dump(OS);
 }
 
@@ -641,7 +674,7 @@
   return nullptr;
 }
 
-DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
+DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
   parseNormalUnits();
   if (auto *CU = NormalUnits.getUnitForOffset(Offset))
     return CU->getDIEForOffset(Offset);
@@ -667,7 +700,7 @@
 
   DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
 
-  CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
+  CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
   CUIndex->parse(CUIndexData);
   return *CUIndex;
 }
@@ -678,7 +711,7 @@
 
   DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
 
-  TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
+  TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
   TUIndex->parse(TUIndexData);
   return *TUIndex;
 }
@@ -688,7 +721,7 @@
     return *GdbIndex;
 
   DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
-  GdbIndex = llvm::make_unique<DWARFGdbIndex>();
+  GdbIndex = std::make_unique<DWARFGdbIndex>();
   GdbIndex->parse(GdbIndexData);
   return *GdbIndex;
 }
@@ -718,32 +751,16 @@
   if (Loc)
     return Loc.get();
 
-  Loc.reset(new DWARFDebugLoc);
   // Assume all units have the same address byte size.
-  if (getNumCompileUnits()) {
-    DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
-                               getUnitAtIndex(0)->getAddressByteSize());
-    Loc->parse(LocData);
-  }
+  auto LocData =
+      getNumCompileUnits()
+          ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(),
+                               getUnitAtIndex(0)->getAddressByteSize())
+          : DWARFDataExtractor("", isLittleEndian(), 0);
+  Loc.reset(new DWARFDebugLoc(std::move(LocData)));
   return Loc.get();
 }
 
-const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
-  if (LocDWO)
-    return LocDWO.get();
-
-  LocDWO.reset(new DWARFDebugLoclists());
-  // Assume all compile units have the same address byte size.
-  // FIXME: We don't need AddressSize for split DWARF since relocatable
-  // addresses cannot appear there. At the moment DWARFExpression requires it.
-  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
-  // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
-  // that means we are parsing the new style .debug_loc (pre-standatized version
-  // of the .debug_loclists).
-  LocDWO->parse(LocData, 4 /* Version */);
-  return LocDWO.get();
-}
-
 const DWARFDebugAranges *DWARFContext::getDebugAranges() {
   if (Aranges)
     return Aranges.get();
@@ -766,7 +783,7 @@
   // provides this information). This problem is fixed in DWARFv4
   // See this dwarf-discuss discussion for more details:
   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
-  DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
+  DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
                                     isLittleEndian(), DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
   DebugFrame->parse(debugFrameData);
@@ -777,13 +794,24 @@
   if (EHFrame)
     return EHFrame.get();
 
-  DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
-                                    DObj->getAddressSize());
+  DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
+                                    isLittleEndian(), DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
 }
 
+const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() {
+  if (MacroDWO)
+    return MacroDWO.get();
+
+  DataExtractor MacinfoDWOData(DObj->getMacinfoDWOSection(), isLittleEndian(),
+                               0);
+  MacroDWO.reset(new DWARFDebugMacro());
+  MacroDWO->parse(MacinfoDWOData);
+  return MacroDWO.get();
+}
+
 const DWARFDebugMacro *DWARFContext::getDebugMacro() {
   if (Macro)
     return Macro.get();
@@ -809,29 +837,29 @@
 }
 
 const DWARFDebugNames &DWARFContext::getDebugNames() {
-  return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
-                       DObj->getStringSection(), isLittleEndian());
+  return getAccelTable(Names, *DObj, DObj->getNamesSection(),
+                       DObj->getStrSection(), isLittleEndian());
 }
 
 const AppleAcceleratorTable &DWARFContext::getAppleNames() {
   return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
-                       DObj->getStringSection(), isLittleEndian());
+                       DObj->getStrSection(), isLittleEndian());
 }
 
 const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
   return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
-                       DObj->getStringSection(), isLittleEndian());
+                       DObj->getStrSection(), isLittleEndian());
 }
 
 const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
   return getAccelTable(AppleNamespaces, *DObj,
                        DObj->getAppleNamespacesSection(),
-                       DObj->getStringSection(), isLittleEndian());
+                       DObj->getStrSection(), isLittleEndian());
 }
 
 const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
   return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
-                       DObj->getStringSection(), isLittleEndian());
+                       DObj->getStrSection(), isLittleEndian());
 }
 
 const DWARFDebugLine::LineTable *
@@ -846,7 +874,7 @@
 }
 
 Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
-    DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
+    DWARFUnit *U, function_ref<void(Error)> RecoverableErrorCallback) {
   if (!Line)
     Line.reset(new DWARFDebugLine);
 
@@ -858,7 +886,7 @@
   if (!Offset)
     return nullptr; // No line table for this compile unit.
 
-  uint32_t stmtOffset = *Offset + U->getLineTableOffset();
+  uint64_t stmtOffset = *Offset + U->getLineTableOffset();
   // See if the line table is cached.
   if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
     return lt;
@@ -898,7 +926,7 @@
   });
 }
 
-DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
+DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
   parseNormalUnits();
   return dyn_cast_or_null<DWARFCompileUnit>(
       NormalUnits.getUnitForOffset(Offset));
@@ -906,7 +934,7 @@
 
 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
   // First, get the offset of the compile unit.
-  uint32_t CUOffset = getDebugAranges()->findAddress(Address);
+  uint64_t CUOffset = getDebugAranges()->findAddress(Address);
   // Retrieve the compile unit.
   return getCompileUnitForOffset(CUOffset);
 }
@@ -1030,19 +1058,56 @@
   return Optional<uint64_t>();
 }
 
+static Optional<int64_t>
+getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
+                         Optional<unsigned> FrameBaseReg) {
+  if (!Expr.empty() &&
+      (Expr[0] == DW_OP_fbreg ||
+       (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
+    unsigned Count;
+    int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
+    // A single DW_OP_fbreg or DW_OP_breg.
+    if (Expr.size() == Count + 1)
+      return Offset;
+    // Same + DW_OP_deref (Fortran arrays look like this).
+    if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
+      return Offset;
+    // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
+  }
+  return None;
+}
+
 void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
                                    DWARFDie Die, std::vector<DILocal> &Result) {
   if (Die.getTag() == DW_TAG_variable ||
       Die.getTag() == DW_TAG_formal_parameter) {
     DILocal Local;
-    if (auto NameAttr = Subprogram.find(DW_AT_name))
-      if (Optional<const char *> Name = NameAttr->getAsCString())
-        Local.FunctionName = *Name;
-    if (auto LocationAttr = Die.find(DW_AT_location))
-      if (Optional<ArrayRef<uint8_t>> Location = LocationAttr->getAsBlock())
-        if (!Location->empty() && (*Location)[0] == DW_OP_fbreg)
-          Local.FrameOffset =
-              decodeSLEB128(Location->data() + 1, nullptr, Location->end());
+    if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
+      Local.FunctionName = Name;
+
+    Optional<unsigned> FrameBaseReg;
+    if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
+      if (Optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
+        if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
+            (*Expr)[0] <= DW_OP_reg31) {
+          FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
+        }
+
+    if (Expected<std::vector<DWARFLocationExpression>> Loc =
+            Die.getLocations(DW_AT_location)) {
+      for (const auto &Entry : *Loc) {
+        if (Optional<int64_t> FrameOffset =
+                getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
+          Local.FrameOffset = *FrameOffset;
+          break;
+        }
+      }
+    } else {
+      // FIXME: missing DW_AT_location is OK here, but other errors should be
+      // reported to the user.
+      consumeError(Loc.takeError());
+    }
+
     if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
       Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
 
@@ -1118,8 +1183,8 @@
   if (!CU)
     return Lines;
 
-  std::string FunctionName = "<invalid>";
   uint32_t StartLine = 0;
+  std::string FunctionName(DILineInfo::BadString);
   getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
                                         FunctionName, StartLine);
 
@@ -1379,46 +1444,52 @@
   InfoSectionMap TypesDWOSections;
 
   DWARFSectionMap LocSection;
-  DWARFSectionMap LocListsSection;
+  DWARFSectionMap LoclistsSection;
+  DWARFSectionMap LoclistsDWOSection;
   DWARFSectionMap LineSection;
-  DWARFSectionMap RangeSection;
+  DWARFSectionMap RangesSection;
   DWARFSectionMap RnglistsSection;
-  DWARFSectionMap StringOffsetSection;
+  DWARFSectionMap StrOffsetsSection;
   DWARFSectionMap LineDWOSection;
+  DWARFSectionMap FrameSection;
+  DWARFSectionMap EHFrameSection;
   DWARFSectionMap LocDWOSection;
-  DWARFSectionMap StringOffsetDWOSection;
-  DWARFSectionMap RangeDWOSection;
+  DWARFSectionMap StrOffsetsDWOSection;
+  DWARFSectionMap RangesDWOSection;
   DWARFSectionMap RnglistsDWOSection;
   DWARFSectionMap AddrSection;
   DWARFSectionMap AppleNamesSection;
   DWARFSectionMap AppleTypesSection;
   DWARFSectionMap AppleNamespacesSection;
   DWARFSectionMap AppleObjCSection;
-  DWARFSectionMap DebugNamesSection;
-  DWARFSectionMap PubNamesSection;
-  DWARFSectionMap PubTypesSection;
-  DWARFSectionMap GnuPubNamesSection;
-  DWARFSectionMap GnuPubTypesSection;
+  DWARFSectionMap NamesSection;
+  DWARFSectionMap PubnamesSection;
+  DWARFSectionMap PubtypesSection;
+  DWARFSectionMap GnuPubnamesSection;
+  DWARFSectionMap GnuPubtypesSection;
 
   DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
     return StringSwitch<DWARFSectionMap *>(Name)
         .Case("debug_loc", &LocSection)
-        .Case("debug_loclists", &LocListsSection)
+        .Case("debug_loclists", &LoclistsSection)
+        .Case("debug_loclists.dwo", &LoclistsDWOSection)
         .Case("debug_line", &LineSection)
-        .Case("debug_str_offsets", &StringOffsetSection)
-        .Case("debug_ranges", &RangeSection)
+        .Case("debug_frame", &FrameSection)
+        .Case("eh_frame", &EHFrameSection)
+        .Case("debug_str_offsets", &StrOffsetsSection)
+        .Case("debug_ranges", &RangesSection)
         .Case("debug_rnglists", &RnglistsSection)
         .Case("debug_loc.dwo", &LocDWOSection)
         .Case("debug_line.dwo", &LineDWOSection)
-        .Case("debug_names", &DebugNamesSection)
+        .Case("debug_names", &NamesSection)
         .Case("debug_rnglists.dwo", &RnglistsDWOSection)
-        .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
+        .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
         .Case("debug_addr", &AddrSection)
         .Case("apple_names", &AppleNamesSection)
-        .Case("debug_pubnames", &PubNamesSection)
-        .Case("debug_pubtypes", &PubTypesSection)
-        .Case("debug_gnu_pubnames", &GnuPubNamesSection)
-        .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
+        .Case("debug_pubnames", &PubnamesSection)
+        .Case("debug_pubtypes", &PubtypesSection)
+        .Case("debug_gnu_pubnames", &GnuPubnamesSection)
+        .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
         .Case("apple_types", &AppleTypesSection)
         .Case("apple_namespaces", &AppleNamespacesSection)
         .Case("apple_namespac", &AppleNamespacesSection)
@@ -1427,17 +1498,16 @@
   }
 
   StringRef AbbrevSection;
-  StringRef ARangeSection;
-  StringRef DebugFrameSection;
-  StringRef EHFrameSection;
-  StringRef StringSection;
+  StringRef ArangesSection;
+  StringRef StrSection;
   StringRef MacinfoSection;
+  StringRef MacinfoDWOSection;
   StringRef AbbrevDWOSection;
-  StringRef StringDWOSection;
+  StringRef StrDWOSection;
   StringRef CUIndexSection;
   StringRef GdbIndexSection;
   StringRef TUIndexSection;
-  StringRef LineStringSection;
+  StringRef LineStrSection;
 
   // A deque holding section data whose iterators are not invalidated when
   // new decompressed sections are inserted at the end.
@@ -1448,17 +1518,16 @@
       return &Sec->Data;
     return StringSwitch<StringRef *>(Name)
         .Case("debug_abbrev", &AbbrevSection)
-        .Case("debug_aranges", &ARangeSection)
-        .Case("debug_frame", &DebugFrameSection)
-        .Case("eh_frame", &EHFrameSection)
-        .Case("debug_str", &StringSection)
+        .Case("debug_aranges", &ArangesSection)
+        .Case("debug_str", &StrSection)
         .Case("debug_macinfo", &MacinfoSection)
+        .Case("debug_macinfo.dwo", &MacinfoDWOSection)
         .Case("debug_abbrev.dwo", &AbbrevDWOSection)
-        .Case("debug_str.dwo", &StringDWOSection)
+        .Case("debug_str.dwo", &StrDWOSection)
         .Case("debug_cu_index", &CUIndexSection)
         .Case("debug_tu_index", &TUIndexSection)
         .Case("gdb_index", &GdbIndexSection)
-        .Case("debug_line_str", &LineStringSection)
+        .Case("debug_line_str", &LineStrSection)
         // Any more debug info sections go here.
         .Default(nullptr);
   }
@@ -1513,7 +1582,11 @@
     StringMap<unsigned> SectionAmountMap;
     for (const SectionRef &Section : Obj.sections()) {
       StringRef Name;
-      Section.getName(Name);
+      if (auto NameOrErr = Section.getName())
+        Name = *NameOrErr;
+      else
+        consumeError(NameOrErr.takeError());
+
       ++SectionAmountMap[Name];
       SectionNames.push_back({ Name, true });
 
@@ -1526,10 +1599,19 @@
         continue;
 
       StringRef Data;
-      section_iterator RelocatedSection = Section.getRelocatedSection();
+      Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
+      if (!SecOrErr) {
+        ErrorPolicy EP = HandleError(createError(
+            "failed to get relocated section: ", SecOrErr.takeError()));
+        if (EP == ErrorPolicy::Halt)
+          return;
+        continue;
+      }
+
       // Try to obtain an already relocated version of this section.
       // Else use the unrelocated section from the object file. We'll have to
       // apply relocations ourselves later.
+      section_iterator RelocatedSection = *SecOrErr;
       if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
         Expected<StringRef> E = Section.getContents();
         if (E)
@@ -1560,7 +1642,7 @@
         *SectionData = Data;
         if (Name == "debug_ranges") {
           // FIXME: Use the other dwo range section when we emit it.
-          RangeDWOSection.Data = Data;
+          RangesDWOSection.Data = Data;
         }
       } else if (Name == "debug_info") {
         // Find debug_info and debug_types data by section rather than name as
@@ -1578,12 +1660,15 @@
         continue;
 
       StringRef RelSecName;
-      StringRef RelSecData;
-      RelocatedSection->getName(RelSecName);
+      if (auto NameOrErr = RelocatedSection->getName())
+        RelSecName = *NameOrErr;
+      else
+        consumeError(NameOrErr.takeError());
 
       // If the section we're relocating was relocated already by the JIT,
       // then we used the relocated version above, so we do not need to process
       // relocations for it now.
+      StringRef RelSecData;
       if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
         continue;
 
@@ -1710,26 +1795,29 @@
   const DWARFSection &getLocDWOSection() const override {
     return LocDWOSection;
   }
-  StringRef getStringDWOSection() const override { return StringDWOSection; }
-  const DWARFSection &getStringOffsetDWOSection() const override {
-    return StringOffsetDWOSection;
+  StringRef getStrDWOSection() const override { return StrDWOSection; }
+  const DWARFSection &getStrOffsetsDWOSection() const override {
+    return StrOffsetsDWOSection;
   }
-  const DWARFSection &getRangeDWOSection() const override {
-    return RangeDWOSection;
+  const DWARFSection &getRangesDWOSection() const override {
+    return RangesDWOSection;
   }
   const DWARFSection &getRnglistsDWOSection() const override {
     return RnglistsDWOSection;
   }
+  const DWARFSection &getLoclistsDWOSection() const override {
+    return LoclistsDWOSection;
+  }
   const DWARFSection &getAddrSection() const override { return AddrSection; }
   StringRef getCUIndexSection() const override { return CUIndexSection; }
   StringRef getGdbIndexSection() const override { return GdbIndexSection; }
   StringRef getTUIndexSection() const override { return TUIndexSection; }
 
   // DWARF v5
-  const DWARFSection &getStringOffsetSection() const override {
-    return StringOffsetSection;
+  const DWARFSection &getStrOffsetsSection() const override {
+    return StrOffsetsSection;
   }
-  StringRef getLineStringSection() const override { return LineStringSection; }
+  StringRef getLineStrSection() const override { return LineStrSection; }
 
   // Sections for DWARF5 split dwarf proposal.
   void forEachInfoDWOSections(
@@ -1745,24 +1833,29 @@
 
   StringRef getAbbrevSection() const override { return AbbrevSection; }
   const DWARFSection &getLocSection() const override { return LocSection; }
-  const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
-  StringRef getARangeSection() const override { return ARangeSection; }
-  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
-  StringRef getEHFrameSection() const override { return EHFrameSection; }
+  const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
+  StringRef getArangesSection() const override { return ArangesSection; }
+  const DWARFSection &getFrameSection() const override {
+    return FrameSection;
+  }
+  const DWARFSection &getEHFrameSection() const override {
+    return EHFrameSection;
+  }
   const DWARFSection &getLineSection() const override { return LineSection; }
-  StringRef getStringSection() const override { return StringSection; }
-  const DWARFSection &getRangeSection() const override { return RangeSection; }
+  StringRef getStrSection() const override { return StrSection; }
+  const DWARFSection &getRangesSection() const override { return RangesSection; }
   const DWARFSection &getRnglistsSection() const override {
     return RnglistsSection;
   }
   StringRef getMacinfoSection() const override { return MacinfoSection; }
-  const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
-  const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
-  const DWARFSection &getGnuPubNamesSection() const override {
-    return GnuPubNamesSection;
+  StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
+  const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
+  const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
+  const DWARFSection &getGnuPubnamesSection() const override {
+    return GnuPubnamesSection;
   }
-  const DWARFSection &getGnuPubTypesSection() const override {
-    return GnuPubTypesSection;
+  const DWARFSection &getGnuPubtypesSection() const override {
+    return GnuPubtypesSection;
   }
   const DWARFSection &getAppleNamesSection() const override {
     return AppleNamesSection;
@@ -1776,8 +1869,8 @@
   const DWARFSection &getAppleObjCSection() const override {
     return AppleObjCSection;
   }
-  const DWARFSection &getDebugNamesSection() const override {
-    return DebugNamesSection;
+  const DWARFSection &getNamesSection() const override {
+    return NamesSection;
   }
 
   StringRef getFileName() const override { return FileName; }
@@ -1799,16 +1892,16 @@
 DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
                      function_ref<ErrorPolicy(Error)> HandleError,
                      std::string DWPName) {
-  auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
-  return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
+  auto DObj = std::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
+  return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
 }
 
 std::unique_ptr<DWARFContext>
 DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
                      uint8_t AddrSize, bool isLittleEndian) {
   auto DObj =
-      llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
-  return llvm::make_unique<DWARFContext>(std::move(DObj), "");
+      std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
+  return std::make_unique<DWARFContext>(std::move(DObj), "");
 }
 
 Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index b9adf8c..53e676b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -12,14 +12,15 @@
 
 using namespace llvm;
 
-uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
-                                               uint64_t *SecNdx) const {
+uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
+                                               uint64_t *SecNdx,
+                                               Error *Err) const {
   if (SecNdx)
     *SecNdx = object::SectionedAddress::UndefSection;
   if (!Section)
-    return getUnsigned(Off, Size);
+    return getUnsigned(Off, Size, Err);
   Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
-  uint64_t A = getUnsigned(Off, Size);
+  uint64_t A = getUnsigned(Off, Size, Err);
   if (!E)
     return A;
   if (SecNdx)
@@ -31,13 +32,13 @@
 }
 
 Optional<uint64_t>
-DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
+DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
                                       uint64_t PCRelOffset) const {
   if (Encoding == dwarf::DW_EH_PE_omit)
     return None;
 
   uint64_t Result = 0;
-  uint32_t OldOffset = *Offset;
+  uint64_t OldOffset = *Offset;
   // First get value
   switch (Encoding & 0x0F) {
   case dwarf::DW_EH_PE_absptr:
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
index 31b324e..4afac2f 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
@@ -26,9 +26,9 @@
 }
 
 bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
-                                              uint32_t *OffsetPtr) {
+                                              uint64_t *OffsetPtr) {
   clear();
-  const uint32_t BeginOffset = *OffsetPtr;
+  const uint64_t BeginOffset = *OffsetPtr;
   Offset = BeginOffset;
   DWARFAbbreviationDeclaration AbbrDecl;
   uint32_t PrevAbbrCode = 0;
@@ -82,12 +82,12 @@
 void DWARFDebugAbbrev::parse() const {
   if (!Data)
     return;
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   auto I = AbbrDeclSets.begin();
   while (Data->isValidOffset(Offset)) {
     while (I != AbbrDeclSets.end() && I->first < Offset)
       ++I;
-    uint32_t CUAbbrOffset = Offset;
+    uint64_t CUAbbrOffset = Offset;
     DWARFAbbreviationDeclarationSet AbbrDecls;
     if (!AbbrDecls.extract(*Data, &Offset))
       break;
@@ -124,7 +124,7 @@
   }
 
   if (Data && CUAbbrOffset < Data->getData().size()) {
-    uint32_t Offset = CUAbbrOffset;
+    uint64_t Offset = CUAbbrOffset;
     DWARFAbbreviationDeclarationSet AbbrDecls;
     if (!AbbrDecls.extract(*Data, &Offset))
       return nullptr;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index 5862653..f715437 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -19,7 +19,7 @@
 }
 
 Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
-                                   uint32_t *OffsetPtr,
+                                   uint64_t *OffsetPtr,
                                    uint16_t Version,
                                    uint8_t AddrSize,
                                    std::function<void(Error)> WarnCallback) {
@@ -30,7 +30,7 @@
     return createStringError(errc::invalid_argument,
                        "section is not large enough to contain a "
                        ".debug_addr table length at offset 0x%"
-                       PRIx32, *OffsetPtr);
+                       PRIx64, *OffsetPtr);
   uint16_t UnitVersion;
   if (Version == 0) {
     WarnCallback(createStringError(errc::invalid_argument,
@@ -44,28 +44,28 @@
   Format = dwarf::DwarfFormat::DWARF32;
   if (UnitVersion >= 5) {
     HeaderData.Length = Data.getU32(OffsetPtr);
-    if (HeaderData.Length == 0xffffffffu) {
+    if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
       invalidateLength();
       return createStringError(errc::not_supported,
-          "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx32,
+          "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64,
           HeaderOffset);
     }
     if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) {
       uint32_t TmpLength = getLength();
       invalidateLength();
       return createStringError(errc::invalid_argument,
-                         ".debug_addr table at offset 0x%" PRIx32
+                         ".debug_addr table at offset 0x%" PRIx64
                          " has too small length (0x%" PRIx32
                          ") to contain a complete header",
                          HeaderOffset, TmpLength);
     }
-    uint32_t End = HeaderOffset + getLength();
+    uint64_t End = HeaderOffset + getLength();
     if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) {
       uint32_t TmpLength = getLength();
       invalidateLength();
       return createStringError(errc::invalid_argument,
           "section is not large enough to contain a .debug_addr table "
-          "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
+          "of length 0x%" PRIx32 " at offset 0x%" PRIx64,
           TmpLength, HeaderOffset);
     }
 
@@ -88,7 +88,7 @@
   // and consists only of a series of addresses.
   if (HeaderData.Version > 5) {
     return createStringError(errc::not_supported, "version %" PRIu16
-        " of .debug_addr section at offset 0x%" PRIx32 " is not supported",
+        " of .debug_addr section at offset 0x%" PRIx64 " is not supported",
         HeaderData.Version, HeaderOffset);
   }
   // FIXME: For now we just treat version mismatch as an error,
@@ -97,19 +97,19 @@
   // attribute in the info table.
   if (HeaderData.Version != UnitVersion)
     return createStringError(errc::invalid_argument,
-                       ".debug_addr table at offset 0x%" PRIx32
+                       ".debug_addr table at offset 0x%" PRIx64
                        " has version %" PRIu16
                        " which is different from the version suggested"
                        " by the DWARF unit header: %" PRIu16,
                        HeaderOffset, HeaderData.Version, UnitVersion);
   if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
     return createStringError(errc::not_supported,
-                       ".debug_addr table at offset 0x%" PRIx32
+                       ".debug_addr table at offset 0x%" PRIx64
                        " has unsupported address size %" PRIu8,
                        HeaderOffset, HeaderData.AddrSize);
   if (HeaderData.AddrSize != AddrSize && AddrSize != 0)
     return createStringError(errc::invalid_argument,
-                       ".debug_addr table at offset 0x%" PRIx32
+                       ".debug_addr table at offset 0x%" PRIx64
                        " has address size %" PRIu8
                        " which is different from CU address size %" PRIu8,
                        HeaderOffset, HeaderData.AddrSize, AddrSize);
@@ -117,13 +117,13 @@
   // TODO: add support for non-zero segment selector size.
   if (HeaderData.SegSize != 0)
     return createStringError(errc::not_supported,
-                       ".debug_addr table at offset 0x%" PRIx32
+                       ".debug_addr table at offset 0x%" PRIx64
                        " has unsupported segment selector size %" PRIu8,
                        HeaderOffset, HeaderData.SegSize);
   if (DataSize % HeaderData.AddrSize != 0) {
     invalidateLength();
     return createStringError(errc::invalid_argument,
-                       ".debug_addr table at offset 0x%" PRIx32
+                       ".debug_addr table at offset 0x%" PRIx64
                        " contains data of size %" PRIu32
                        " which is not a multiple of addr size %" PRIu8,
                        HeaderOffset, DataSize, HeaderData.AddrSize);
@@ -162,7 +162,7 @@
     return Addrs[Index];
   return createStringError(errc::invalid_argument,
                            "Index %" PRIu32 " is out of range of the "
-                           ".debug_addr table at offset 0x%" PRIx32,
+                           ".debug_addr table at offset 0x%" PRIx64,
                            Index, HeaderOffset);
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 6551b61..200b2d5 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -24,13 +24,13 @@
 }
 
 void DWARFDebugArangeSet::clear() {
-  Offset = -1U;
+  Offset = -1ULL;
   std::memset(&HeaderData, 0, sizeof(Header));
   ArangeDescriptors.clear();
 }
 
 bool
-DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
+DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
   if (data.isValidOffset(*offset_ptr)) {
     ArangeDescriptors.clear();
     Offset = *offset_ptr;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index 6460c9f..fa157e8 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -23,11 +23,11 @@
 void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
   if (!DebugArangesData.isValidOffset(0))
     return;
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   DWARFDebugArangeSet Set;
 
   while (Set.extract(DebugArangesData, &Offset)) {
-    uint32_t CUOffset = Set.getCompileUnitDIEOffset();
+    uint64_t CUOffset = Set.getCompileUnitDIEOffset();
     for (const auto &Desc : Set.descriptors()) {
       uint64_t LowPC = Desc.Address;
       uint64_t HighPC = Desc.getEndAddress();
@@ -43,7 +43,7 @@
     return;
 
   // Extract aranges from .debug_aranges section.
-  DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
+  DataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
                             CTX->isLittleEndian(), 0);
   extract(ArangesData);
 
@@ -51,7 +51,7 @@
   // it may describe only a small subset of compilation units, so we need to
   // manually build aranges for the rest of them.
   for (const auto &CU : CTX->compile_units()) {
-    uint32_t CUOffset = CU->getOffset();
+    uint64_t CUOffset = CU->getOffset();
     if (ParsedCUOffsets.insert(CUOffset).second) {
       Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges();
       if (!CURanges)
@@ -71,7 +71,7 @@
   ParsedCUOffsets.clear();
 }
 
-void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
+void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC,
                                     uint64_t HighPC) {
   if (LowPC >= HighPC)
     return;
@@ -80,7 +80,7 @@
 }
 
 void DWARFDebugAranges::construct() {
-  std::multiset<uint32_t> ValidCUs;  // Maintain the set of CUs describing
+  std::multiset<uint64_t> ValidCUs;  // Maintain the set of CUs describing
                                      // a current address range.
   llvm::sort(Endpoints);
   uint64_t PrevAddress = -1ULL;
@@ -113,10 +113,10 @@
   Endpoints.shrink_to_fit();
 }
 
-uint32_t DWARFDebugAranges::findAddress(uint64_t Address) const {
+uint64_t DWARFDebugAranges::findAddress(uint64_t Address) const {
   RangeCollIterator It =
       partition_point(Aranges, [=](Range R) { return R.HighPC() <= Address; });
   if (It != Aranges.end() && It->LowPC <= Address)
     return It->CUOffset;
-  return -1U;
+  return -1ULL;
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b3f2336..81b00f6 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -34,10 +34,10 @@
 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
 
-Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
-                        uint32_t EndOffset) {
+Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
+                        uint64_t EndOffset) {
   while (*Offset < EndOffset) {
-    uint8_t Opcode = Data.getU8(Offset);
+    uint8_t Opcode = Data.getRelocatedValue(1, Offset);
     // Some instructions have a primary opcode encoded in the top bits.
     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
 
@@ -74,19 +74,19 @@
         break;
       case DW_CFA_set_loc:
         // Operands: Address
-        addInstruction(Opcode, Data.getAddress(Offset));
+        addInstruction(Opcode, Data.getRelocatedAddress(Offset));
         break;
       case DW_CFA_advance_loc1:
         // Operands: 1-byte delta
-        addInstruction(Opcode, Data.getU8(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(1, Offset));
         break;
       case DW_CFA_advance_loc2:
         // Operands: 2-byte delta
-        addInstruction(Opcode, Data.getU16(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(2, Offset));
         break;
       case DW_CFA_advance_loc4:
         // Operands: 4-byte delta
-        addInstruction(Opcode, Data.getU32(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(4, Offset));
         break;
       case DW_CFA_restore_extended:
       case DW_CFA_undefined:
@@ -331,7 +331,7 @@
 DWARFDebugFrame::~DWARFDebugFrame() = default;
 
 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
-                                              uint32_t Offset, int Length) {
+                                              uint64_t Offset, int Length) {
   errs() << "DUMP: ";
   for (int i = 0; i < Length; ++i) {
     uint8_t c = Data.getU8(&Offset);
@@ -344,7 +344,7 @@
 // noreturn attribute usage in lambdas. Once the support for those
 // compilers are phased out, we can remove this and return back to
 // a ReportError lambda: [StartOffset](const char *ErrorMsg).
-static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset,
+static void LLVM_ATTRIBUTE_NORETURN ReportError(uint64_t StartOffset,
                                                 const char *ErrorMsg) {
   std::string Str;
   raw_string_ostream OS(Str);
@@ -354,32 +354,30 @@
 }
 
 void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
-  uint32_t Offset = 0;
-  DenseMap<uint32_t, CIE *> CIEs;
+  uint64_t Offset = 0;
+  DenseMap<uint64_t, CIE *> CIEs;
 
   while (Data.isValidOffset(Offset)) {
-    uint32_t StartOffset = Offset;
+    uint64_t StartOffset = Offset;
 
     bool IsDWARF64 = false;
-    uint64_t Length = Data.getU32(&Offset);
+    uint64_t Length = Data.getRelocatedValue(4, &Offset);
     uint64_t Id;
 
-    if (Length == UINT32_MAX) {
+    if (Length == dwarf::DW_LENGTH_DWARF64) {
       // DWARF-64 is distinguished by the first 32 bits of the initial length
       // field being 0xffffffff. Then, the next 64 bits are the actual entry
       // length.
       IsDWARF64 = true;
-      Length = Data.getU64(&Offset);
+      Length = Data.getRelocatedValue(8, &Offset);
     }
 
     // At this point, Offset points to the next field after Length.
     // Length is the structure size excluding itself. Compute an offset one
     // past the end of the structure (needed to know how many instructions to
     // read).
-    // TODO: For honest DWARF64 support, DataExtractor will have to treat
-    //       offset_ptr as uint64_t*
-    uint32_t StartStructureOffset = Offset;
-    uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
+    uint64_t StartStructureOffset = Offset;
+    uint64_t EndStructureOffset = Offset + Length;
 
     // The Id field's size depends on the DWARF format
     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
@@ -407,22 +405,23 @@
       Optional<uint32_t> PersonalityEncoding;
       if (IsEH) {
         Optional<uint64_t> AugmentationLength;
-        uint32_t StartAugmentationOffset;
-        uint32_t EndAugmentationOffset;
+        uint64_t StartAugmentationOffset;
+        uint64_t EndAugmentationOffset;
 
         // Walk the augmentation string to get all the augmentation data.
         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
           switch (AugmentationString[i]) {
             default:
-              ReportError(StartOffset,
-                          "Unknown augmentation character in entry at %lx");
+              ReportError(
+                  StartOffset,
+                  "Unknown augmentation character in entry at %" PRIx64);
             case 'L':
               LSDAPointerEncoding = Data.getU8(&Offset);
               break;
             case 'P': {
               if (Personality)
                 ReportError(StartOffset,
-                            "Duplicate personality in entry at %lx");
+                            "Duplicate personality in entry at %" PRIx64);
               PersonalityEncoding = Data.getU8(&Offset);
               Personality = Data.getEncodedPointer(
                   &Offset, *PersonalityEncoding,
@@ -438,13 +437,12 @@
             case 'z':
               if (i)
                 ReportError(StartOffset,
-                            "'z' must be the first character at %lx");
+                            "'z' must be the first character at %" PRIx64);
               // Parse the augmentation length first.  We only parse it if
               // the string contains a 'z'.
               AugmentationLength = Data.getULEB128(&Offset);
               StartAugmentationOffset = Offset;
-              EndAugmentationOffset = Offset +
-                static_cast<uint32_t>(*AugmentationLength);
+              EndAugmentationOffset = Offset + *AugmentationLength;
               break;
             case 'B':
               // B-Key is used for signing functions associated with this
@@ -455,14 +453,15 @@
 
         if (AugmentationLength.hasValue()) {
           if (Offset != EndAugmentationOffset)
-            ReportError(StartOffset, "Parsing augmentation data at %lx failed");
+            ReportError(StartOffset,
+                        "Parsing augmentation data at %" PRIx64 " failed");
 
           AugmentationData = Data.getData().slice(StartAugmentationOffset,
                                                   EndAugmentationOffset);
         }
       }
 
-      auto Cie = llvm::make_unique<CIE>(
+      auto Cie = std::make_unique<CIE>(
           StartOffset, Length, Version, AugmentationString, AddressSize,
           SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
           ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
@@ -480,8 +479,8 @@
       if (IsEH) {
         // The address size is encoded in the CIE we reference.
         if (!Cie)
-          ReportError(StartOffset,
-                      "Parsing FDE data at %lx failed due to missing CIE");
+          ReportError(StartOffset, "Parsing FDE data at %" PRIx64
+                                   " failed due to missing CIE");
 
         if (auto Val = Data.getEncodedPointer(
                 &Offset, Cie->getFDEPointerEncoding(),
@@ -498,8 +497,7 @@
           // Parse the augmentation length and data for this FDE.
           uint64_t AugmentationLength = Data.getULEB128(&Offset);
 
-          uint32_t EndAugmentationOffset =
-            Offset + static_cast<uint32_t>(AugmentationLength);
+          uint64_t EndAugmentationOffset = Offset + AugmentationLength;
 
           // Decode the LSDA if the CIE augmentation string said we should.
           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
@@ -509,11 +507,12 @@
           }
 
           if (Offset != EndAugmentationOffset)
-            ReportError(StartOffset, "Parsing augmentation data at %lx failed");
+            ReportError(StartOffset,
+                        "Parsing augmentation data at %" PRIx64 " failed");
         }
       } else {
-        InitialLocation = Data.getAddress(&Offset);
-        AddressRange = Data.getAddress(&Offset);
+        InitialLocation = Data.getRelocatedAddress(&Offset);
+        AddressRange = Data.getRelocatedAddress(&Offset);
       }
 
       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
@@ -527,7 +526,8 @@
     }
 
     if (Offset != EndStructureOffset)
-      ReportError(StartOffset, "Parsing entry instructions at %lx failed");
+      ReportError(StartOffset,
+                  "Parsing entry instructions at %" PRIx64 " failed");
   }
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index d8a755e..87eab34 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -19,15 +19,15 @@
 using namespace dwarf;
 
 bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
-                                             uint32_t *OffsetPtr) {
+                                             uint64_t *OffsetPtr) {
   DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
-  const uint32_t UEndOffset = U.getNextUnitOffset();
+  const uint64_t UEndOffset = U.getNextUnitOffset();
   return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
 }
 
-bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
                                       const DWARFDataExtractor &DebugInfoData,
-                                      uint32_t UEndOffset, uint32_t D) {
+                                      uint64_t UEndOffset, uint32_t D) {
   Offset = *OffsetPtr;
   Depth = D;
   if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index a1cb1e8..11adb1e 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -16,7 +16,6 @@
 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Format.h"
-#include "llvm/Support/Path.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -40,7 +39,7 @@
 
 using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
 
-} // end anonmyous namespace
+} // end anonymous namespace
 
 void DWARFDebugLine::ContentTypeTracker::trackContentType(
     dwarf::LineNumberEntryFormat ContentType) {
@@ -156,7 +155,7 @@
 // Parse v2-v4 directory and file tables.
 static void
 parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
-                     uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
+                     uint64_t *OffsetPtr, uint64_t EndPrologueOffset,
                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
                      std::vector<DWARFFormValue> &IncludeDirectories,
                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
@@ -187,18 +186,15 @@
 }
 
 // Parse v5 directory/file entry content descriptions.
-// Returns the descriptors, or an empty vector if we did not find a path or
-// ran off the end of the prologue.
-static ContentDescriptors
-parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
-    *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker
-    *ContentTypes) {
+// Returns the descriptors, or an error if we did not find a path or ran off
+// the end of the prologue.
+static llvm::Expected<ContentDescriptors>
+parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+                   DWARFDebugLine::ContentTypeTracker *ContentTypes) {
   ContentDescriptors Descriptors;
   int FormatCount = DebugLineData.getU8(OffsetPtr);
   bool HasPath = false;
   for (int I = 0; I != FormatCount; ++I) {
-    if (*OffsetPtr >= EndPrologueOffset)
-      return ContentDescriptors();
     ContentDescriptor Descriptor;
     Descriptor.Type =
       dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr));
@@ -209,60 +205,65 @@
       ContentTypes->trackContentType(Descriptor.Type);
     Descriptors.push_back(Descriptor);
   }
-  return HasPath ? Descriptors : ContentDescriptors();
+
+  if (!HasPath)
+    return createStringError(errc::invalid_argument,
+                             "failed to parse entry content descriptions"
+                             " because no path was found");
+  return Descriptors;
 }
 
-static bool
+static Error
 parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
-                     uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
-                     const dwarf::FormParams &FormParams,
+                     uint64_t *OffsetPtr, const dwarf::FormParams &FormParams,
                      const DWARFContext &Ctx, const DWARFUnit *U,
                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
                      std::vector<DWARFFormValue> &IncludeDirectories,
                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
   // Get the directory entry description.
-  ContentDescriptors DirDescriptors =
-      parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr);
-  if (DirDescriptors.empty())
-    return false;
+  llvm::Expected<ContentDescriptors> DirDescriptors =
+      parseV5EntryFormat(DebugLineData, OffsetPtr, nullptr);
+  if (!DirDescriptors)
+    return DirDescriptors.takeError();
 
   // Get the directory entries, according to the format described above.
   int DirEntryCount = DebugLineData.getU8(OffsetPtr);
   for (int I = 0; I != DirEntryCount; ++I) {
-    if (*OffsetPtr >= EndPrologueOffset)
-      return false;
-    for (auto Descriptor : DirDescriptors) {
+    for (auto Descriptor : *DirDescriptors) {
       DWARFFormValue Value(Descriptor.Form);
       switch (Descriptor.Type) {
       case DW_LNCT_path:
         if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
-          return false;
+          return createStringError(errc::invalid_argument,
+                                   "failed to parse directory entry because "
+                                   "extracting the form value failed.");
         IncludeDirectories.push_back(Value);
         break;
       default:
         if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
-          return false;
+          return createStringError(errc::invalid_argument,
+                                   "failed to parse directory entry because "
+                                   "skipping the form value failed.");
       }
     }
   }
 
   // Get the file entry description.
-  ContentDescriptors FileDescriptors =
-      parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset,
-          &ContentTypes);
-  if (FileDescriptors.empty())
-    return false;
+  llvm::Expected<ContentDescriptors> FileDescriptors =
+      parseV5EntryFormat(DebugLineData, OffsetPtr, &ContentTypes);
+  if (!FileDescriptors)
+    return FileDescriptors.takeError();
 
   // Get the file entries, according to the format described above.
   int FileEntryCount = DebugLineData.getU8(OffsetPtr);
   for (int I = 0; I != FileEntryCount; ++I) {
-    if (*OffsetPtr >= EndPrologueOffset)
-      return false;
     DWARFDebugLine::FileNameEntry FileEntry;
-    for (auto Descriptor : FileDescriptors) {
+    for (auto Descriptor : *FileDescriptors) {
       DWARFFormValue Value(Descriptor.Form);
       if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
-        return false;
+        return createStringError(errc::invalid_argument,
+                                 "failed to parse file entry because "
+                                 "extracting the form value failed.");
       switch (Descriptor.Type) {
       case DW_LNCT_path:
         FileEntry.Name = Value;
@@ -280,7 +281,10 @@
         FileEntry.Length = Value.getAsUnsignedConstant().getValue();
         break;
       case DW_LNCT_MD5:
-        assert(Value.getAsBlock().getValue().size() == 16);
+        if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16)
+          return createStringError(
+              errc::invalid_argument,
+              "failed to parse file entry because the MD5 hash is invalid");
         std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
                                   FileEntry.Checksum.Bytes.begin());
         break;
@@ -290,21 +294,21 @@
     }
     FileNames.push_back(FileEntry);
   }
-  return true;
+  return Error::success();
 }
 
 Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
-                                      uint32_t *OffsetPtr,
+                                      uint64_t *OffsetPtr,
                                       const DWARFContext &Ctx,
                                       const DWARFUnit *U) {
   const uint64_t PrologueOffset = *OffsetPtr;
 
   clear();
   TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr);
-  if (TotalLength == UINT32_MAX) {
+  if (TotalLength == dwarf::DW_LENGTH_DWARF64) {
     FormParams.Format = dwarf::DWARF64;
     TotalLength = DebugLineData.getU64(OffsetPtr);
-  } else if (TotalLength >= 0xfffffff0) {
+  } else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) {
     return createStringError(errc::invalid_argument,
         "parsing line table prologue at offset 0x%8.8" PRIx64
         " unsupported reserved unit length found of value 0x%8.8" PRIx64,
@@ -343,14 +347,17 @@
   }
 
   if (getVersion() >= 5) {
-    if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
-                              FormParams, Ctx, U, ContentTypes,
-                              IncludeDirectories, FileNames)) {
-      return createStringError(errc::invalid_argument,
-          "parsing line table prologue at 0x%8.8" PRIx64
-          " found an invalid directory or file table description at"
-          " 0x%8.8" PRIx64,
-          PrologueOffset, (uint64_t)*OffsetPtr);
+    if (Error E =
+            parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
+                                 ContentTypes, IncludeDirectories, FileNames)) {
+      return joinErrors(
+          createStringError(
+              errc::invalid_argument,
+              "parsing line table prologue at 0x%8.8" PRIx64
+              " found an invalid directory or file table description at"
+              " 0x%8.8" PRIx64,
+              PrologueOffset, *OffsetPtr),
+          std::move(E));
     }
   } else
     parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
@@ -361,7 +368,7 @@
                        "parsing line table prologue at 0x%8.8" PRIx64
                        " should have ended at 0x%8.8" PRIx64
                        " but it ended at 0x%8.8" PRIx64,
-                       PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
+                       PrologueOffset, EndPrologueOffset, *OffsetPtr);
   return Error::success();
 }
 
@@ -420,14 +427,18 @@
 void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
                                      DIDumpOptions DumpOptions) const {
   Prologue.dump(OS, DumpOptions);
-  OS << '\n';
 
   if (!Rows.empty()) {
+    OS << '\n';
     Row::dumpTableHeader(OS);
     for (const Row &R : Rows) {
       R.dump(OS);
     }
   }
+
+  // Terminate the table with a final blank line to clearly delineate it from
+  // later dumps.
+  OS << '\n';
 }
 
 void DWARFDebugLine::LineTable::clear() {
@@ -468,7 +479,7 @@
 }
 
 const DWARFDebugLine::LineTable *
-DWARFDebugLine::getLineTable(uint32_t Offset) const {
+DWARFDebugLine::getLineTable(uint64_t Offset) const {
   LineTableConstIter Pos = LineTableMap.find(Offset);
   if (Pos != LineTableMap.end())
     return &Pos->second;
@@ -476,10 +487,10 @@
 }
 
 Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
-    DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx,
-    const DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
+    DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
+    const DWARFUnit *U, function_ref<void(Error)> RecoverableErrorCallback) {
   if (!DebugLineData.isValidOffset(Offset))
-    return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx32
+    return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64
                        " is not a valid debug line section offset",
                        Offset);
 
@@ -496,10 +507,10 @@
 }
 
 Error DWARFDebugLine::LineTable::parse(
-    DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
+    DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
     const DWARFContext &Ctx, const DWARFUnit *U,
-    std::function<void(Error)> RecoverableErrorCallback, raw_ostream *OS) {
-  const uint32_t DebugLineOffset = *OffsetPtr;
+    function_ref<void(Error)> RecoverableErrorCallback, raw_ostream *OS) {
+  const uint64_t DebugLineOffset = *OffsetPtr;
 
   clear();
 
@@ -515,8 +526,23 @@
   if (PrologueErr)
     return PrologueErr;
 
-  const uint32_t EndOffset =
-      DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
+  uint64_t ProgramLength = Prologue.TotalLength + Prologue.sizeofTotalLength();
+  if (!DebugLineData.isValidOffsetForDataOfSize(DebugLineOffset,
+                                                ProgramLength)) {
+    assert(DebugLineData.size() > DebugLineOffset &&
+           "prologue parsing should handle invalid offset");
+    uint64_t BytesRemaining = DebugLineData.size() - DebugLineOffset;
+    RecoverableErrorCallback(
+        createStringError(errc::invalid_argument,
+                          "line table program with offset 0x%8.8" PRIx64
+                          " has length 0x%8.8" PRIx64 " but only 0x%8.8" PRIx64
+                          " bytes are available",
+                          DebugLineOffset, ProgramLength, BytesRemaining));
+    // Continue by capping the length at the number of remaining bytes.
+    ProgramLength = BytesRemaining;
+  }
+
+  const uint64_t EndOffset = DebugLineOffset + ProgramLength;
 
   // See if we should tell the data extractor the address size.
   if (DebugLineData.getAddressSize() == 0)
@@ -529,7 +555,7 @@
 
   while (*OffsetPtr < EndOffset) {
     if (OS)
-      *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr);
+      *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
 
     uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
 
@@ -540,7 +566,7 @@
       // Extended Opcodes always start with a zero opcode followed by
       // a uleb128 length so you can skip ones you don't know about
       uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
-      uint32_t ExtOffset = *OffsetPtr;
+      uint64_t ExtOffset = *OffsetPtr;
 
       // Tolerate zero-length; assume length is correct and soldier on.
       if (Len == 0) {
@@ -562,12 +588,12 @@
         // address is that of the byte after the last target machine instruction
         // of the sequence.
         State.Row.EndSequence = true;
-        State.appendRowToMatrix();
         if (OS) {
           *OS << "\n";
           OS->indent(12);
           State.Row.dump(*OS);
         }
+        State.appendRowToMatrix();
         State.resetRowAndSequence();
         break;
 
@@ -581,19 +607,28 @@
         //
         // Make sure the extractor knows the address size.  If not, infer it
         // from the size of the operand.
-        if (DebugLineData.getAddressSize() == 0)
+        {
+          uint8_t ExtractorAddressSize = DebugLineData.getAddressSize();
+          if (ExtractorAddressSize != Len - 1 && ExtractorAddressSize != 0)
+            RecoverableErrorCallback(createStringError(
+                errc::invalid_argument,
+                "mismatching address size at offset 0x%8.8" PRIx64
+                " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
+                ExtOffset, ExtractorAddressSize, Len - 1));
+
+          // Assume that the line table is correct and temporarily override the
+          // address size.
           DebugLineData.setAddressSize(Len - 1);
-        else if (DebugLineData.getAddressSize() != Len - 1) {
-          return createStringError(errc::invalid_argument,
-                             "mismatching address size at offset 0x%8.8" PRIx32
-                             " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
-                             ExtOffset, DebugLineData.getAddressSize(),
-                             Len - 1);
+          State.Row.Address.Address = DebugLineData.getRelocatedAddress(
+              OffsetPtr, &State.Row.Address.SectionIndex);
+
+          // Restore the address size if the extractor already had it.
+          if (ExtractorAddressSize != 0)
+            DebugLineData.setAddressSize(ExtractorAddressSize);
+
+          if (OS)
+            *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
         }
-        State.Row.Address.Address = DebugLineData.getRelocatedAddress(
-            OffsetPtr, &State.Row.Address.SectionIndex);
-        if (OS)
-          *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
         break;
 
       case DW_LNE_define_file:
@@ -652,8 +687,8 @@
       // Otherwise we have an unparseable line-number program.
       if (*OffsetPtr - ExtOffset != Len)
         return createStringError(errc::illegal_byte_sequence,
-                           "unexpected line op length at offset 0x%8.8" PRIx32
-                           " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32,
+                           "unexpected line op length at offset 0x%8.8" PRIx64
+                           " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
                            ExtOffset, Len, *OffsetPtr - ExtOffset);
     } else if (Opcode < Prologue.OpcodeBase) {
       if (OS)
@@ -780,7 +815,7 @@
         // column register of the state machine.
         State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
         if (OS)
-          *OS << " (" << State.Row.Isa << ")";
+          *OS << " (" << (uint64_t)State.Row.Isa << ")";
         break;
 
       default:
@@ -855,9 +890,11 @@
   }
 
   if (!State.Sequence.Empty)
-    RecoverableErrorCallback(
-        createStringError(errc::illegal_byte_sequence,
-                    "last sequence in debug line table is not terminated!"));
+    RecoverableErrorCallback(createStringError(
+        errc::illegal_byte_sequence,
+        "last sequence in debug line table at offset 0x%8.8" PRIx64
+        " is not terminated",
+        DebugLineOffset));
 
   // Sort all sequences so that address lookup will work faster.
   if (!Sequences.empty()) {
@@ -1007,14 +1044,16 @@
          sys::path::is_absolute(Path, sys::path::Style::windows);
 }
 
-bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex,
-                                                  StringRef CompDir,
-                                                  FileLineInfoKind Kind,
-                                                  std::string &Result) const {
+bool DWARFDebugLine::Prologue::getFileNameByIndex(
+    uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
+    std::string &Result, sys::path::Style Style) const {
   if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
     return false;
   const FileNameEntry &Entry = getFileNameEntry(FileIndex);
-  StringRef FileName = Entry.Name.getAsCString().getValue();
+  Optional<const char *> Name = Entry.Name.getAsCString();
+  if (!Name)
+    return false;
+  StringRef FileName = *Name;
   if (Kind != FileLineInfoKind::AbsoluteFilePath ||
       isPathAbsoluteOnWindowsOrPosix(FileName)) {
     Result = FileName;
@@ -1036,11 +1075,11 @@
     // We know that FileName is not absolute, the only way to have an
     // absolute path at this point would be if IncludeDir is absolute.
     if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
-      sys::path::append(FilePath, CompDir);
+      sys::path::append(FilePath, Style, CompDir);
   }
 
   // sys::path::append skips empty strings.
-  sys::path::append(FilePath, IncludeDir, FileName);
+  sys::path::append(FilePath, Style, IncludeDir, FileName);
   Result = FilePath.str();
   return true;
 }
@@ -1092,7 +1131,8 @@
 }
 
 bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
-  return TotalLength == 0xffffffff || TotalLength < 0xfffffff0;
+  return TotalLength == dwarf::DW_LENGTH_DWARF64 ||
+         TotalLength < dwarf::DW_LENGTH_lo_reserved;
 }
 
 DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
@@ -1101,7 +1141,7 @@
   assert(DebugLineData.isValidOffset(Offset) &&
          "parsing should have terminated");
   DWARFUnit *U = prepareToParse(Offset);
-  uint32_t OldOffset = Offset;
+  uint64_t OldOffset = Offset;
   LineTable LT;
   if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
                            RecoverableErrorCallback, OS))
@@ -1115,14 +1155,14 @@
   assert(DebugLineData.isValidOffset(Offset) &&
          "parsing should have terminated");
   DWARFUnit *U = prepareToParse(Offset);
-  uint32_t OldOffset = Offset;
+  uint64_t OldOffset = Offset;
   LineTable LT;
   if (Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U))
     ErrorCallback(std::move(Err));
   moveToNextTable(OldOffset, LT.Prologue);
 }
 
-DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) {
+DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
   DWARFUnit *U = nullptr;
   auto It = LineToUnit.find(Offset);
   if (It != LineToUnit.end())
@@ -1131,7 +1171,7 @@
   return U;
 }
 
-void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset,
+void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
                                                     const Prologue &P) {
   // If the length field is not valid, we don't know where the next table is, so
   // cannot continue to parse. Mark the parser as done, and leave the Offset
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 6d8f4be..0c5f9a9 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -22,257 +22,388 @@
 #include <cstdint>
 
 using namespace llvm;
+using object::SectionedAddress;
+
+namespace {
+class DWARFLocationInterpreter {
+  Optional<object::SectionedAddress> Base;
+  std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
+
+public:
+  DWARFLocationInterpreter(
+      Optional<object::SectionedAddress> Base,
+      std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
+      : Base(Base), LookupAddr(std::move(LookupAddr)) {}
+
+  Expected<Optional<DWARFLocationExpression>>
+  Interpret(const DWARFLocationEntry &E);
+};
+} // namespace
+
+static Error createResolverError(uint32_t Index, unsigned Kind) {
+  return createStringError(errc::invalid_argument,
+                           "Unable to resolve indirect address %u for: %s",
+                           Index, dwarf::LocListEncodingString(Kind).data());
+}
+
+Expected<Optional<DWARFLocationExpression>>
+DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
+  switch (E.Kind) {
+  case dwarf::DW_LLE_end_of_list:
+    return None;
+  case dwarf::DW_LLE_base_addressx: {
+    Base = LookupAddr(E.Value0);
+    if (!Base)
+      return createResolverError(E.Value0, E.Kind);
+    return None;
+  }
+  case dwarf::DW_LLE_startx_endx: {
+    Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
+    if (!LowPC)
+      return createResolverError(E.Value0, E.Kind);
+    Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
+    if (!HighPC)
+      return createResolverError(E.Value1, E.Kind);
+    return DWARFLocationExpression{
+        DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
+        E.Loc};
+  }
+  case dwarf::DW_LLE_startx_length: {
+    Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
+    if (!LowPC)
+      return createResolverError(E.Value0, E.Kind);
+    return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
+                                                     LowPC->Address + E.Value1,
+                                                     LowPC->SectionIndex},
+                                   E.Loc};
+  }
+  case dwarf::DW_LLE_offset_pair: {
+    if (!Base) {
+      return createStringError(inconvertibleErrorCode(),
+                               "Unable to resolve location list offset pair: "
+                               "Base address not defined");
+    }
+    DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
+                            Base->SectionIndex};
+    if (Range.SectionIndex == SectionedAddress::UndefSection)
+      Range.SectionIndex = E.SectionIndex;
+    return DWARFLocationExpression{Range, E.Loc};
+  }
+  case dwarf::DW_LLE_default_location:
+    return DWARFLocationExpression{None, E.Loc};
+  case dwarf::DW_LLE_base_address:
+    Base = SectionedAddress{E.Value0, E.SectionIndex};
+    return None;
+  case dwarf::DW_LLE_start_end:
+    return DWARFLocationExpression{
+        DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
+  case dwarf::DW_LLE_start_length:
+    return DWARFLocationExpression{
+        DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
+        E.Loc};
+  default:
+    llvm_unreachable("unreachable locations list kind");
+  }
+}
 
 // When directly dumping the .debug_loc without a compile unit, we have to guess
 // at the DWARF version. This only affects DW_OP_call_ref, which is a rare
 // expression that LLVM doesn't produce. Guessing the wrong version means we
 // won't be able to pretty print expressions in DWARF2 binaries produced by
 // non-LLVM tools.
-static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data,
+static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
                            bool IsLittleEndian, unsigned AddressSize,
                            const MCRegisterInfo *MRI, DWARFUnit *U) {
-  DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()),
-                               IsLittleEndian, AddressSize);
+  DWARFDataExtractor Extractor(toStringRef(Data), IsLittleEndian, AddressSize);
   DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U);
 }
 
-void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
-                                       unsigned AddressSize,
-                                       const MCRegisterInfo *MRI,
-                                       DWARFUnit *U,
-                                       uint64_t BaseAddress,
-                                       unsigned Indent) const {
-  for (const Entry &E : Entries) {
-    OS << '\n';
-    OS.indent(Indent);
-    OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2,
-                 BaseAddress + E.Begin);
-    OS << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2,
-                 BaseAddress + E.End);
-    OS << ": ";
+bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
+                                          Optional<SectionedAddress> BaseAddr,
+                                          const MCRegisterInfo *MRI,
+                                          const DWARFObject &Obj, DWARFUnit *U,
+                                          DIDumpOptions DumpOpts,
+                                          unsigned Indent) const {
+  DWARFLocationInterpreter Interp(
+      BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
+        if (U)
+          return U->getAddrOffsetSectionItem(Index);
+        return None;
+      });
+  OS << format("0x%8.8" PRIx64 ": ", *Offset);
+  Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
+    Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
+    if (!Loc || DumpOpts.DisplayRawContents)
+      dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
+    if (Loc && *Loc) {
+      OS << "\n";
+      OS.indent(Indent);
+      if (DumpOpts.DisplayRawContents)
+        OS << "          => ";
 
-    dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
+      DIDumpOptions RangeDumpOpts(DumpOpts);
+      RangeDumpOpts.DisplayRawContents = false;
+      if (Loc.get()->Range)
+        Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
+      else
+        OS << "<default>";
+    }
+    if (!Loc)
+      consumeError(Loc.takeError());
+
+    if (E.Kind != dwarf::DW_LLE_base_address &&
+        E.Kind != dwarf::DW_LLE_base_addressx &&
+        E.Kind != dwarf::DW_LLE_end_of_list) {
+      OS << ": ";
+      dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(),
+                     MRI, U);
+    }
+    return true;
+  });
+  if (E) {
+    OS << "\n";
+    OS.indent(Indent);
+    OS << "error: " << toString(std::move(E));
+    return false;
   }
+  return true;
 }
 
-DWARFDebugLoc::LocationList const *
-DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
-  auto It = partition_point(
-      Locations, [=](const LocationList &L) { return L.Offset < Offset; });
-  if (It != Locations.end() && It->Offset == Offset)
-    return &(*It);
-  return nullptr;
+Error DWARFLocationTable::visitAbsoluteLocationList(
+    uint64_t Offset, Optional<SectionedAddress> BaseAddr,
+    std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
+    function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
+  DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
+  return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
+    Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
+    if (!Loc)
+      return Callback(Loc.takeError());
+    if (*Loc)
+      return Callback(**Loc);
+    return true;
+  });
 }
 
 void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
-                         Optional<uint64_t> Offset) const {
-  auto DumpLocationList = [&](const LocationList &L) {
-    OS << format("0x%8.8x: ", L.Offset);
-    L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12);
-    OS << "\n\n";
-  };
+                         const DWARFObject &Obj, DIDumpOptions DumpOpts,
+                         Optional<uint64_t> DumpOffset) const {
+  auto BaseAddr = None;
+  unsigned Indent = 12;
+  if (DumpOffset) {
+    dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
+                     Indent);
+  } else {
+    uint64_t Offset = 0;
+    StringRef Separator;
+    bool CanContinue = true;
+    while (CanContinue && Data.isValidOffset(Offset)) {
+      OS << Separator;
+      Separator = "\n";
 
-  if (Offset) {
-    if (auto *L = getLocationListAtOffset(*Offset))
-      DumpLocationList(*L);
-    return;
-  }
-
-  for (const LocationList &L : Locations) {
-    DumpLocationList(L);
+      CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
+                                     DumpOpts, Indent);
+      OS << '\n';
+    }
   }
 }
 
-Optional<DWARFDebugLoc::LocationList>
-DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) {
-  LocationList LL;
-  LL.Offset = *Offset;
-
-  // 2.6.2 Location Lists
-  // A location list entry consists of:
+Error DWARFDebugLoc::visitLocationList(
+    uint64_t *Offset,
+    function_ref<bool(const DWARFLocationEntry &)> Callback) const {
+  DataExtractor::Cursor C(*Offset);
   while (true) {
-    Entry E;
-    if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) {
-      WithColor::error() << "location list overflows the debug_loc section.\n";
-      return None;
-    }
+    uint64_t SectionIndex;
+    uint64_t Value0 = Data.getRelocatedAddress(C);
+    uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
 
-    // 1. A beginning address offset. ...
-    E.Begin = Data.getRelocatedAddress(Offset);
-
-    // 2. An ending address offset. ...
-    E.End = Data.getRelocatedAddress(Offset);
+    DWARFLocationEntry E;
 
     // The end of any given location list is marked by an end of list entry,
     // which consists of a 0 for the beginning address offset and a 0 for the
-    // ending address offset.
-    if (E.Begin == 0 && E.End == 0)
-      return LL;
-
-    if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) {
-      WithColor::error() << "location list overflows the debug_loc section.\n";
-      return None;
+    // ending address offset. A beginning offset of 0xff...f marks the base
+    // address selection entry.
+    if (Value0 == 0 && Value1 == 0) {
+      E.Kind = dwarf::DW_LLE_end_of_list;
+    } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
+      E.Kind = dwarf::DW_LLE_base_address;
+      E.Value0 = Value1;
+      E.SectionIndex = SectionIndex;
+    } else {
+      E.Kind = dwarf::DW_LLE_offset_pair;
+      E.Value0 = Value0;
+      E.Value1 = Value1;
+      E.SectionIndex = SectionIndex;
+      unsigned Bytes = Data.getU16(C);
+      // A single location description describing the location of the object...
+      Data.getU8(C, E.Loc, Bytes);
     }
 
-    unsigned Bytes = Data.getU16(Offset);
-    if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) {
-      WithColor::error() << "location list overflows the debug_loc section.\n";
-      return None;
-    }
-    // A single location description describing the location of the object...
-    StringRef str = Data.getData().substr(*Offset, Bytes);
-    *Offset += Bytes;
-    E.Loc.reserve(str.size());
-    llvm::copy(str, std::back_inserter(E.Loc));
-    LL.Entries.push_back(std::move(E));
-  }
-}
-
-void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
-  IsLittleEndian = data.isLittleEndian();
-  AddressSize = data.getAddressSize();
-
-  uint32_t Offset = 0;
-  while (data.isValidOffset(Offset + data.getAddressSize() - 1)) {
-    if (auto LL = parseOneLocationList(data, &Offset))
-      Locations.push_back(std::move(*LL));
-    else
+    if (!C)
+      return C.takeError();
+    if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
       break;
   }
-  if (data.isValidOffset(Offset))
-    WithColor::error() << "failed to consume entire .debug_loc section\n";
+  *Offset = C.tell();
+  return Error::success();
 }
 
-Optional<DWARFDebugLoclists::LocationList>
-DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset,
-                                         unsigned Version) {
-  LocationList LL;
-  LL.Offset = *Offset;
+void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
+                                 raw_ostream &OS, unsigned Indent,
+                                 DIDumpOptions DumpOpts,
+                                 const DWARFObject &Obj) const {
+  uint64_t Value0, Value1;
+  switch (Entry.Kind) {
+  case dwarf::DW_LLE_base_address:
+    Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
+    Value1 = Entry.Value0;
+    break;
+  case dwarf::DW_LLE_offset_pair:
+    Value0 = Entry.Value0;
+    Value1 = Entry.Value1;
+    break;
+  case dwarf::DW_LLE_end_of_list:
+    Value0 = Value1 = 0;
+    return;
+  default:
+    llvm_unreachable("Not possible in DWARF4!");
+  }
+  OS << '\n';
+  OS.indent(Indent);
+  OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
+     << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
+  DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
+}
 
-  // dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
-  while (auto Kind =
-             static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
+Error DWARFDebugLoclists::visitLocationList(
+    uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
 
-    Entry E;
-    E.Kind = Kind;
-    switch (Kind) {
+  DataExtractor::Cursor C(*Offset);
+  bool Continue = true;
+  while (Continue) {
+    DWARFLocationEntry E;
+    E.Kind = Data.getU8(C);
+    switch (E.Kind) {
+    case dwarf::DW_LLE_end_of_list:
+      break;
+    case dwarf::DW_LLE_base_addressx:
+      E.Value0 = Data.getULEB128(C);
+      break;
+    case dwarf::DW_LLE_startx_endx:
+      E.Value0 = Data.getULEB128(C);
+      E.Value1 = Data.getULEB128(C);
+      break;
     case dwarf::DW_LLE_startx_length:
-      E.Value0 = Data.getULEB128(Offset);
+      E.Value0 = Data.getULEB128(C);
       // Pre-DWARF 5 has different interpretation of the length field. We have
       // to support both pre- and standartized styles for the compatibility.
       if (Version < 5)
-        E.Value1 = Data.getU32(Offset);
+        E.Value1 = Data.getU32(C);
       else
-        E.Value1 = Data.getULEB128(Offset);
-      break;
-    case dwarf::DW_LLE_start_length:
-      E.Value0 = Data.getAddress(Offset);
-      E.Value1 = Data.getULEB128(Offset);
+        E.Value1 = Data.getULEB128(C);
       break;
     case dwarf::DW_LLE_offset_pair:
-      E.Value0 = Data.getULEB128(Offset);
-      E.Value1 = Data.getULEB128(Offset);
+      E.Value0 = Data.getULEB128(C);
+      E.Value1 = Data.getULEB128(C);
+      E.SectionIndex = SectionedAddress::UndefSection;
+      break;
+    case dwarf::DW_LLE_default_location:
       break;
     case dwarf::DW_LLE_base_address:
-      E.Value0 = Data.getAddress(Offset);
+      E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+      break;
+    case dwarf::DW_LLE_start_end:
+      E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+      E.Value1 = Data.getRelocatedAddress(C);
+      break;
+    case dwarf::DW_LLE_start_length:
+      E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+      E.Value1 = Data.getULEB128(C);
       break;
     default:
-      WithColor::error() << "dumping support for LLE of kind " << (int)Kind
-                         << " not implemented\n";
-      return None;
+      cantFail(C.takeError());
+      return createStringError(errc::illegal_byte_sequence,
+                               "LLE of kind %x not supported", (int)E.Kind);
     }
 
-    if (Kind != dwarf::DW_LLE_base_address) {
-      unsigned Bytes =
-          Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset);
+    if (E.Kind != dwarf::DW_LLE_base_address &&
+        E.Kind != dwarf::DW_LLE_base_addressx &&
+        E.Kind != dwarf::DW_LLE_end_of_list) {
+      unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
       // A single location description describing the location of the object...
-      StringRef str = Data.getData().substr(*Offset, Bytes);
-      *Offset += Bytes;
-      E.Loc.resize(str.size());
-      llvm::copy(str, E.Loc.begin());
+      Data.getU8(C, E.Loc, Bytes);
     }
 
-    LL.Entries.push_back(std::move(E));
+    if (!C)
+      return C.takeError();
+    Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
   }
-  return LL;
+  *Offset = C.tell();
+  return Error::success();
 }
 
-void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
-  IsLittleEndian = data.isLittleEndian();
-  AddressSize = data.getAddressSize();
+void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
+                                      raw_ostream &OS, unsigned Indent,
+                                      DIDumpOptions DumpOpts,
+                                      const DWARFObject &Obj) const {
+  size_t MaxEncodingStringLength = 0;
+#define HANDLE_DW_LLE(ID, NAME)                                                \
+  MaxEncodingStringLength = std::max(MaxEncodingStringLength,                  \
+                                     dwarf::LocListEncodingString(ID).size());
+#include "llvm/BinaryFormat/Dwarf.def"
 
-  uint32_t Offset = 0;
-  while (data.isValidOffset(Offset)) {
-    if (auto LL = parseOneLocationList(data, &Offset, Version))
-      Locations.push_back(std::move(*LL));
-    else
-      return;
+  OS << "\n";
+  OS.indent(Indent);
+  StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
+  // Unsupported encodings should have been reported during parsing.
+  assert(!EncodingString.empty() && "Unknown loclist entry encoding");
+  OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
+  unsigned FieldSize = 2 + 2 * Data.getAddressSize();
+  switch (Entry.Kind) {
+  case dwarf::DW_LLE_end_of_list:
+  case dwarf::DW_LLE_default_location:
+    break;
+  case dwarf::DW_LLE_startx_endx:
+  case dwarf::DW_LLE_startx_length:
+  case dwarf::DW_LLE_offset_pair:
+  case dwarf::DW_LLE_start_end:
+  case dwarf::DW_LLE_start_length:
+    OS << format_hex(Entry.Value0, FieldSize) << ", "
+       << format_hex(Entry.Value1, FieldSize);
+    break;
+  case dwarf::DW_LLE_base_addressx:
+  case dwarf::DW_LLE_base_address:
+    OS << format_hex(Entry.Value0, FieldSize);
+    break;
+  }
+  OS << ')';
+  switch (Entry.Kind) {
+  case dwarf::DW_LLE_base_address:
+  case dwarf::DW_LLE_start_end:
+  case dwarf::DW_LLE_start_length:
+    DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
+    break;
+  default:
+    break;
   }
 }
 
-DWARFDebugLoclists::LocationList const *
-DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const {
-  auto It = partition_point(
-      Locations, [=](const LocationList &L) { return L.Offset < Offset; });
-  if (It != Locations.end() && It->Offset == Offset)
-    return &(*It);
-  return nullptr;
-}
-
-void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
-                                            bool IsLittleEndian,
-                                            unsigned AddressSize,
-                                            const MCRegisterInfo *MRI,
-                                            DWARFUnit *U,
-                                            unsigned Indent) const {
-  for (const Entry &E : Entries) {
-    switch (E.Kind) {
-    case dwarf::DW_LLE_startx_length:
-      OS << '\n';
-      OS.indent(Indent);
-      OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): ";
-      break;
-    case dwarf::DW_LLE_start_length:
-      OS << '\n';
-      OS.indent(Indent);
-      OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
-                   AddressSize * 2, E.Value0, AddressSize * 2, AddressSize * 2,
-                   E.Value0 + E.Value1);
-      break;
-    case dwarf::DW_LLE_offset_pair:
-      OS << '\n';
-      OS.indent(Indent);
-      OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
-                   AddressSize * 2, BaseAddr + E.Value0, AddressSize * 2,
-                   AddressSize * 2, BaseAddr + E.Value1);
-      break;
-    case dwarf::DW_LLE_base_address:
-      BaseAddr = E.Value0;
-      break;
-    default:
-      llvm_unreachable("unreachable locations list kind");
-    }
-
-    dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
-  }
-}
-
-void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
-                              const MCRegisterInfo *MRI,
-                              Optional<uint64_t> Offset) const {
-  auto DumpLocationList = [&](const LocationList &L) {
-    OS << format("0x%8.8x: ", L.Offset);
-    L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12);
-    OS << "\n\n";
-  };
-
-  if (Offset) {
-    if (auto *L = getLocationListAtOffset(*Offset))
-      DumpLocationList(*L);
+void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
+                                   raw_ostream &OS, const MCRegisterInfo *MRI,
+                                   const DWARFObject &Obj,
+                                   DIDumpOptions DumpOpts) {
+  if (!Data.isValidOffsetForDataOfSize(StartOffset, Size))  {
+    OS << "Invalid dump range\n";
     return;
   }
+  uint64_t Offset = StartOffset;
+  StringRef Separator;
+  bool CanContinue = true;
+  while (CanContinue && Offset < StartOffset + Size) {
+    OS << Separator;
+    Separator = "\n";
 
-  for (const LocationList &L : Locations) {
-    DumpLocationList(L);
+    CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
+                                   nullptr, DumpOpts, /*Indent=*/12);
+    OS << '\n';
   }
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 3317a77..8cb259e 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -17,52 +17,61 @@
 
 void DWARFDebugMacro::dump(raw_ostream &OS) const {
   unsigned IndLevel = 0;
-  for (const Entry &E : Macros) {
-    // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
-    // this check handles the case of corrupted ".debug_macinfo" section.
-    if (IndLevel > 0)
-      IndLevel -= (E.Type == DW_MACINFO_end_file);
-    // Print indentation.
-    for (unsigned I = 0; I < IndLevel; I++)
-      OS << "  ";
-    IndLevel += (E.Type == DW_MACINFO_start_file);
+  for (const auto &Macros : MacroLists) {
+    for (const Entry &E : Macros) {
+      // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
+      // this check handles the case of corrupted ".debug_macinfo" section.
+      if (IndLevel > 0)
+        IndLevel -= (E.Type == DW_MACINFO_end_file);
+      // Print indentation.
+      for (unsigned I = 0; I < IndLevel; I++)
+        OS << "  ";
+      IndLevel += (E.Type == DW_MACINFO_start_file);
 
-    WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
-    switch (E.Type) {
-    default:
-      // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
-      break;
-    case DW_MACINFO_define:
-    case DW_MACINFO_undef:
-      OS << " - lineno: " << E.Line;
-      OS << " macro: " << E.MacroStr;
-      break;
-    case DW_MACINFO_start_file:
-      OS << " - lineno: " << E.Line;
-      OS << " filenum: " << E.File;
-      break;
-    case DW_MACINFO_end_file:
-      break;
-    case DW_MACINFO_vendor_ext:
-      OS << " - constant: " << E.ExtConstant;
-      OS << " string: " << E.ExtStr;
-      break;
+      WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
+      switch (E.Type) {
+      default:
+        // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
+        break;
+      case DW_MACINFO_define:
+      case DW_MACINFO_undef:
+        OS << " - lineno: " << E.Line;
+        OS << " macro: " << E.MacroStr;
+        break;
+      case DW_MACINFO_start_file:
+        OS << " - lineno: " << E.Line;
+        OS << " filenum: " << E.File;
+        break;
+      case DW_MACINFO_end_file:
+        break;
+      case DW_MACINFO_vendor_ext:
+        OS << " - constant: " << E.ExtConstant;
+        OS << " string: " << E.ExtStr;
+        break;
+      }
+      OS << "\n";
     }
     OS << "\n";
   }
 }
 
 void DWARFDebugMacro::parse(DataExtractor data) {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
+  MacroList *M = nullptr;
   while (data.isValidOffset(Offset)) {
+    if (!M) {
+      MacroLists.emplace_back();
+      M = &MacroLists.back();
+    }
     // A macro list entry consists of:
-    Entry E;
+    M->emplace_back();
+    Entry &E = M->back();
     // 1. Macinfo type
     E.Type = data.getULEB128(&Offset);
 
     if (E.Type == 0) {
-      // Reached end of ".debug_macinfo" section.
-      return;
+      // Reached end of a ".debug_macinfo" section contribution.
+      continue;
     }
 
     switch (E.Type) {
@@ -70,7 +79,6 @@
       // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
       // Push the corrupted entry to the list and halt parsing.
       E.Type = DW_MACINFO_invalid;
-      Macros.push_back(E);
       return;
     case DW_MACINFO_define:
     case DW_MACINFO_undef:
@@ -94,7 +102,5 @@
       E.ExtStr = data.getCStr(&Offset);
       break;
     }
-
-    Macros.push_back(E);
   }
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
index 963ec64..ab71b23 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
@@ -23,7 +23,7 @@
                                        bool LittleEndian, bool GnuStyle)
     : GnuStyle(GnuStyle) {
   DWARFDataExtractor PubNames(Obj, Sec, LittleEndian, 0);
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   while (PubNames.isValidOffset(Offset)) {
     Sets.push_back({});
     Set &SetData = Sets.back();
@@ -49,13 +49,13 @@
   for (const Set &S : Sets) {
     OS << "length = " << format("0x%08x", S.Length);
     OS << " version = " << format("0x%04x", S.Version);
-    OS << " unit_offset = " << format("0x%08x", S.Offset);
+    OS << " unit_offset = " << format("0x%08" PRIx64, S.Offset);
     OS << " unit_size = " << format("0x%08x", S.Size) << '\n';
     OS << (GnuStyle ? "Offset     Linkage  Kind     Name\n"
                     : "Offset     Name\n");
 
     for (const Entry &E : S.Entries) {
-      OS << format("0x%8.8x ", E.SecOffset);
+      OS << format("0x%8.8" PRIx64 " ", E.SecOffset);
       if (GnuStyle) {
         StringRef EntryLinkage =
             GDBIndexEntryLinkageString(E.Descriptor.Linkage);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index d8df81a..1a1857d 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -17,17 +17,17 @@
 using namespace llvm;
 
 void DWARFDebugRangeList::clear() {
-  Offset = -1U;
+  Offset = -1ULL;
   AddressSize = 0;
   Entries.clear();
 }
 
 Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
-                                   uint32_t *offset_ptr) {
+                                   uint64_t *offset_ptr) {
   clear();
   if (!data.isValidOffset(*offset_ptr))
     return createStringError(errc::invalid_argument,
-                       "invalid range list offset 0x%" PRIx32, *offset_ptr);
+                       "invalid range list offset 0x%" PRIx64, *offset_ptr);
 
   AddressSize = data.getAddressSize();
   if (AddressSize != 4 && AddressSize != 8)
@@ -38,7 +38,7 @@
     RangeListEntry Entry;
     Entry.SectionIndex = -1ULL;
 
-    uint32_t prev_offset = *offset_ptr;
+    uint64_t prev_offset = *offset_ptr;
     Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
     Entry.EndAddress =
         data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
@@ -47,7 +47,7 @@
     if (*offset_ptr != prev_offset + 2 * AddressSize) {
       clear();
       return createStringError(errc::invalid_argument,
-                         "invalid range list entry at offset 0x%" PRIx32,
+                         "invalid range list entry at offset 0x%" PRIx64,
                          prev_offset);
     }
     if (Entry.isEndOfListEntry())
@@ -59,12 +59,12 @@
 
 void DWARFDebugRangeList::dump(raw_ostream &OS) const {
   for (const RangeListEntry &RLE : Entries) {
-    const char *format_str = (AddressSize == 4
-                              ? "%08x %08"  PRIx64 " %08"  PRIx64 "\n"
-                              : "%08x %016" PRIx64 " %016" PRIx64 "\n");
+    const char *format_str =
+        (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n"
+                          : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n");
     OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
   }
-  OS << format("%08x <End of list>\n", Offset);
+  OS << format("%08" PRIx64 " <End of list>\n", Offset);
 }
 
 DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 5ac3326..9ae4c5b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -16,8 +16,8 @@
 
 using namespace llvm;
 
-Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
-                              uint32_t *OffsetPtr) {
+Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End,
+                              uint64_t *OffsetPtr) {
   Offset = *OffsetPtr;
   SectionIndex = -1ULL;
   // The caller should guarantee that we have at least 1 byte available, so
@@ -32,41 +32,41 @@
     break;
   // TODO: Support other encodings.
   case dwarf::DW_RLE_base_addressx: {
-    uint32_t PreviousOffset = *OffsetPtr - 1;
+    uint64_t PreviousOffset = *OffsetPtr - 1;
     Value0 = Data.getULEB128(OffsetPtr);
     if (End < *OffsetPtr)
       return createStringError(
           errc::invalid_argument,
           "read past end of table when reading "
-          "DW_RLE_base_addressx encoding at offset 0x%" PRIx32,
+          "DW_RLE_base_addressx encoding at offset 0x%" PRIx64,
           PreviousOffset);
     break;
   }
   case dwarf::DW_RLE_startx_endx:
     return createStringError(errc::not_supported,
                        "unsupported rnglists encoding DW_RLE_startx_endx at "
-                       "offset 0x%" PRIx32,
+                       "offset 0x%" PRIx64,
                        *OffsetPtr - 1);
   case dwarf::DW_RLE_startx_length: {
-    uint32_t PreviousOffset = *OffsetPtr - 1;
+    uint64_t PreviousOffset = *OffsetPtr - 1;
     Value0 = Data.getULEB128(OffsetPtr);
     Value1 = Data.getULEB128(OffsetPtr);
     if (End < *OffsetPtr)
       return createStringError(
           errc::invalid_argument,
           "read past end of table when reading "
-          "DW_RLE_startx_length encoding at offset 0x%" PRIx32,
+          "DW_RLE_startx_length encoding at offset 0x%" PRIx64,
           PreviousOffset);
     break;
   }
   case dwarf::DW_RLE_offset_pair: {
-    uint32_t PreviousOffset = *OffsetPtr - 1;
+    uint64_t PreviousOffset = *OffsetPtr - 1;
     Value0 = Data.getULEB128(OffsetPtr);
     Value1 = Data.getULEB128(OffsetPtr);
     if (End < *OffsetPtr)
       return createStringError(errc::invalid_argument,
                          "read past end of table when reading "
-                         "DW_RLE_offset_pair encoding at offset 0x%" PRIx32,
+                         "DW_RLE_offset_pair encoding at offset 0x%" PRIx64,
                          PreviousOffset);
     break;
   }
@@ -74,7 +74,7 @@
     if ((End - *OffsetPtr) < Data.getAddressSize())
       return createStringError(errc::invalid_argument,
                          "insufficient space remaining in table for "
-                         "DW_RLE_base_address encoding at offset 0x%" PRIx32,
+                         "DW_RLE_base_address encoding at offset 0x%" PRIx64,
                          *OffsetPtr - 1);
     Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
     break;
@@ -84,27 +84,27 @@
       return createStringError(errc::invalid_argument,
                          "insufficient space remaining in table for "
                          "DW_RLE_start_end encoding "
-                         "at offset 0x%" PRIx32,
+                         "at offset 0x%" PRIx64,
                          *OffsetPtr - 1);
     Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
     Value1 = Data.getRelocatedAddress(OffsetPtr);
     break;
   }
   case dwarf::DW_RLE_start_length: {
-    uint32_t PreviousOffset = *OffsetPtr - 1;
+    uint64_t PreviousOffset = *OffsetPtr - 1;
     Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
     Value1 = Data.getULEB128(OffsetPtr);
     if (End < *OffsetPtr)
       return createStringError(errc::invalid_argument,
                          "read past end of table when reading "
-                         "DW_RLE_start_length encoding at offset 0x%" PRIx32,
+                         "DW_RLE_start_length encoding at offset 0x%" PRIx64,
                          PreviousOffset);
     break;
   }
   default:
     return createStringError(errc::not_supported,
                        "unknown rnglists encoding 0x%" PRIx32
-                       " at offset 0x%" PRIx32,
+                       " at offset 0x%" PRIx64,
                        uint32_t(Encoding), *OffsetPtr - 1);
   }
 
@@ -114,12 +114,21 @@
 
 DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
     llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
+  return getAbsoluteRanges(BaseAddr, [&](uint32_t Index) {
+    return U.getAddrOffsetSectionItem(Index);
+  });
+}
+
+DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
+    Optional<object::SectionedAddress> BaseAddr,
+    function_ref<Optional<object::SectionedAddress>(uint32_t)>
+        LookupPooledAddress) const {
   DWARFAddressRangesVector Res;
   for (const RangeListEntry &RLE : Entries) {
     if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
       break;
     if (RLE.EntryKind == dwarf::DW_RLE_base_addressx) {
-      BaseAddr = U.getAddrOffsetSectionItem(RLE.Value0);
+      BaseAddr = LookupPooledAddress(RLE.Value0);
       if (!BaseAddr)
         BaseAddr = {RLE.Value0, -1ULL};
       continue;
@@ -152,7 +161,7 @@
       E.HighPC = E.LowPC + RLE.Value1;
       break;
     case dwarf::DW_RLE_startx_length: {
-      auto Start = U.getAddrOffsetSectionItem(RLE.Value0);
+      auto Start = LookupPooledAddress(RLE.Value0);
       if (!Start)
         Start = {0, -1ULL};
       E.SectionIndex = Start->SectionIndex;
@@ -187,7 +196,7 @@
 
   if (DumpOpts.Verbose) {
     // Print the section offset in verbose mode.
-    OS << format("0x%8.8" PRIx32 ":", Offset);
+    OS << format("0x%8.8" PRIx64 ":", Offset);
     auto EncodingString = dwarf::RangeListEncodingString(EntryKind);
     // Unsupported encodings should have been reported during parsing.
     assert(!EncodingString.empty() && "Unknown range entry encoding");
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index d638dc4..c1dc3b6 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -21,6 +21,7 @@
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/WithColor.h"
@@ -61,16 +62,10 @@
   if (!DumpOpts.ShowAddresses)
     return;
 
-  ArrayRef<SectionName> SectionNames;
-  if (DumpOpts.Verbose)
-    SectionNames = Obj.getSectionNames();
-
   for (const DWARFAddressRange &R : Ranges) {
     OS << '\n';
     OS.indent(Indent);
-    R.dump(OS, AddressSize);
-
-    DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, R.SectionIndex);
+    R.dump(OS, AddressSize, DumpOpts, &Obj);
   }
 }
 
@@ -78,7 +73,6 @@
                          DWARFUnit *U, unsigned Indent,
                          DIDumpOptions DumpOpts) {
   DWARFContext &Ctx = U->getContext();
-  const DWARFObject &Obj = Ctx.getDWARFObj();
   const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
   if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
       FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
@@ -90,51 +84,24 @@
     return;
   }
 
-  FormValue.dump(OS, DumpOpts);
   if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
-    uint32_t Offset = *FormValue.getAsSectionOffset();
-    if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
-      DWARFDebugLoc DebugLoc;
-      DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
-                              Obj.getAddressSize());
-      auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
-      if (LL) {
-        uint64_t BaseAddr = 0;
-        if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
-          BaseAddr = BA->Address;
-        LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
-                 BaseAddr, Indent);
-      } else
-        OS << "error extracting location list.";
-      return;
-    }
+    uint64_t Offset = *FormValue.getAsSectionOffset();
 
-    bool UseLocLists = !U->isDWOUnit();
-    StringRef LoclistsSectionData =
-        UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData();
+    if (FormValue.getForm() == DW_FORM_loclistx) {
+      FormValue.dump(OS, DumpOpts);
 
-    if (!LoclistsSectionData.empty()) {
-      DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
-                         Obj.getAddressSize());
-
-      // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
-      // Modern locations list (.debug_loclists) are used starting from v5.
-      // Ideally we should take the version from the .debug_loclists section
-      // header, but using CU's version for simplicity.
-      auto LL = DWARFDebugLoclists::parseOneLocationList(
-          Data, &Offset, UseLocLists ? U->getVersion() : 4);
-
-      uint64_t BaseAddr = 0;
-      if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
-        BaseAddr = BA->Address;
-
-      if (LL)
-        LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
-                 U, Indent);
+      if (auto LoclistOffset = U->getLoclistOffset(Offset))
+        Offset = *LoclistOffset;
       else
-        OS << "error extracting location list.";
+        return;
     }
+    U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
+                                           MRI, Ctx.getDWARFObj(), U, DumpOpts,
+                                           Indent);
+    return;
   }
+
+  FormValue.dump(OS, DumpOpts);
 }
 
 /// Dump the name encoded in the type tag.
@@ -264,7 +231,7 @@
 }
 
 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
-                          uint32_t *OffsetPtr, dwarf::Attribute Attr,
+                          uint64_t *OffsetPtr, dwarf::Attribute Attr,
                           dwarf::Form Form, unsigned Indent,
                           DIDumpOptions DumpOpts) {
   if (!Die.isValid())
@@ -312,7 +279,8 @@
       else
         FormValue.dump(OS, DumpOpts);
     }
-  } else if (DWARFAttribute::mayHaveLocationDescription(Attr))
+  } else if (Form == dwarf::Form::DW_FORM_exprloc ||
+             DWARFAttribute::mayHaveLocationDescription(Attr))
     dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
   else
     FormValue.dump(OS, DumpOpts);
@@ -442,6 +410,10 @@
   return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
 }
 
+Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
+  return toSectionOffset(find(DW_AT_loclists_base));
+}
+
 Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
   if (auto FormValue = find(DW_AT_high_pc)) {
     if (auto Address = FormValue->getAsAddress()) {
@@ -517,6 +489,37 @@
   return false;
 }
 
+Expected<DWARFLocationExpressionsVector>
+DWARFDie::getLocations(dwarf::Attribute Attr) const {
+  Optional<DWARFFormValue> Location = find(Attr);
+  if (!Location)
+    return createStringError(inconvertibleErrorCode(), "No %s",
+                             dwarf::AttributeString(Attr).data());
+
+  if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
+    uint64_t Offset = *Off;
+
+    if (Location->getForm() == DW_FORM_loclistx) {
+      if (auto LoclistOffset = U->getLoclistOffset(Offset))
+        Offset = *LoclistOffset;
+      else
+        return createStringError(inconvertibleErrorCode(),
+                                 "Loclist table not found");
+    }
+    return U->findLoclistFromOffset(Offset);
+  }
+
+  if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
+    return DWARFLocationExpressionsVector{
+        DWARFLocationExpression{None, to_vector<4>(*Expr)}};
+  }
+
+  return createStringError(
+      inconvertibleErrorCode(), "Unsupported %s encoding: %s",
+      dwarf::AttributeString(Attr).data(),
+      dwarf::FormEncodingString(Location->getForm()).data());
+}
+
 const char *DWARFDie::getSubroutineName(DINameKind Kind) const {
   if (!isSubroutineDIE())
     return nullptr;
@@ -568,8 +571,8 @@
   if (!isValid())
     return;
   DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
-  const uint32_t Offset = getOffset();
-  uint32_t offset = Offset;
+  const uint64_t Offset = getOffset();
+  uint64_t offset = Offset;
   if (DumpOpts.ShowParents) {
     DIDumpOptions ParentDumpOpts = DumpOpts;
     ParentDumpOpts.ShowParents = false;
@@ -581,7 +584,7 @@
     uint32_t abbrCode = debug_info_data.getULEB128(&offset);
     if (DumpOpts.ShowAddresses)
       WithColor(OS, HighlightColor::Address).get()
-          << format("\n0x%8.8x: ", Offset);
+          << format("\n0x%8.8" PRIx64 ": ", Offset);
 
     if (abbrCode) {
       auto AbbrevDecl = getAbbreviationDeclarationPtr();
@@ -685,7 +688,7 @@
     AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
     // Add the previous byte size of any previous attribute value.
     AttrValue.Offset += AttrValue.ByteSize;
-    uint32_t ParseOffset = AttrValue.Offset;
+    uint64_t ParseOffset = AttrValue.Offset;
     auto U = Die.getDwarfUnit();
     assert(U && "Die must have valid DWARF unit");
     AttrValue.Value = DWARFFormValue::createFromUnit(
@@ -733,6 +736,7 @@
   case DW_AT_call_data_value:
   // Extensions.
   case DW_AT_GNU_call_site_value:
+  case DW_AT_GNU_call_site_target:
     return true;
   default:
     return false;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index b182692..7d817d8 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -121,7 +121,7 @@
 }
 
 bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
-                                         uint8_t AddressSize, uint32_t Offset) {
+                                         uint8_t AddressSize, uint64_t Offset) {
   Opcode = Data.getU8(&Offset);
 
   Desc = getOpDesc(Opcode);
@@ -220,9 +220,8 @@
   else
     DwarfRegNum = Opcode - DW_OP_reg0;
 
-  int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH);
-  if (LLVMRegNum >= 0) {
-    if (const char *RegName = MRI->getName(LLVMRegNum)) {
+  if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
+    if (const char *RegName = MRI->getName(*LLVMRegNum)) {
       if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
           Opcode == DW_OP_bregx)
         OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
@@ -265,7 +264,7 @@
     if (Size == Operation::BaseTypeRef && U) {
       auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
       if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
-        OS << format(" (0x%08x)", U->getOffset() + Operands[Operand]);
+        OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
         if (auto Name = Die.find(dwarf::DW_AT_name))
           OS << " \"" << Name->getAsCString() << "\"";
       } else {
@@ -273,7 +272,7 @@
                      Operands[Operand]);
       }
     } else if (Size == Operation::SizeBlock) {
-      uint32_t Offset = Operands[Operand];
+      uint64_t Offset = Operands[Operand];
       for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
         OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
     } else {
@@ -292,7 +291,7 @@
   uint32_t EntryValExprSize = 0;
   for (auto &Op : *this) {
     if (!Op.print(OS, this, RegInfo, U, IsEH)) {
-      uint32_t FailOffset = Op.getEndOffset();
+      uint64_t FailOffset = Op.getEndOffset();
       while (FailOffset < Data.getData().size())
         OS << format(" %02x", Data.getU8(&FailOffset));
       return;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 290d355..e97ae81 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -98,7 +98,7 @@
 }
 
 DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
-                                              uint32_t *OffsetPtr) {
+                                              uint64_t *OffsetPtr) {
   DWARFFormValue FormValue(F);
   FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
                          U->getFormParams(), U);
@@ -106,7 +106,7 @@
 }
 
 bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
-                               uint32_t *OffsetPtr,
+                               uint64_t *OffsetPtr,
                                const dwarf::FormParams Params) {
   bool Indirect = false;
   do {
@@ -234,7 +234,7 @@
 }
 
 bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
-                                  uint32_t *OffsetPtr, dwarf::FormParams FP,
+                                  uint64_t *OffsetPtr, dwarf::FormParams FP,
                                   const DWARFContext *Ctx,
                                   const DWARFUnit *CU) {
   if (!Ctx && CU)
@@ -312,6 +312,7 @@
     case DW_FORM_udata:
     case DW_FORM_ref_udata:
     case DW_FORM_rnglistx:
+    case DW_FORM_loclistx:
       Value.uval = Data.getULEB128(OffsetPtr);
       break;
     case DW_FORM_string:
@@ -411,7 +412,7 @@
     if (A)
       dumpSectionedAddress(AddrOS, DumpOpts, *A);
     else
-      OS << "<no .debug_addr section>";
+      OS << "<unresolved>";
     break;
   }
   case DW_FORM_flag_present:
@@ -551,6 +552,10 @@
     OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
     break;
 
+  case DW_FORM_loclistx:
+    OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue);
+    break;
+
   // Should be formatted to 64-bit for DWARF64.
   case DW_FORM_sec_offset:
     AddrOS << format("0x%08x", (uint32_t)UValue);
@@ -590,7 +595,7 @@
   // FIXME: Add support for DW_FORM_GNU_strp_alt
   if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
     return None;
-  uint32_t Offset = Value.uval;
+  uint64_t Offset = Value.uval;
   if (Form == DW_FORM_line_strp) {
     // .debug_line_str is tracked in the Context.
     if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
@@ -624,6 +629,7 @@
     return SA->Address;
   return None;
 }
+
 Optional<object::SectionedAddress>
 DWARFFormValue::getAsSectionedAddress() const {
   if (!isFormClass(FC_Address))
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index f5f9755..252b58e 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -112,7 +112,7 @@
 }
 
 bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
 
   // Only version 7 is supported at this moment.
   Version = Data.getU32(&Offset);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
index e38e706..269ea9f 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -16,33 +16,42 @@
 using namespace llvm;
 
 Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
-                                    uint32_t *OffsetPtr) {
+                                    uint64_t *OffsetPtr) {
   HeaderOffset = *OffsetPtr;
   // Read and verify the length field.
   if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
     return createStringError(errc::invalid_argument,
                        "section is not large enough to contain a "
-                       "%s table length at offset 0x%" PRIx32,
+                       "%s table length at offset 0x%" PRIx64,
                        SectionName.data(), *OffsetPtr);
-  // TODO: Add support for DWARF64.
-  HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
-  if (HeaderData.Length == 0xffffffffu)
-    return createStringError(errc::not_supported,
-                       "DWARF64 is not supported in %s at offset 0x%" PRIx32,
-                       SectionName.data(), HeaderOffset);
   Format = dwarf::DwarfFormat::DWARF32;
-  if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
+  uint8_t OffsetByteSize = 4;
+  HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
+  if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
+    Format = dwarf::DwarfFormat::DWARF64;
+    OffsetByteSize = 8;
+    HeaderData.Length = Data.getU64(OffsetPtr);
+  } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
     return createStringError(errc::invalid_argument,
-                       "%s table at offset 0x%" PRIx32
-                       " has too small length (0x%" PRIx32
+        "%s table at offset 0x%" PRIx64
+        " has unsupported reserved unit length of value 0x%8.8" PRIx64,
+        SectionName.data(), HeaderOffset, HeaderData.Length);
+  }
+  uint64_t FullLength =
+      HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+  assert(FullLength == length());
+  if (FullLength < getHeaderSize(Format))
+    return createStringError(errc::invalid_argument,
+                       "%s table at offset 0x%" PRIx64
+                       " has too small length (0x%" PRIx64
                        ") to contain a complete header",
-                       SectionName.data(), HeaderOffset, length());
-  uint32_t End = HeaderOffset + length();
-  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
+                       SectionName.data(), HeaderOffset, FullLength);
+  uint64_t End = HeaderOffset + FullLength;
+  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
     return createStringError(errc::invalid_argument,
                        "section is not large enough to contain a %s table "
-                       "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
-                       SectionName.data(), length(), HeaderOffset);
+                       "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
+                       SectionName.data(), FullLength, HeaderOffset);
 
   HeaderData.Version = Data.getU16(OffsetPtr);
   HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -53,35 +62,35 @@
   if (HeaderData.Version != 5)
     return createStringError(errc::invalid_argument,
                        "unrecognised %s table version %" PRIu16
-                       " in table at offset 0x%" PRIx32,
+                       " in table at offset 0x%" PRIx64,
                        SectionName.data(), HeaderData.Version, HeaderOffset);
   if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
     return createStringError(errc::not_supported,
-                       "%s table at offset 0x%" PRIx32
+                       "%s table at offset 0x%" PRIx64
                        " has unsupported address size %" PRIu8,
                        SectionName.data(), HeaderOffset, HeaderData.AddrSize);
   if (HeaderData.SegSize != 0)
     return createStringError(errc::not_supported,
-                       "%s table at offset 0x%" PRIx32
+                       "%s table at offset 0x%" PRIx64
                        " has unsupported segment selector size %" PRIu8,
                        SectionName.data(), HeaderOffset, HeaderData.SegSize);
-  if (End < HeaderOffset + sizeof(HeaderData) +
-                HeaderData.OffsetEntryCount * sizeof(uint32_t))
+  if (End < HeaderOffset + getHeaderSize(Format) +
+                HeaderData.OffsetEntryCount * OffsetByteSize)
     return createStringError(errc::invalid_argument,
-        "%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32
+        "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
         ") than there is space for",
         SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
   Data.setAddressSize(HeaderData.AddrSize);
   for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
-    Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
+    Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
   return Error::success();
 }
 
 void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
   if (DumpOpts.Verbose)
-    OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
+    OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
   OS << format(
-      "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", "
+      "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", "
       "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
       ", offset_entry_count = "
       "0x%8.8" PRIx32 "\n",
@@ -91,18 +100,17 @@
   if (HeaderData.OffsetEntryCount > 0) {
     OS << "offsets: [";
     for (const auto &Off : Offsets) {
-      OS << format("\n0x%8.8" PRIx32, Off);
+      OS << format("\n0x%8.8" PRIx64, Off);
       if (DumpOpts.Verbose)
-        OS << format(" => 0x%8.8" PRIx32,
-                     Off + HeaderOffset + sizeof(HeaderData));
+        OS << format(" => 0x%8.8" PRIx64,
+                     Off + HeaderOffset + getHeaderSize(Format));
     }
     OS << "\n]\n";
   }
 }
 
-uint32_t DWARFListTableHeader::length() const {
+uint64_t DWARFListTableHeader::length() const {
   if (HeaderData.Length == 0)
     return 0;
-  // TODO: DWARF64 support.
-  return HeaderData.Length + sizeof(uint32_t);
+  return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp
new file mode 100644
index 0000000..1cf73a6
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp
@@ -0,0 +1,19 @@
+//===- DWARFLocationExpression.cpp ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+
+raw_ostream &llvm::operator<<(raw_ostream &OS,
+                              const DWARFLocationExpression &Loc) {
+  return OS << Loc.Range << ": "
+            << formatv("{0}", make_range(Loc.Expr.begin(), Loc.Expr.end()));
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index 844920b..bb81090 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -24,21 +24,23 @@
   if (DumpOpts.SummarizeTypes) {
     OS << "name = '" << Name << "'"
        << " type_signature = " << format("0x%016" PRIx64, getTypeHash())
-       << " length = " << format("0x%08x", getLength()) << '\n';
+       << " length = " << format("0x%08" PRIx64, getLength()) << '\n';
     return;
   }
 
-  OS << format("0x%08x", getOffset()) << ": Type Unit:"
-     << " length = " << format("0x%08x", getLength())
+  OS << format("0x%08" PRIx64, getOffset()) << ": Type Unit:"
+     << " length = " << format("0x%08" PRIx64, getLength())
      << " version = " << format("0x%04x", getVersion());
   if (getVersion() >= 5)
     OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
-  OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
+  OS << " abbr_offset = "
+     << format("0x%04" PRIx64, getAbbreviations()->getOffset())
      << " addr_size = " << format("0x%02x", getAddressByteSize())
      << " name = '" << Name << "'"
      << " type_signature = " << format("0x%016" PRIx64, getTypeHash())
-     << " type_offset = " << format("0x%04x", getTypeOffset())
-     << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
+     << " type_offset = " << format("0x%04" PRIx64, getTypeOffset())
+     << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+     << ")\n";
 
   if (DWARFDie TU = getUnitDIE(false))
     TU.dump(OS, 0, DumpOpts);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index b74acf6..7bb0194 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -37,9 +37,9 @@
                                          const DWARFSection &Section,
                                          DWARFSectionKind SectionKind) {
   const DWARFObject &D = C.getDWARFObj();
-  addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
-               &D.getLocSection(), D.getStringSection(),
-               D.getStringOffsetSection(), &D.getAddrSection(),
+  addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
+               &D.getLocSection(), D.getStrSection(),
+               D.getStrOffsetsSection(), &D.getAddrSection(),
                D.getLineSection(), D.isLittleEndian(), false, false,
                SectionKind);
 }
@@ -49,9 +49,9 @@
                                             DWARFSectionKind SectionKind,
                                             bool Lazy) {
   const DWARFObject &D = C.getDWARFObj();
-  addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
-               &D.getLocDWOSection(), D.getStringDWOSection(),
-               D.getStringOffsetDWOSection(), &D.getAddrSection(),
+  addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
+               &D.getLocDWOSection(), D.getStrDWOSection(),
+               D.getStrOffsetsDWOSection(), &D.getAddrSection(),
                D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
                SectionKind);
 }
@@ -66,7 +66,7 @@
   // Lazy initialization of Parser, now that we have all section info.
   if (!Parser) {
     Parser = [=, &Context, &Obj, &Section, &SOS,
-              &LS](uint32_t Offset, DWARFSectionKind SectionKind,
+              &LS](uint64_t Offset, DWARFSectionKind SectionKind,
                    const DWARFSection *CurSection,
                    const DWARFUnitIndex::Entry *IndexEntry)
         -> std::unique_ptr<DWARFUnit> {
@@ -83,11 +83,11 @@
         return nullptr;
       std::unique_ptr<DWARFUnit> U;
       if (Header.isTypeUnit())
-        U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
+        U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
                                              RS, LocSection, SS, SOS, AOS, LS,
                                              LE, IsDWO, *this);
       else
-        U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
+        U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
                                                 DA, RS, LocSection, SS, SOS,
                                                 AOS, LS, LE, IsDWO, *this);
       return U;
@@ -101,7 +101,7 @@
   // within a section, although not necessarily within the object file,
   // even if we do lazy parsing.
   auto I = this->begin();
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   while (Data.isValidOffset(Offset)) {
     if (I != this->end() &&
         (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
@@ -126,11 +126,11 @@
   return this->insert(I, std::move(Unit))->get();
 }
 
-DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const {
+DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
   auto end = begin() + getNumInfoUnits();
   auto *CU =
       std::upper_bound(begin(), end, Offset,
-                       [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+                       [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
                          return LHS < RHS->getNextUnitOffset();
                        });
   if (CU != end && (*CU)->getOffset() <= Offset)
@@ -149,7 +149,7 @@
 
   auto *CU =
       std::upper_bound(begin(), end, CUOff->Offset,
-                       [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+                       [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
                          return LHS < RHS->getNextUnitOffset();
                        });
   if (CU != end && (*CU)->getOffset() <= Offset)
@@ -175,18 +175,37 @@
                      const DWARFSection *AOS, const DWARFSection &LS, bool LE,
                      bool IsDWO, const DWARFUnitVector &UnitVector)
     : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
-      RangeSection(RS), LocSection(LocSection), LineSection(LS),
-      StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
-      isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) {
+      RangeSection(RS), LineSection(LS), StringSection(SS),
+      StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
+      IsDWO(IsDWO), UnitVector(UnitVector) {
   clear();
-  // For split DWARF we only need to keep track of the location list section's
-  // data (no relocations), and if we are reading a package file, we need to
-  // adjust the location list data based on the index entries.
   if (IsDWO) {
-    LocSectionData = LocSection->Data;
+    // If we are reading a package file, we need to adjust the location list
+    // data based on the index entries.
+    StringRef Data = LocSection->Data;
     if (auto *IndexEntry = Header.getIndexEntry())
       if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
-        LocSectionData = LocSectionData.substr(C->Offset, C->Length);
+        Data = Data.substr(C->Offset, C->Length);
+
+    DWARFDataExtractor DWARFData =
+        Header.getVersion() >= 5
+            ? DWARFDataExtractor(Context.getDWARFObj(),
+                                 Context.getDWARFObj().getLoclistsDWOSection(),
+                                 isLittleEndian, getAddressByteSize())
+            : DWARFDataExtractor(Data, isLittleEndian, getAddressByteSize());
+    LocTable =
+        std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
+
+  } else if (Header.getVersion() >= 5) {
+    LocTable = std::make_unique<DWARFDebugLoclists>(
+        DWARFDataExtractor(Context.getDWARFObj(),
+                           Context.getDWARFObj().getLoclistsSection(),
+                           isLittleEndian, getAddressByteSize()),
+        Header.getVersion());
+  } else {
+    LocTable = std::make_unique<DWARFDebugLoc>(
+        DWARFDataExtractor(Context.getDWARFObj(), *LocSection, isLittleEndian,
+                           getAddressByteSize()));
   }
 }
 
@@ -209,7 +228,9 @@
     if (I != R.end() && std::next(I) == R.end())
       return (*I)->getAddrOffsetSectionItem(Index);
   }
-  uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
+  if (!AddrOffsetSectionBase)
+    return None;
+  uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize();
   if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
     return None;
   DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
@@ -223,7 +244,7 @@
   if (!StringOffsetsTableContribution)
     return None;
   unsigned ItemSize = getDwarfStringOffsetsByteSize();
-  uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
+  uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
   if (StringOffsetSection.Data.size() < Offset + ItemSize)
     return None;
   DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
@@ -233,30 +254,31 @@
 
 bool DWARFUnitHeader::extract(DWARFContext &Context,
                               const DWARFDataExtractor &debug_info,
-                              uint32_t *offset_ptr,
+                              uint64_t *offset_ptr,
                               DWARFSectionKind SectionKind,
                               const DWARFUnitIndex *Index,
                               const DWARFUnitIndex::Entry *Entry) {
   Offset = *offset_ptr;
+  Error Err = Error::success();
   IndexEntry = Entry;
   if (!IndexEntry && Index)
     IndexEntry = Index->getFromOffset(*offset_ptr);
-  Length = debug_info.getRelocatedValue(4, offset_ptr);
+  Length = debug_info.getRelocatedValue(4, offset_ptr, nullptr, &Err);
   FormParams.Format = DWARF32;
-  unsigned SizeOfLength = 4;
-  if (Length == 0xffffffff) {
-    Length = debug_info.getU64(offset_ptr);
+  if (Length == dwarf::DW_LENGTH_DWARF64) {
+    Length = debug_info.getU64(offset_ptr, &Err);
     FormParams.Format = DWARF64;
-    SizeOfLength = 8;
   }
-  FormParams.Version = debug_info.getU16(offset_ptr);
+  FormParams.Version = debug_info.getU16(offset_ptr, &Err);
   if (FormParams.Version >= 5) {
-    UnitType = debug_info.getU8(offset_ptr);
-    FormParams.AddrSize = debug_info.getU8(offset_ptr);
-    AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
+    UnitType = debug_info.getU8(offset_ptr, &Err);
+    FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
+    AbbrOffset = debug_info.getRelocatedValue(
+        FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
   } else {
-    AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
-    FormParams.AddrSize = debug_info.getU8(offset_ptr);
+    AbbrOffset = debug_info.getRelocatedValue(
+        FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
+    FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
     // Fake a unit type based on the section type.  This isn't perfect,
     // but distinguishing compile and type units is generally enough.
     if (SectionKind == DW_SECT_TYPES)
@@ -276,10 +298,14 @@
     AbbrOffset = AbbrEntry->Offset;
   }
   if (isTypeUnit()) {
-    TypeHash = debug_info.getU64(offset_ptr);
-    TypeOffset = debug_info.getU32(offset_ptr);
+    TypeHash = debug_info.getU64(offset_ptr, &Err);
+    TypeOffset = debug_info.getUnsigned(
+        offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
   } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
-    DWOId = debug_info.getU64(offset_ptr);
+    DWOId = debug_info.getU64(offset_ptr, &Err);
+
+  if (errorToBool(std::move(Err)))
+    return false;
 
   // Header fields all parsed, capture the size of this unit header.
   assert(*offset_ptr - Offset <= 255 && "unexpected header size");
@@ -290,7 +316,8 @@
   bool TypeOffsetOK =
       !isTypeUnit()
           ? true
-          : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
+          : TypeOffset >= Size &&
+                TypeOffset < getLength() + getUnitLengthFieldByteSize();
   bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
   bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
   bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
@@ -305,31 +332,34 @@
 
 // Parse the rangelist table header, including the optional array of offsets
 // following it (DWARF v5 and later).
-static Expected<DWARFDebugRnglistTable>
-parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
-  // TODO: Support DWARF64
+template<typename ListTableType>
+static Expected<ListTableType>
+parseListTableHeader(DWARFDataExtractor &DA, uint64_t Offset,
+                        DwarfFormat Format) {
   // We are expected to be called with Offset 0 or pointing just past the table
-  // header, which is 12 bytes long for DWARF32.
+  // header. Correct Offset in the latter case so that it points to the start
+  // of the header.
   if (Offset > 0) {
-    if (Offset < 12U)
-      return createStringError(errc::invalid_argument, "Did not detect a valid"
-                               " range list table with base = 0x%" PRIu32,
+    uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Format);
+    if (Offset < HeaderSize)
+      return createStringError(errc::invalid_argument, "did not detect a valid"
+                               " list table with base = 0x%" PRIx64 "\n",
                                Offset);
-    Offset -= 12U;
+    Offset -= HeaderSize;
   }
-  llvm::DWARFDebugRnglistTable Table;
+  ListTableType Table;
   if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
     return std::move(E);
   return Table;
 }
 
-Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
+Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
                                   DWARFDebugRangeList &RangeList) const {
   // Require that compile unit is extracted.
   assert(!DieArray.empty());
   DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
                                 isLittleEndian, getAddressByteSize());
-  uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
+  uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
   return RangeList.extract(RangesData, &ActualRangeListOffset);
 }
 
@@ -337,7 +367,8 @@
   Abbrevs = nullptr;
   BaseAddr.reset();
   RangeSectionBase = 0;
-  AddrOffsetSectionBase = 0;
+  LocSectionBase = 0;
+  AddrOffsetSectionBase = None;
   clearDIEs(false);
   DWO.reset();
 }
@@ -354,8 +385,8 @@
 
   // Set the offset to that of the first DIE and calculate the start of the
   // next compilation unit header.
-  uint32_t DIEOffset = getOffset() + getHeaderSize();
-  uint32_t NextCUOffset = getNextUnitOffset();
+  uint64_t DIEOffset = getOffset() + getHeaderSize();
+  uint64_t NextCUOffset = getNextUnitOffset();
   DWARFDebugInfoEntry DIE;
   DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
   uint32_t Depth = 0;
@@ -396,90 +427,131 @@
   // unit header).
   if (DIEOffset > NextCUOffset)
     WithColor::warning() << format("DWARF compile unit extends beyond its "
-                                   "bounds cu 0x%8.8x at 0x%8.8x\n",
+                                   "bounds cu 0x%8.8" PRIx64 " "
+                                   "at 0x%8.8" PRIx64 "\n",
                                    getOffset(), DIEOffset);
 }
 
-size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+  if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
+    WithColor::error() << toString(std::move(e));
+}
+
+Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
   if ((CUDieOnly && !DieArray.empty()) ||
       DieArray.size() > 1)
-    return 0; // Already parsed.
+    return Error::success(); // Already parsed.
 
   bool HasCUDie = !DieArray.empty();
   extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
 
   if (DieArray.empty())
-    return 0;
+    return Error::success();
 
   // If CU DIE was just parsed, copy several attribute values from it.
-  if (!HasCUDie) {
-    DWARFDie UnitDie = getUnitDIE();
-    if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
-      Header.setDWOId(*DWOId);
-    if (!IsDWO) {
-      assert(AddrOffsetSectionBase == 0);
-      assert(RangeSectionBase == 0);
-      AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
-      if (!AddrOffsetSectionBase)
-        AddrOffsetSectionBase =
-            toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
-      RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+  if (HasCUDie)
+    return Error::success();
+
+  DWARFDie UnitDie(this, &DieArray[0]);
+  if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
+    Header.setDWOId(*DWOId);
+  if (!IsDWO) {
+    assert(AddrOffsetSectionBase == None);
+    assert(RangeSectionBase == 0);
+    assert(LocSectionBase == 0);
+    AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
+    if (!AddrOffsetSectionBase)
+      AddrOffsetSectionBase =
+          toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
+    RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+    LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
+  }
+
+  // In general, in DWARF v5 and beyond we derive the start of the unit's
+  // contribution to the string offsets table from the unit DIE's
+  // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
+  // attribute, so we assume that there is a contribution to the string
+  // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
+  // In both cases we need to determine the format of the contribution,
+  // which may differ from the unit's format.
+  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+                        isLittleEndian, 0);
+  if (IsDWO || getVersion() >= 5) {
+    auto StringOffsetOrError =
+        IsDWO ? determineStringOffsetsTableContributionDWO(DA)
+              : determineStringOffsetsTableContribution(DA);
+    if (!StringOffsetOrError)
+      return createStringError(errc::invalid_argument,
+                               "invalid reference to or invalid content in "
+                               ".debug_str_offsets[.dwo]: " +
+                                   toString(StringOffsetOrError.takeError()));
+
+    StringOffsetsTableContribution = *StringOffsetOrError;
+  }
+
+  // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
+  // describe address ranges.
+  if (getVersion() >= 5) {
+    if (IsDWO)
+      setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
+    else
+      setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
+                       toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
+    if (RangeSection->Data.size()) {
+      // Parse the range list table header. Individual range lists are
+      // extracted lazily.
+      DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
+                                  isLittleEndian, 0);
+      auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
+          RangesDA, RangeSectionBase, Header.getFormat());
+      if (!TableOrError)
+        return createStringError(errc::invalid_argument,
+                                 "parsing a range list table: " +
+                                     toString(TableOrError.takeError()));
+
+      RngListTable = TableOrError.get();
+
+      // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
+      // Adjust RangeSectionBase to point past the table header.
+      if (IsDWO && RngListTable)
+        RangeSectionBase = RngListTable->getHeaderSize();
     }
 
-    // In general, in DWARF v5 and beyond we derive the start of the unit's
-    // contribution to the string offsets table from the unit DIE's
-    // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
-    // attribute, so we assume that there is a contribution to the string
-    // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
-    // In both cases we need to determine the format of the contribution,
-    // which may differ from the unit's format.
-    DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
-                          isLittleEndian, 0);
-    if (IsDWO || getVersion() >= 5) {
-      auto StringOffsetOrError =
-          IsDWO ? determineStringOffsetsTableContributionDWO(DA)
-                : determineStringOffsetsTableContribution(DA);
-      if (!StringOffsetOrError) {
-        WithColor::error() << "invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: "
-                           << toString(StringOffsetOrError.takeError()) << '\n';
-      } else {
-        StringOffsetsTableContribution = *StringOffsetOrError;
-      }
-    }
+    // In a split dwarf unit, there is no DW_AT_loclists_base attribute.
+    // Setting LocSectionBase to point past the table header.
+    if (IsDWO)
+      setLocSection(&Context.getDWARFObj().getLoclistsDWOSection(),
+                    DWARFListTableHeader::getHeaderSize(Header.getFormat()));
+    else
+      setLocSection(&Context.getDWARFObj().getLoclistsSection(),
+                    toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0));
 
-    // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
-    // describe address ranges.
-    if (getVersion() >= 5) {
+    if (LocSection->Data.size()) {
       if (IsDWO)
-        setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
+        LoclistTableHeader.emplace(".debug_loclists.dwo", "locations");
       else
-        setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
-                         toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
-      if (RangeSection->Data.size()) {
-        // Parse the range list table header. Individual range lists are
-        // extracted lazily.
-        DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
-                                    isLittleEndian, 0);
-        if (auto TableOrError =
-                parseRngListTableHeader(RangesDA, RangeSectionBase))
-          RngListTable = TableOrError.get();
-        else
-          WithColor::error() << "parsing a range list table: "
-                             << toString(TableOrError.takeError())
-                             << '\n';
+        LoclistTableHeader.emplace(".debug_loclists", "locations");
 
-        // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
-        // Adjust RangeSectionBase to point past the table header.
-        if (IsDWO && RngListTable)
-          RangeSectionBase = RngListTable->getHeaderSize();
-      }
+      uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat());
+      uint64_t Offset = getLocSectionBase();
+      DWARFDataExtractor Data(Context.getDWARFObj(), *LocSection,
+                              isLittleEndian, getAddressByteSize());
+      if (Offset < HeaderSize)
+        return createStringError(errc::invalid_argument,
+                                 "did not detect a valid"
+                                 " list table with base = 0x%" PRIx64 "\n",
+                                 Offset);
+      Offset -= HeaderSize;
+      if (Error E = LoclistTableHeader->extract(Data, &Offset))
+        return createStringError(errc::invalid_argument,
+                                 "parsing a loclist table: " +
+                                     toString(std::move(E)));
     }
+  }
 
-    // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
-    // skeleton CU DIE, so that DWARF users not aware of it are not broken.
-    }
-
-  return DieArray.size();
+  // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
+  // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+  return Error::success();
 }
 
 bool DWARFUnit::parseDWO() {
@@ -490,7 +562,9 @@
   DWARFDie UnitDie = getUnitDIE();
   if (!UnitDie)
     return false;
-  auto DWOFileName = dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
+  auto DWOFileName = getVersion() >= 5
+                         ? dwarf::toString(UnitDie.find(DW_AT_dwo_name))
+                         : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
   if (!DWOFileName)
     return false;
   auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
@@ -512,12 +586,14 @@
     return false;
   DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
   // Share .debug_addr and .debug_ranges section with compile unit in .dwo
-  DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
+  if (AddrOffsetSectionBase)
+    DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
   if (getVersion() >= 5) {
     DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
     DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
                                 isLittleEndian, 0);
-    if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
+    if (auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
+            RangesDA, RangeSectionBase, Header.getFormat()))
       DWO->RngListTable = TableOrError.get();
     else
       WithColor::error() << "parsing a range list table: "
@@ -541,7 +617,7 @@
 }
 
 Expected<DWARFAddressRangesVector>
-DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
+DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
   if (getVersion() <= 4) {
     DWARFDebugRangeList RangeList;
     if (Error E = extractRangeList(Offset, RangeList))
@@ -564,14 +640,14 @@
 Expected<DWARFAddressRangesVector>
 DWARFUnit::findRnglistFromIndex(uint32_t Index) {
   if (auto Offset = getRnglistOffset(Index))
-    return findRnglistFromOffset(*Offset + RangeSectionBase);
+    return findRnglistFromOffset(*Offset);
 
   if (RngListTable)
     return createStringError(errc::invalid_argument,
                              "invalid range list table index %d", Index);
-  else
-    return createStringError(errc::invalid_argument,
-                             "missing or invalid range list table");
+
+  return createStringError(errc::invalid_argument,
+                           "missing or invalid range list table");
 }
 
 Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
@@ -588,6 +664,30 @@
   return *CUDIERangesOrError;
 }
 
+Expected<DWARFLocationExpressionsVector>
+DWARFUnit::findLoclistFromOffset(uint64_t Offset) {
+  DWARFLocationExpressionsVector Result;
+
+  Error InterpretationError = Error::success();
+
+  Error ParseError = getLocationTable().visitAbsoluteLocationList(
+      Offset, getBaseAddress(),
+      [this](uint32_t Index) { return getAddrOffsetSectionItem(Index); },
+      [&](Expected<DWARFLocationExpression> L) {
+        if (L)
+          Result.push_back(std::move(*L));
+        else
+          InterpretationError =
+              joinErrors(L.takeError(), std::move(InterpretationError));
+        return !InterpretationError;
+      });
+
+  if (ParseError || InterpretationError)
+    return joinErrors(std::move(ParseError), std::move(InterpretationError));
+
+  return Result;
+}
+
 void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
   if (Die.isSubroutineDIE()) {
     auto DIERangesOrError = Die.getAddressRanges();
@@ -780,11 +880,11 @@
 // Look for a DWARF64-formatted contribution to the string offsets table
 // starting at a given offset and record it in a descriptor.
 static Expected<StrOffsetsContributionDescriptor>
-parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
   if (!DA.isValidOffsetForDataOfSize(Offset, 16))
     return createStringError(errc::invalid_argument, "section offset exceeds section size");
 
-  if (DA.getU32(&Offset) != 0xffffffff)
+  if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
     return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
 
   uint64_t Size = DA.getU64(&Offset);
@@ -798,12 +898,12 @@
 // Look for a DWARF32-formatted contribution to the string offsets table
 // starting at a given offset and record it in a descriptor.
 static Expected<StrOffsetsContributionDescriptor>
-parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
   if (!DA.isValidOffsetForDataOfSize(Offset, 8))
     return createStringError(errc::invalid_argument, "section offset exceeds section size");
 
   uint32_t ContributionSize = DA.getU32(&Offset);
-  if (ContributionSize >= 0xfffffff0)
+  if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
     return createStringError(errc::invalid_argument, "invalid length");
 
   uint8_t Version = DA.getU16(&Offset);
@@ -823,7 +923,7 @@
   case dwarf::DwarfFormat::DWARF64: {
     if (Offset < 16)
       return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
-    auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16);
+    auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16);
     if (!DescOrError)
       return DescOrError.takeError();
     Desc = *DescOrError;
@@ -832,7 +932,7 @@
   case dwarf::DwarfFormat::DWARF32: {
     if (Offset < 8)
       return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
-    auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
+    auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8);
     if (!DescOrError)
       return DescOrError.takeError();
     Desc = *DescOrError;
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index 047c634..f29c1e6 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -18,7 +18,7 @@
 using namespace llvm;
 
 bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
-                                   uint32_t *OffsetPtr) {
+                                   uint64_t *OffsetPtr) {
   if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
     return false;
   Version = IndexData.getU32(OffsetPtr);
@@ -45,7 +45,7 @@
 }
 
 bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   if (!Header.parse(IndexData, &Offset))
     return false;
 
@@ -54,10 +54,10 @@
                       (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
     return false;
 
-  Rows = llvm::make_unique<Entry[]>(Header.NumBuckets);
+  Rows = std::make_unique<Entry[]>(Header.NumBuckets);
   auto Contribs =
-      llvm::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
-  ColumnKinds = llvm::make_unique<DWARFSectionKind[]>(Header.NumColumns);
+      std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
+  ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
 
   // Read Hash Table of Signatures
   for (unsigned i = 0; i != Header.NumBuckets; ++i)
@@ -70,7 +70,7 @@
       continue;
     Rows[i].Index = this;
     Rows[i].Contributions =
-        llvm::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
+        std::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
     Contribs[Index - 1] = Rows[i].Contributions.get();
   }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index c2b3189..1fd6c1d 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -34,11 +34,11 @@
 
   if (Pos != End) {
     if (Pos->intersects(R))
-      return Pos;
+      return std::move(Pos);
     if (Pos != Begin) {
       auto Iter = Pos - 1;
       if (Iter->intersects(R))
-        return Iter;
+        return std::move(Iter);
     }
   }
 
@@ -98,7 +98,7 @@
 }
 
 bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
-                                     uint32_t *Offset, unsigned UnitIndex,
+                                     uint64_t *Offset, unsigned UnitIndex,
                                      uint8_t &UnitType, bool &isUnitDWARF64) {
   uint64_t AbbrOffset, Length;
   uint8_t AddrSize = 0;
@@ -111,9 +111,9 @@
   bool ValidType = true;
   bool ValidAbbrevOffset = true;
 
-  uint32_t OffsetStart = *Offset;
+  uint64_t OffsetStart = *Offset;
   Length = DebugInfoData.getU32(Offset);
-  if (Length == UINT32_MAX) {
+  if (Length == dwarf::DW_LENGTH_DWARF64) {
     Length = DebugInfoData.getU64(Offset);
     isUnitDWARF64 = true;
   }
@@ -139,7 +139,7 @@
   if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
       !ValidType) {
     Success = false;
-    error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
+    error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
                       OffsetStart);
     if (!ValidLength)
       note() << "The length for this unit is too "
@@ -196,6 +196,14 @@
     NumUnitErrors++;
   }
 
+  //  According to DWARF Debugging Information Format Version 5,
+  //  3.1.2 Skeleton Compilation Unit Entries:
+  //  "A skeleton compilation unit has no children."
+  if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
+    error() << "Skeleton compilation unit has children.\n";
+    NumUnitErrors++;
+  }
+
   DieRangeInfo RI;
   NumUnitErrors += verifyDieRanges(Die, RI);
 
@@ -203,7 +211,7 @@
 }
 
 unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
-  if (Die.getTag() != DW_TAG_call_site)
+  if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
     return 0;
 
   DWARFDie Curr = Die.getParent();
@@ -223,7 +231,9 @@
 
   Optional<DWARFFormValue> CallAttr =
       Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
-                 DW_AT_call_all_tail_calls});
+                 DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
+                 DW_AT_GNU_all_source_call_sites,
+                 DW_AT_GNU_all_tail_call_sites});
   if (!CallAttr) {
     error() << "Subprogram with call site entry has no DW_AT_call attribute:";
     Curr.dump(OS);
@@ -273,7 +283,7 @@
   const DWARFObject &DObj = DCtx.getDWARFObj();
   DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
   unsigned NumDebugInfoErrors = 0;
-  uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
+  uint64_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
   uint8_t UnitType = 0;
   bool isUnitDWARF64 = false;
   bool isHeaderChainValid = true;
@@ -294,10 +304,10 @@
       switch (UnitType) {
       case dwarf::DW_UT_type:
       case dwarf::DW_UT_split_type: {
-        Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>(
-            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
-            &DObj.getLocSection(), DObj.getStringSection(),
-            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+        Unit = TypeUnitVector.addUnit(std::make_unique<DWARFTypeUnit>(
+            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+            &DObj.getLocSection(), DObj.getStrSection(),
+            DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(),
             DObj.getLineSection(), DCtx.isLittleEndian(), false,
             TypeUnitVector));
         break;
@@ -308,10 +318,10 @@
       case dwarf::DW_UT_partial:
       // UnitType = 0 means that we are verifying a compile unit in DWARF v4.
       case 0: {
-        Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>(
-            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
-            &DObj.getLocSection(), DObj.getStringSection(),
-            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+        Unit = CompileUnitVector.addUnit(std::make_unique<DWARFCompileUnit>(
+            DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+            &DObj.getLocSection(), DObj.getStrSection(),
+            DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(),
             DObj.getLineSection(), DCtx.isLittleEndian(), false,
             CompileUnitVector));
         break;
@@ -449,7 +459,7 @@
   case DW_AT_ranges:
     // Make sure the offset in the DW_AT_ranges attribute is valid.
     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
-      if (*SectionOffset >= DObj.getRangeSection().Data.size())
+      if (*SectionOffset >= DObj.getRangesSection().Data.size())
         ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:");
       break;
     }
@@ -466,27 +476,21 @@
     ReportError("DIE has invalid DW_AT_stmt_list encoding:");
     break;
   case DW_AT_location: {
-    auto VerifyLocationExpr = [&](StringRef D) {
+    if (Expected<std::vector<DWARFLocationExpression>> Loc =
+            Die.getLocations(DW_AT_location)) {
       DWARFUnit *U = Die.getDwarfUnit();
-      DataExtractor Data(D, DCtx.isLittleEndian(), 0);
-      DWARFExpression Expression(Data, U->getVersion(),
-                                 U->getAddressByteSize());
-      bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
-        return Op.isError();
-      });
-      if (Error || !Expression.verify(U))
-        ReportError("DIE contains invalid DWARF expression:");
-    };
-    if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
-      // Verify inlined location.
-      VerifyLocationExpr(llvm::toStringRef(*Expr));
-    } else if (auto LocOffset = AttrValue.Value.getAsSectionOffset()) {
-      // Verify location list.
-      if (auto DebugLoc = DCtx.getDebugLoc())
-        if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset))
-          for (const auto &Entry : LocList->Entries)
-            VerifyLocationExpr({Entry.Loc.data(), Entry.Loc.size()});
-    }
+      for (const auto &Entry : *Loc) {
+        DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
+        DWARFExpression Expression(Data, U->getVersion(),
+                                   U->getAddressByteSize());
+        bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) {
+          return Op.isError();
+        });
+        if (Error || !Expression.verify(U))
+          ReportError("DIE contains invalid DWARF expression:");
+      }
+    } else
+      ReportError(toString(Loc.takeError()));
     break;
   }
   case DW_AT_specification:
@@ -500,6 +504,9 @@
         break;
       if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
         break;
+      // This might be reference to a function declaration.
+      if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
+        break;
       ReportError("DIE with tag " + TagString(DieTag) + " has " +
                   AttributeString(Attr) +
                   " that points to DIE with "
@@ -545,7 +552,7 @@
         error() << FormEncodingString(Form) << " CU offset "
                 << format("0x%08" PRIx64, CUOffset)
                 << " is invalid (must be less than CU size of "
-                << format("0x%08" PRIx32, CUSize) << "):\n";
+                << format("0x%08" PRIx64, CUSize) << "):\n";
         Die.dump(OS, 0, DumpOpts);
         dump(Die) << '\n';
       } else {
@@ -578,7 +585,7 @@
   case DW_FORM_strp: {
     auto SecOffset = AttrValue.Value.getAsSectionOffset();
     assert(SecOffset); // DW_FORM_strp is a section offset.
-    if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
+    if (SecOffset && *SecOffset >= DObj.getStrSection().size()) {
       ++NumErrors;
       error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
       dump(Die) << '\n';
@@ -605,7 +612,7 @@
     // Use a 64-bit type to calculate the offset to guard against overflow.
     uint64_t Offset =
         (uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
-    if (DObj.getStringOffsetSection().Data.size() < Offset + ItemSize) {
+    if (DObj.getStrOffsetsSection().Data.size() < Offset + ItemSize) {
       ++NumErrors;
       error() << FormEncodingString(Form) << " uses index "
               << format("%" PRIu64, Index) << ", which is too large:\n";
@@ -614,7 +621,7 @@
     }
     // Check that the string offset is valid.
     uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
-    if (StringOffset >= DObj.getStringSection().size()) {
+    if (StringOffset >= DObj.getStrSection().size()) {
       ++NumErrors;
       error() << FormEncodingString(Form) << " uses index "
               << format("%" PRIu64, Index)
@@ -635,7 +642,7 @@
   // getting the DIE by offset and emitting an error
   OS << "Verifying .debug_info references...\n";
   unsigned NumErrors = 0;
-  for (const std::pair<uint64_t, std::set<uint32_t>> &Pair :
+  for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
        ReferenceToDIEOffsets) {
     if (DCtx.getDIEForOffset(Pair.first))
       continue;
@@ -659,12 +666,12 @@
     auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
     if (!StmtSectionOffset)
       continue;
-    const uint32_t LineTableOffset = *StmtSectionOffset;
+    const uint64_t LineTableOffset = *StmtSectionOffset;
     auto LineTable = DCtx.getLineTableForUnit(CU.get());
     if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
       if (!LineTable) {
         ++NumDebugLineErrors;
-        error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset)
+        error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
                 << "] was not able to be parsed for CU:\n";
         dump(Die) << '\n';
         continue;
@@ -680,8 +687,8 @@
     if (Iter != StmtListToDie.end()) {
       ++NumDebugLineErrors;
       error() << "two compile unit DIEs, "
-              << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
-              << format("0x%08" PRIx32, Die.getOffset())
+              << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
+              << format("0x%08" PRIx64, Die.getOffset())
               << ", have the same DW_AT_stmt_list section offset:\n";
       dump(Iter->second);
       dump(Die) << '\n';
@@ -826,10 +833,10 @@
   uint32_t NumBuckets = AccelTable.getNumBuckets();
   uint32_t NumHashes = AccelTable.getNumHashes();
 
-  uint32_t BucketsOffset =
+  uint64_t BucketsOffset =
       AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
-  uint32_t HashesBase = BucketsOffset + NumBuckets * 4;
-  uint32_t OffsetsBase = HashesBase + NumHashes * 4;
+  uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
+  uint64_t OffsetsBase = HashesBase + NumHashes * 4;
   for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
     uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
     if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
@@ -849,28 +856,29 @@
   }
 
   for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
-    uint32_t HashOffset = HashesBase + 4 * HashIdx;
-    uint32_t DataOffset = OffsetsBase + 4 * HashIdx;
+    uint64_t HashOffset = HashesBase + 4 * HashIdx;
+    uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
     uint32_t Hash = AccelSectionData.getU32(&HashOffset);
-    uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
+    uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
     if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
                                                      sizeof(uint64_t))) {
-      error() << format("Hash[%d] has invalid HashData offset: 0x%08x.\n",
+      error() << format("Hash[%d] has invalid HashData offset: "
+                        "0x%08" PRIx64 ".\n",
                         HashIdx, HashDataOffset);
       ++NumErrors;
     }
 
-    uint32_t StrpOffset;
-    uint32_t StringOffset;
+    uint64_t StrpOffset;
+    uint64_t StringOffset;
     uint32_t StringCount = 0;
-    unsigned Offset;
+    uint64_t Offset;
     unsigned Tag;
     while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
       const uint32_t NumHashDataObjects =
           AccelSectionData.getU32(&HashDataOffset);
       for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
            ++HashDataIdx) {
-        std::tie(Offset, Tag) = AccelTable.readAtoms(HashDataOffset);
+        std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
         auto Die = DCtx.getDIEForOffset(Offset);
         if (!Die) {
           const uint32_t BucketIdx =
@@ -882,8 +890,8 @@
 
           error() << format(
               "%s Bucket[%d] Hash[%d] = 0x%08x "
-              "Str[%u] = 0x%08x "
-              "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
+              "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
+              "is not a valid DIE offset for \"%s\".\n",
               SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
               HashDataIdx, Offset, Name);
 
@@ -908,8 +916,8 @@
 DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
   // A map from CU offset to the (first) Name Index offset which claims to index
   // this CU.
-  DenseMap<uint32_t, uint32_t> CUMap;
-  const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max();
+  DenseMap<uint64_t, uint64_t> CUMap;
+  const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
 
   CUMap.reserve(DCtx.getNumCompileUnits());
   for (const auto &CU : DCtx.compile_units())
@@ -924,7 +932,7 @@
       continue;
     }
     for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
-      uint32_t Offset = NI.getCUOffset(CU);
+      uint64_t Offset = NI.getCUOffset(CU);
       auto Iter = CUMap.find(Offset);
 
       if (Iter == CUMap.end()) {
@@ -962,7 +970,7 @@
 
     constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
         : Bucket(Bucket), Index(Index) {}
-    bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; };
+    bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
   };
 
   uint32_t NumErrors = 0;
@@ -1205,8 +1213,8 @@
 
   unsigned NumErrors = 0;
   unsigned NumEntries = 0;
-  uint32_t EntryID = NTE.getEntryOffset();
-  uint32_t NextEntryID = EntryID;
+  uint64_t EntryID = NTE.getEntryOffset();
+  uint64_t NextEntryID = EntryID;
   Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
   for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
                                 EntryOr = NI.getEntry(&NextEntryID)) {
@@ -1218,7 +1226,7 @@
       ++NumErrors;
       continue;
     }
-    uint32_t CUOffset = NI.getCUOffset(CUIndex);
+    uint64_t CUOffset = NI.getCUOffset(CUIndex);
     uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
     DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
     if (!DIE) {
@@ -1272,36 +1280,24 @@
 }
 
 static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
-  Optional<DWARFFormValue> Location = Die.findRecursively(DW_AT_location);
-  if (!Location)
+  Expected<std::vector<DWARFLocationExpression>> Loc =
+      Die.getLocations(DW_AT_location);
+  if (!Loc) {
+    consumeError(Loc.takeError());
     return false;
-
-  auto ContainsInterestingOperators = [&](StringRef D) {
-    DWARFUnit *U = Die.getDwarfUnit();
-    DataExtractor Data(D, DCtx.isLittleEndian(), U->getAddressByteSize());
+  }
+  DWARFUnit *U = Die.getDwarfUnit();
+  for (const auto &Entry : *Loc) {
+    DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
+                       U->getAddressByteSize());
     DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
-    return any_of(Expression, [](DWARFExpression::Operation &Op) {
+    bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) {
       return !Op.isError() && (Op.getCode() == DW_OP_addr ||
                                Op.getCode() == DW_OP_form_tls_address ||
                                Op.getCode() == DW_OP_GNU_push_tls_address);
     });
-  };
-
-  if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
-    // Inlined location.
-    if (ContainsInterestingOperators(toStringRef(*Expr)))
+    if (IsInteresting)
       return true;
-  } else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) {
-    // Location list.
-    if (const DWARFDebugLoc *DebugLoc = DCtx.getDebugLoc()) {
-      if (const DWARFDebugLoc::LocationList *LocList =
-              DebugLoc->getLocationListAtOffset(*Offset)) {
-        if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) {
-              return ContainsInterestingOperators({E.Loc.data(), E.Loc.size()});
-            }))
-          return true;
-      }
-    }
   }
   return false;
 }
@@ -1455,7 +1451,7 @@
 
 bool DWARFVerifier::handleAccelTables() {
   const DWARFObject &D = DCtx.getDWARFObj();
-  DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
+  DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
   unsigned NumErrors = 0;
   if (!D.getAppleNamesSection().Data.empty())
     NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
@@ -1470,8 +1466,8 @@
     NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
                                        ".apple_objc");
 
-  if (!D.getDebugNamesSection().Data.empty())
-    NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData);
+  if (!D.getNamesSection().Data.empty())
+    NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
   return NumErrors == 0;
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
index fc37d56..d0fb2ca 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
@@ -1,9 +1,18 @@
-add_llvm_library(LLVMDebugInfoGSYM
+add_llvm_component_library(LLVMDebugInfoGSYM
+  Header.cpp
+  FileWriter.cpp
   FunctionInfo.cpp
+  GsymCreator.cpp
+  GsymReader.cpp
   InlineInfo.cpp
+  LineTable.cpp
+  LookupResult.cpp
   Range.cpp
 
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/GSYM
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo
+
+  DEPENDS
+  LLVMMC
   )
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/FileWriter.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/FileWriter.cpp
new file mode 100644
index 0000000..4b30dcb
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/FileWriter.cpp
@@ -0,0 +1,78 @@
+//===- FileWriter.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+using namespace gsym;
+
+FileWriter::~FileWriter() { OS.flush(); }
+
+void FileWriter::writeSLEB(int64_t S) {
+  uint8_t Bytes[32];
+  auto Length = encodeSLEB128(S, Bytes);
+  assert(Length < sizeof(Bytes));
+  OS.write(reinterpret_cast<const char *>(Bytes), Length);
+}
+
+void FileWriter::writeULEB(uint64_t U) {
+  uint8_t Bytes[32];
+  auto Length = encodeULEB128(U, Bytes);
+  assert(Length < sizeof(Bytes));
+  OS.write(reinterpret_cast<const char *>(Bytes), Length);
+}
+
+void FileWriter::writeU8(uint8_t U) {
+  OS.write(reinterpret_cast<const char *>(&U), sizeof(U));
+}
+
+void FileWriter::writeU16(uint16_t U) {
+  const uint16_t Swapped = support::endian::byte_swap(U, ByteOrder);
+  OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::writeU32(uint32_t U) {
+  const uint32_t Swapped = support::endian::byte_swap(U, ByteOrder);
+  OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::writeU64(uint64_t U) {
+  const uint64_t Swapped = support::endian::byte_swap(U, ByteOrder);
+  OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::fixup32(uint32_t U, uint64_t Offset) {
+  const uint32_t Swapped = support::endian::byte_swap(U, ByteOrder);
+  OS.pwrite(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped),
+            Offset);
+}
+
+void FileWriter::writeData(llvm::ArrayRef<uint8_t> Data) {
+  OS.write(reinterpret_cast<const char *>(Data.data()), Data.size());
+}
+
+void FileWriter::writeNullTerminated(llvm::StringRef Str) {
+  OS << Str << '\0';
+}
+
+uint64_t FileWriter::tell() {
+  return OS.tell();
+}
+
+void FileWriter::alignTo(size_t Align) {
+  off_t Offset = OS.tell();
+  off_t AlignedOffset = (Offset + Align - 1) / Align * Align;
+  if (AlignedOffset == Offset)
+    return;
+  off_t PadCount = AlignedOffset - Offset;
+  OS.write_zeros(PadCount);
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
index 55c36a5..6731a8b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
@@ -1,22 +1,249 @@
-//===- FunctionInfo.cpp -----------------------------------------*- C++ -*-===//
+//===- FunctionInfo.cpp ---------------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/GsymReader.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/Support/DataExtractor.h"
 
 using namespace llvm;
 using namespace gsym;
 
+/// FunctionInfo information type that is used to encode the optional data
+/// that is associated with a FunctionInfo object.
+enum InfoType : uint32_t {
+  EndOfList = 0u,
+  LineTableInfo = 1u,
+  InlineInfo = 2u
+};
+
 raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const FunctionInfo &FI) {
   OS << '[' << HEX64(FI.Range.Start) << '-' << HEX64(FI.Range.End) << "): "
-     << "Name=" << HEX32(FI.Name) << '\n';
-  for (const auto &Line : FI.Lines)
-    OS << Line << '\n';
-  OS << FI.Inline;
+     << "Name=" << HEX32(FI.Name) << '\n' << FI.OptLineTable << FI.Inline;
   return OS;
 }
+
+llvm::Expected<FunctionInfo> FunctionInfo::decode(DataExtractor &Data,
+                                                  uint64_t BaseAddr) {
+  FunctionInfo FI;
+  FI.Range.Start = BaseAddr;
+  uint64_t Offset = 0;
+  if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing FunctionInfo Size", Offset);
+  FI.Range.End = FI.Range.Start + Data.getU32(&Offset);
+  if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing FunctionInfo Name", Offset);
+  FI.Name = Data.getU32(&Offset);
+  if (FI.Name == 0)
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": invalid FunctionInfo Name value 0x%8.8x",
+        Offset - 4, FI.Name);
+  bool Done = false;
+  while (!Done) {
+    if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+      return createStringError(std::errc::io_error,
+          "0x%8.8" PRIx64 ": missing FunctionInfo InfoType value", Offset);
+    const uint32_t IT = Data.getU32(&Offset);
+    if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+      return createStringError(std::errc::io_error,
+          "0x%8.8" PRIx64 ": missing FunctionInfo InfoType length", Offset);
+    const uint32_t InfoLength = Data.getU32(&Offset);
+    if (!Data.isValidOffsetForDataOfSize(Offset, InfoLength))
+      return createStringError(std::errc::io_error,
+          "0x%8.8" PRIx64 ": missing FunctionInfo data for InfoType %u",
+          Offset, IT);
+    DataExtractor InfoData(Data.getData().substr(Offset, InfoLength),
+                           Data.isLittleEndian(),
+                           Data.getAddressSize());
+    switch (IT) {
+      case InfoType::EndOfList:
+        Done = true;
+        break;
+
+      case InfoType::LineTableInfo:
+        if (Expected<LineTable> LT = LineTable::decode(InfoData, BaseAddr))
+          FI.OptLineTable = std::move(LT.get());
+        else
+          return LT.takeError();
+        break;
+
+      case InfoType::InlineInfo:
+        if (Expected<InlineInfo> II = InlineInfo::decode(InfoData, BaseAddr))
+          FI.Inline = std::move(II.get());
+        else
+          return II.takeError();
+        break;
+
+      default:
+        return createStringError(std::errc::io_error,
+                                 "0x%8.8" PRIx64 ": unsupported InfoType %u",
+                                 Offset-8, IT);
+    }
+    Offset += InfoLength;
+  }
+  return std::move(FI);
+}
+
+llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &O) const {
+  if (!isValid())
+    return createStringError(std::errc::invalid_argument,
+        "attempted to encode invalid FunctionInfo object");
+  // Align FunctionInfo data to a 4 byte alignment.
+  O.alignTo(4);
+  const uint64_t FuncInfoOffset = O.tell();
+  // Write the size in bytes of this function as a uint32_t. This can be zero
+  // if we just have a symbol from a symbol table and that symbol has no size.
+  O.writeU32(size());
+  // Write the name of this function as a uint32_t string table offset.
+  O.writeU32(Name);
+
+  if (OptLineTable.hasValue()) {
+    O.writeU32(InfoType::LineTableInfo);
+    // Write a uint32_t length as zero for now, we will fix this up after
+    // writing the LineTable out with the number of bytes that were written.
+    O.writeU32(0);
+    const auto StartOffset = O.tell();
+    llvm::Error err = OptLineTable->encode(O, Range.Start);
+    if (err)
+      return std::move(err);
+    const auto Length = O.tell() - StartOffset;
+    if (Length > UINT32_MAX)
+        return createStringError(std::errc::invalid_argument,
+            "LineTable length is greater than UINT32_MAX");
+    // Fixup the size of the LineTable data with the correct size.
+    O.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+  }
+
+  // Write out the inline function info if we have any and if it is valid.
+  if (Inline.hasValue()) {
+    O.writeU32(InfoType::InlineInfo);
+    // Write a uint32_t length as zero for now, we will fix this up after
+    // writing the LineTable out with the number of bytes that were written.
+    O.writeU32(0);
+    const auto StartOffset = O.tell();
+    llvm::Error err = Inline->encode(O, Range.Start);
+    if (err)
+      return std::move(err);
+    const auto Length = O.tell() - StartOffset;
+    if (Length > UINT32_MAX)
+        return createStringError(std::errc::invalid_argument,
+            "InlineInfo length is greater than UINT32_MAX");
+    // Fixup the size of the InlineInfo data with the correct size.
+    O.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+  }
+
+  // Terminate the data chunks with and end of list with zero size
+  O.writeU32(InfoType::EndOfList);
+  O.writeU32(0);
+  return FuncInfoOffset;
+}
+
+
+llvm::Expected<LookupResult> FunctionInfo::lookup(DataExtractor &Data,
+                                                  const GsymReader &GR,
+                                                  uint64_t FuncAddr,
+                                                  uint64_t Addr) {
+  LookupResult LR;
+  LR.LookupAddr = Addr;
+  LR.FuncRange.Start = FuncAddr;
+  uint64_t Offset = 0;
+  LR.FuncRange.End = FuncAddr + Data.getU32(&Offset);
+  uint32_t NameOffset = Data.getU32(&Offset);
+  // The "lookup" functions doesn't report errors as accurately as the "decode"
+  // function as it is meant to be fast. For more accurage errors we could call
+  // "decode".
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+                              "FunctionInfo data is truncated");
+  // This function will be called with the result of a binary search of the
+  // address table, we must still make sure the address does not fall into a
+  // gap between functions are after the last function.
+  if (Addr >= LR.FuncRange.End)
+    return createStringError(std::errc::io_error,
+        "address 0x%" PRIx64 " is not in GSYM", Addr);
+
+  if (NameOffset == 0)
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": invalid FunctionInfo Name value 0x00000000",
+        Offset - 4);
+  LR.FuncName = GR.getString(NameOffset);
+  bool Done = false;
+  Optional<LineEntry> LineEntry;
+  Optional<DataExtractor> InlineInfoData;
+  while (!Done) {
+    if (!Data.isValidOffsetForDataOfSize(Offset, 8))
+      return createStringError(std::errc::io_error,
+                               "FunctionInfo data is truncated");
+    const uint32_t IT = Data.getU32(&Offset);
+    const uint32_t InfoLength = Data.getU32(&Offset);
+    const StringRef InfoBytes = Data.getData().substr(Offset, InfoLength);
+    if (InfoLength != InfoBytes.size())
+      return createStringError(std::errc::io_error,
+                               "FunctionInfo data is truncated");
+    DataExtractor InfoData(InfoBytes, Data.isLittleEndian(),
+                           Data.getAddressSize());
+    switch (IT) {
+      case InfoType::EndOfList:
+        Done = true;
+        break;
+
+      case InfoType::LineTableInfo:
+        if (auto ExpectedLE = LineTable::lookup(InfoData, FuncAddr, Addr))
+          LineEntry = ExpectedLE.get();
+        else
+          return ExpectedLE.takeError();
+        break;
+
+      case InfoType::InlineInfo:
+        // We will parse the inline info after our line table, but only if
+        // we have a line entry.
+        InlineInfoData = InfoData;
+        break;
+
+      default:
+        break;
+    }
+    Offset += InfoLength;
+  }
+
+  if (!LineEntry) {
+    // We don't have a valid line entry for our address, fill in our source
+    // location as best we can and return.
+    SourceLocation SrcLoc;
+    SrcLoc.Name = LR.FuncName;
+    LR.Locations.push_back(SrcLoc);
+    return LR;
+  }
+
+  Optional<FileEntry> LineEntryFile = GR.getFile(LineEntry->File);
+  if (!LineEntryFile)
+    return createStringError(std::errc::invalid_argument,
+                              "failed to extract file[%" PRIu32 "]",
+                              LineEntry->File);
+
+  SourceLocation SrcLoc;
+  SrcLoc.Name = LR.FuncName;
+  SrcLoc.Dir = GR.getString(LineEntryFile->Dir);
+  SrcLoc.Base = GR.getString(LineEntryFile->Base);
+  SrcLoc.Line = LineEntry->Line;
+  LR.Locations.push_back(SrcLoc);
+  // If we don't have inline information, we are done.
+  if (!InlineInfoData)
+    return LR;
+  // We have inline information. Try to augment the lookup result with this
+  // data.
+  llvm::Error Err = InlineInfo::lookup(GR, *InlineInfoData, FuncAddr, Addr,
+                                       LR.Locations);
+  if (Err)
+    return std::move(Err);
+  return LR;
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
new file mode 100644
index 0000000..f371426
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -0,0 +1,275 @@
+//===- GsymCreator.cpp ----------------------------------------------------===//
+//
+// 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
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/GsymCreator.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <vector>
+
+using namespace llvm;
+using namespace gsym;
+
+
+GsymCreator::GsymCreator() : StrTab(StringTableBuilder::ELF) {
+  insertFile(StringRef());
+}
+
+uint32_t GsymCreator::insertFile(StringRef Path,
+                                 llvm::sys::path::Style Style) {
+  llvm::StringRef directory = llvm::sys::path::parent_path(Path, Style);
+  llvm::StringRef filename = llvm::sys::path::filename(Path, Style);
+  FileEntry FE(insertString(directory), insertString(filename));
+
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  const auto NextIndex = Files.size();
+  // Find FE in hash map and insert if not present.
+  auto R = FileEntryToIndex.insert(std::make_pair(FE, NextIndex));
+  if (R.second)
+    Files.emplace_back(FE);
+  return R.first->second;
+}
+
+llvm::Error GsymCreator::save(StringRef Path,
+                              llvm::support::endianness ByteOrder) const {
+  std::error_code EC;
+  raw_fd_ostream OutStrm(Path, EC);
+  if (EC)
+    return llvm::errorCodeToError(EC);
+  FileWriter O(OutStrm, ByteOrder);
+  return encode(O);
+}
+
+llvm::Error GsymCreator::encode(FileWriter &O) const {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  if (Funcs.empty())
+    return createStringError(std::errc::invalid_argument,
+                             "no functions to encode");
+  if (!Finalized)
+    return createStringError(std::errc::invalid_argument,
+                             "GsymCreator wasn't finalized prior to encoding");
+
+  if (Funcs.size() > UINT32_MAX)
+    return createStringError(std::errc::invalid_argument,
+                             "too many FunctionInfos");
+  const uint64_t MinAddr = Funcs.front().startAddress();
+  const uint64_t MaxAddr = Funcs.back().startAddress();
+  const uint64_t AddrDelta = MaxAddr - MinAddr;
+  Header Hdr;
+  Hdr.Magic = GSYM_MAGIC;
+  Hdr.Version = GSYM_VERSION;
+  Hdr.AddrOffSize = 0;
+  Hdr.UUIDSize = static_cast<uint8_t>(UUID.size());
+  Hdr.BaseAddress = MinAddr;
+  Hdr.NumAddresses = static_cast<uint32_t>(Funcs.size());
+  Hdr.StrtabOffset = 0; // We will fix this up later.
+  Hdr.StrtabOffset = 0; // We will fix this up later.
+  memset(Hdr.UUID, 0, sizeof(Hdr.UUID));
+  if (UUID.size() > sizeof(Hdr.UUID))
+    return createStringError(std::errc::invalid_argument,
+                             "invalid UUID size %u", (uint32_t)UUID.size());
+  // Set the address offset size correctly in the GSYM header.
+  if (AddrDelta <= UINT8_MAX)
+    Hdr.AddrOffSize = 1;
+  else if (AddrDelta <= UINT16_MAX)
+    Hdr.AddrOffSize = 2;
+  else if (AddrDelta <= UINT32_MAX)
+    Hdr.AddrOffSize = 4;
+  else
+    Hdr.AddrOffSize = 8;
+  // Copy the UUID value if we have one.
+  if (UUID.size() > 0)
+    memcpy(Hdr.UUID, UUID.data(), UUID.size());
+  // Write out the header.
+  llvm::Error Err = Hdr.encode(O);
+  if (Err)
+    return Err;
+
+  // Write out the address offsets.
+  O.alignTo(Hdr.AddrOffSize);
+  for (const auto &FuncInfo : Funcs) {
+    uint64_t AddrOffset = FuncInfo.startAddress() - Hdr.BaseAddress;
+    switch(Hdr.AddrOffSize) {
+      case 1: O.writeU8(static_cast<uint8_t>(AddrOffset)); break;
+      case 2: O.writeU16(static_cast<uint16_t>(AddrOffset)); break;
+      case 4: O.writeU32(static_cast<uint32_t>(AddrOffset)); break;
+      case 8: O.writeU64(AddrOffset); break;
+    }
+  }
+
+  // Write out all zeros for the AddrInfoOffsets.
+  O.alignTo(4);
+  const off_t AddrInfoOffsetsOffset = O.tell();
+  for (size_t i = 0, n = Funcs.size(); i < n; ++i)
+    O.writeU32(0);
+
+  // Write out the file table
+  O.alignTo(4);
+  assert(!Files.empty());
+  assert(Files[0].Dir == 0);
+  assert(Files[0].Base == 0);
+  size_t NumFiles = Files.size();
+  if (NumFiles > UINT32_MAX)
+    return createStringError(std::errc::invalid_argument,
+                             "too many files");
+  O.writeU32(static_cast<uint32_t>(NumFiles));
+  for (auto File: Files) {
+      O.writeU32(File.Dir);
+      O.writeU32(File.Base);
+  }
+
+  // Write out the sting table.
+  const off_t StrtabOffset = O.tell();
+  StrTab.write(O.get_stream());
+  const off_t StrtabSize = O.tell() - StrtabOffset;
+  std::vector<uint32_t> AddrInfoOffsets;
+
+  // Write out the address infos for each function info.
+  for (const auto &FuncInfo : Funcs) {
+    if (Expected<uint64_t> OffsetOrErr = FuncInfo.encode(O))
+        AddrInfoOffsets.push_back(OffsetOrErr.get());
+    else
+        return OffsetOrErr.takeError();
+  }
+  // Fixup the string table offset and size in the header
+  O.fixup32((uint32_t)StrtabOffset, offsetof(Header, StrtabOffset));
+  O.fixup32((uint32_t)StrtabSize, offsetof(Header, StrtabSize));
+
+  // Fixup all address info offsets
+  uint64_t Offset = 0;
+  for (auto AddrInfoOffset: AddrInfoOffsets) {
+    O.fixup32(AddrInfoOffset, AddrInfoOffsetsOffset + Offset);
+    Offset += 4;
+  }
+  return ErrorSuccess();
+}
+
+llvm::Error GsymCreator::finalize(llvm::raw_ostream &OS) {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  if (Finalized)
+    return createStringError(std::errc::invalid_argument,
+                             "already finalized");
+  Finalized = true;
+
+  // Sort function infos so we can emit sorted functions.
+  llvm::sort(Funcs.begin(), Funcs.end());
+
+  // Don't let the string table indexes change by finalizing in order.
+  StrTab.finalizeInOrder();
+
+  // Remove duplicates function infos that have both entries from debug info
+  // (DWARF or Breakpad) and entries from the SymbolTable.
+  //
+  // Also handle overlapping function. Usually there shouldn't be any, but they
+  // can and do happen in some rare cases.
+  //
+  // (a)          (b)         (c)
+  //     ^  ^       ^            ^
+  //     |X |Y      |X ^         |X
+  //     |  |       |  |Y        |  ^
+  //     |  |       |  v         v  |Y
+  //     v  v       v               v
+  //
+  // In (a) and (b), Y is ignored and X will be reported for the full range.
+  // In (c), both functions will be included in the result and lookups for an
+  // address in the intersection will return Y because of binary search.
+  //
+  // Note that in case of (b), we cannot include Y in the result because then
+  // we wouldn't find any function for range (end of Y, end of X)
+  // with binary search
+  auto NumBefore = Funcs.size();
+  auto Curr = Funcs.begin();
+  auto Prev = Funcs.end();
+  while (Curr != Funcs.end()) {
+    // Can't check for overlaps or same address ranges if we don't have a
+    // previous entry
+    if (Prev != Funcs.end()) {
+      if (Prev->Range.intersects(Curr->Range)) {
+        // Overlapping address ranges.
+        if (Prev->Range == Curr->Range) {
+          // Same address range. Check if one is from debug info and the other
+          // is from a symbol table. If so, then keep the one with debug info.
+          // Our sorting guarantees that entries with matching address ranges
+          // that have debug info are last in the sort.
+          if (*Prev == *Curr) {
+            // FunctionInfo entries match exactly (range, lines, inlines)
+            OS << "warning: duplicate function info entries, removing "
+                  "duplicate:\n"
+               << *Curr << '\n';
+            Curr = Funcs.erase(Prev);
+          } else {
+            if (!Prev->hasRichInfo() && Curr->hasRichInfo()) {
+              // Same address range, one with no debug info (symbol) and the
+              // next with debug info. Keep the latter.
+              Curr = Funcs.erase(Prev);
+            } else {
+              OS << "warning: same address range contains different debug "
+                 << "info. Removing:\n"
+                 << *Prev << "\nIn favor of this one:\n"
+                 << *Curr << "\n";
+              Curr = Funcs.erase(Prev);
+            }
+          }
+        } else {
+          // print warnings about overlaps
+          OS << "warning: function ranges overlap:\n"
+             << *Prev << "\n"
+             << *Curr << "\n";
+        }
+      } else if (Prev->Range.size() == 0 &&
+                 Curr->Range.contains(Prev->Range.Start)) {
+        OS << "warning: removing symbol:\n"
+           << *Prev << "\nKeeping:\n"
+           << *Curr << "\n";
+        Curr = Funcs.erase(Prev);
+      }
+    }
+    if (Curr == Funcs.end())
+      break;
+    Prev = Curr++;
+  }
+
+  OS << "Pruned " << NumBefore - Funcs.size() << " functions, ended with "
+     << Funcs.size() << " total\n";
+  return Error::success();
+}
+
+uint32_t GsymCreator::insertString(StringRef S) {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  if (S.empty())
+    return 0;
+  return StrTab.add(S);
+}
+
+void GsymCreator::addFunctionInfo(FunctionInfo &&FI) {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  Funcs.emplace_back(FI);
+}
+
+void GsymCreator::forEachFunctionInfo(
+    std::function<bool(FunctionInfo &)> const &Callback) {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  for (auto &FI : Funcs) {
+    if (!Callback(FI))
+      break;
+  }
+}
+
+void GsymCreator::forEachFunctionInfo(
+    std::function<bool(const FunctionInfo &)> const &Callback) const {
+  std::lock_guard<std::recursive_mutex> Guard(Mutex);
+  for (const auto &FI : Funcs) {
+    if (!Callback(FI))
+      break;
+  }
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymReader.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
new file mode 100644
index 0000000..b4f3f20
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/GsymReader.cpp
@@ -0,0 +1,279 @@
+//===- GsymReader.cpp -----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/GsymReader.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "llvm/DebugInfo/GSYM/GsymCreator.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace gsym;
+
+GsymReader::GsymReader(std::unique_ptr<MemoryBuffer> Buffer) :
+    MemBuffer(std::move(Buffer)),
+    Endian(support::endian::system_endianness()) {}
+
+  GsymReader::GsymReader(GsymReader &&RHS) = default;
+
+GsymReader::~GsymReader() = default;
+
+llvm::Expected<GsymReader> GsymReader::openFile(StringRef Filename) {
+  // Open the input file and return an appropriate error if needed.
+  ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
+      MemoryBuffer::getFileOrSTDIN(Filename);
+  auto Err = BuffOrErr.getError();
+  if (Err)
+    return llvm::errorCodeToError(Err);
+  return create(BuffOrErr.get());
+}
+
+llvm::Expected<GsymReader> GsymReader::copyBuffer(StringRef Bytes) {
+  auto MemBuffer = MemoryBuffer::getMemBufferCopy(Bytes, "GSYM bytes");
+  return create(MemBuffer);
+}
+
+llvm::Expected<llvm::gsym::GsymReader>
+GsymReader::create(std::unique_ptr<MemoryBuffer> &MemBuffer) {
+  if (!MemBuffer.get())
+    return createStringError(std::errc::invalid_argument,
+                             "invalid memory buffer");
+  GsymReader GR(std::move(MemBuffer));
+  llvm::Error Err = GR.parse();
+  if (Err)
+    return std::move(Err);
+  return std::move(GR);
+}
+
+llvm::Error
+GsymReader::parse() {
+  BinaryStreamReader FileData(MemBuffer->getBuffer(),
+                              support::endian::system_endianness());
+  // Check for the magic bytes. This file format is designed to be mmap'ed
+  // into a process and accessed as read only. This is done for performance
+  // and efficiency for symbolicating and parsing GSYM data.
+  if (FileData.readObject(Hdr))
+    return createStringError(std::errc::invalid_argument,
+                             "not enough data for a GSYM header");
+
+  const auto HostByteOrder = support::endian::system_endianness();
+  switch (Hdr->Magic) {
+    case GSYM_MAGIC:
+      Endian = HostByteOrder;
+      break;
+    case GSYM_CIGAM:
+      // This is a GSYM file, but not native endianness.
+      Endian = sys::IsBigEndianHost ? support::little : support::big;
+      Swap.reset(new SwappedData);
+      break;
+    default:
+      return createStringError(std::errc::invalid_argument,
+                               "not a GSYM file");
+  }
+
+  bool DataIsLittleEndian = HostByteOrder != support::little;
+  // Read a correctly byte swapped header if we need to.
+  if (Swap) {
+    DataExtractor Data(MemBuffer->getBuffer(), DataIsLittleEndian, 4);
+    if (auto ExpectedHdr = Header::decode(Data))
+      Swap->Hdr = ExpectedHdr.get();
+    else
+      return ExpectedHdr.takeError();
+    Hdr = &Swap->Hdr;
+  }
+
+  // Detect errors in the header and report any that are found. If we make it
+  // past this without errors, we know we have a good magic value, a supported
+  // version number, verified address offset size and a valid UUID size.
+  if (Error Err = Hdr->checkForError())
+    return Err;
+
+  if (!Swap) {
+    // This is the native endianness case that is most common and optimized for
+    // efficient lookups. Here we just grab pointers to the native data and
+    // use ArrayRef objects to allow efficient read only access.
+
+    // Read the address offsets.
+    if (FileData.padToAlignment(Hdr->AddrOffSize) ||
+        FileData.readArray(AddrOffsets,
+                           Hdr->NumAddresses * Hdr->AddrOffSize))
+      return createStringError(std::errc::invalid_argument,
+                              "failed to read address table");
+
+    // Read the address info offsets.
+    if (FileData.padToAlignment(4) ||
+        FileData.readArray(AddrInfoOffsets, Hdr->NumAddresses))
+      return createStringError(std::errc::invalid_argument,
+                              "failed to read address info offsets table");
+
+    // Read the file table.
+    uint32_t NumFiles = 0;
+    if (FileData.readInteger(NumFiles) || FileData.readArray(Files, NumFiles))
+      return createStringError(std::errc::invalid_argument,
+                              "failed to read file table");
+
+    // Get the string table.
+    FileData.setOffset(Hdr->StrtabOffset);
+    if (FileData.readFixedString(StrTab.Data, Hdr->StrtabSize))
+      return createStringError(std::errc::invalid_argument,
+                              "failed to read string table");
+} else {
+  // This is the non native endianness case that is not common and not
+  // optimized for lookups. Here we decode the important tables into local
+  // storage and then set the ArrayRef objects to point to these swapped
+  // copies of the read only data so lookups can be as efficient as possible.
+  DataExtractor Data(MemBuffer->getBuffer(), DataIsLittleEndian, 4);
+
+  // Read the address offsets.
+  uint64_t Offset = alignTo(sizeof(Header), Hdr->AddrOffSize);
+  Swap->AddrOffsets.resize(Hdr->NumAddresses * Hdr->AddrOffSize);
+  switch (Hdr->AddrOffSize) {
+    case 1:
+      if (!Data.getU8(&Offset, Swap->AddrOffsets.data(), Hdr->NumAddresses))
+        return createStringError(std::errc::invalid_argument,
+                                  "failed to read address table");
+      break;
+    case 2:
+      if (!Data.getU16(&Offset,
+                        reinterpret_cast<uint16_t *>(Swap->AddrOffsets.data()),
+                        Hdr->NumAddresses))
+        return createStringError(std::errc::invalid_argument,
+                                  "failed to read address table");
+      break;
+    case 4:
+      if (!Data.getU32(&Offset,
+                        reinterpret_cast<uint32_t *>(Swap->AddrOffsets.data()),
+                        Hdr->NumAddresses))
+        return createStringError(std::errc::invalid_argument,
+                                  "failed to read address table");
+      break;
+    case 8:
+      if (!Data.getU64(&Offset,
+                        reinterpret_cast<uint64_t *>(Swap->AddrOffsets.data()),
+                        Hdr->NumAddresses))
+        return createStringError(std::errc::invalid_argument,
+                                  "failed to read address table");
+    }
+    AddrOffsets = ArrayRef<uint8_t>(Swap->AddrOffsets);
+
+    // Read the address info offsets.
+    Offset = alignTo(Offset, 4);
+    Swap->AddrInfoOffsets.resize(Hdr->NumAddresses);
+    if (Data.getU32(&Offset, Swap->AddrInfoOffsets.data(), Hdr->NumAddresses))
+      AddrInfoOffsets = ArrayRef<uint32_t>(Swap->AddrInfoOffsets);
+    else
+      return createStringError(std::errc::invalid_argument,
+                               "failed to read address table");
+    // Read the file table.
+    const uint32_t NumFiles = Data.getU32(&Offset);
+    if (NumFiles > 0) {
+      Swap->Files.resize(NumFiles);
+      if (Data.getU32(&Offset, &Swap->Files[0].Dir, NumFiles*2))
+        Files = ArrayRef<FileEntry>(Swap->Files);
+      else
+        return createStringError(std::errc::invalid_argument,
+                                 "failed to read file table");
+    }
+    // Get the string table.
+    StrTab.Data = MemBuffer->getBuffer().substr(Hdr->StrtabOffset,
+                                                Hdr->StrtabSize);
+    if (StrTab.Data.empty())
+      return createStringError(std::errc::invalid_argument,
+                               "failed to read string table");
+  }
+  return Error::success();
+
+}
+
+const Header &GsymReader::getHeader() const {
+  // The only way to get a GsymReader is from GsymReader::openFile(...) or
+  // GsymReader::copyBuffer() and the header must be valid and initialized to
+  // a valid pointer value, so the assert below should not trigger.
+  assert(Hdr);
+  return *Hdr;
+}
+
+Optional<uint64_t> GsymReader::getAddress(size_t Index) const {
+  switch (Hdr->AddrOffSize) {
+  case 1: return addressForIndex<uint8_t>(Index);
+  case 2: return addressForIndex<uint16_t>(Index);
+  case 4: return addressForIndex<uint32_t>(Index);
+  case 8: return addressForIndex<uint64_t>(Index);
+  }
+  return llvm::None;
+}
+
+Optional<uint64_t> GsymReader::getAddressInfoOffset(size_t Index) const {
+  const auto NumAddrInfoOffsets = AddrInfoOffsets.size();
+  if (Index < NumAddrInfoOffsets)
+    return AddrInfoOffsets[Index];
+  return llvm::None;
+}
+
+Expected<uint64_t>
+GsymReader::getAddressIndex(const uint64_t Addr) const {
+  if (Addr < Hdr->BaseAddress)
+    return createStringError(std::errc::invalid_argument,
+                             "address 0x%" PRIx64 " not in GSYM", Addr);
+  const uint64_t AddrOffset = Addr - Hdr->BaseAddress;
+  switch (Hdr->AddrOffSize) {
+  case 1: return getAddressOffsetIndex<uint8_t>(AddrOffset);
+  case 2: return getAddressOffsetIndex<uint16_t>(AddrOffset);
+  case 4: return getAddressOffsetIndex<uint32_t>(AddrOffset);
+  case 8: return getAddressOffsetIndex<uint64_t>(AddrOffset);
+  default: break;
+  }
+  return createStringError(std::errc::invalid_argument,
+                           "unsupported address offset size %u",
+                           Hdr->AddrOffSize);
+}
+
+llvm::Expected<FunctionInfo> GsymReader::getFunctionInfo(uint64_t Addr) const {
+  Expected<uint64_t> AddressIndex = getAddressIndex(Addr);
+  if (!AddressIndex)
+    return AddressIndex.takeError();
+  // Address info offsets size should have been checked in parse().
+  assert(*AddressIndex < AddrInfoOffsets.size());
+  auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
+  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset), Endian, 4);
+  if (Optional<uint64_t> OptAddr = getAddress(*AddressIndex)) {
+    auto ExpectedFI = FunctionInfo::decode(Data, *OptAddr);
+    if (ExpectedFI) {
+      if (ExpectedFI->Range.contains(Addr) || ExpectedFI->Range.size() == 0)
+        return ExpectedFI;
+      return createStringError(std::errc::invalid_argument,
+                                "address 0x%" PRIx64 " not in GSYM", Addr);
+    }
+  }
+  return createStringError(std::errc::invalid_argument,
+                           "failed to extract address[%" PRIu64 "]",
+                           *AddressIndex);
+}
+
+llvm::Expected<LookupResult> GsymReader::lookup(uint64_t Addr) const {
+  Expected<uint64_t> AddressIndex = getAddressIndex(Addr);
+  if (!AddressIndex)
+    return AddressIndex.takeError();
+  // Address info offsets size should have been checked in parse().
+  assert(*AddressIndex < AddrInfoOffsets.size());
+  auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
+  DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset), Endian, 4);
+  if (Optional<uint64_t> OptAddr = getAddress(*AddressIndex))
+    return FunctionInfo::lookup(Data, *this, *OptAddr, Addr);
+  return createStringError(std::errc::invalid_argument,
+                           "failed to extract address[%" PRIu64 "]",
+                           *AddressIndex);
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/Header.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/Header.cpp
new file mode 100644
index 0000000..0b3fb9c
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/Header.cpp
@@ -0,0 +1,109 @@
+//===- Header.cpp -----------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define HEX8(v) llvm::format_hex(v, 4)
+#define HEX16(v) llvm::format_hex(v, 6)
+#define HEX32(v) llvm::format_hex(v, 10)
+#define HEX64(v) llvm::format_hex(v, 18)
+
+using namespace llvm;
+using namespace gsym;
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const Header &H) {
+  OS << "Header:\n";
+  OS << "  Magic        = " << HEX32(H.Magic) << "\n";
+  OS << "  Version      = " << HEX16(H.Version) << '\n';
+  OS << "  AddrOffSize  = " << HEX8(H.AddrOffSize) << '\n';
+  OS << "  UUIDSize     = " << HEX8(H.UUIDSize) << '\n';
+  OS << "  BaseAddress  = " << HEX64(H.BaseAddress) << '\n';
+  OS << "  NumAddresses = " << HEX32(H.NumAddresses) << '\n';
+  OS << "  StrtabOffset = " << HEX32(H.StrtabOffset) << '\n';
+  OS << "  StrtabSize   = " << HEX32(H.StrtabSize) << '\n';
+  OS << "  UUID         = ";
+  for (uint8_t I = 0; I < H.UUIDSize; ++I)
+    OS << format_hex_no_prefix(H.UUID[I], 2);
+  OS << '\n';
+  return OS;
+}
+
+/// Check the header and detect any errors.
+llvm::Error Header::checkForError() const {
+  if (Magic != GSYM_MAGIC)
+    return createStringError(std::errc::invalid_argument,
+                             "invalid GSYM magic 0x%8.8x", Magic);
+  if (Version != GSYM_VERSION)
+    return createStringError(std::errc::invalid_argument,
+                             "unsupported GSYM version %u", Version);
+  switch (AddrOffSize) {
+    case 1: break;
+    case 2: break;
+    case 4: break;
+    case 8: break;
+    default:
+        return createStringError(std::errc::invalid_argument,
+                                 "invalid address offset size %u",
+                                 AddrOffSize);
+  }
+  if (UUIDSize > GSYM_MAX_UUID_SIZE)
+    return createStringError(std::errc::invalid_argument,
+                             "invalid UUID size %u", UUIDSize);
+  return Error::success();
+}
+
+llvm::Expected<Header> Header::decode(DataExtractor &Data) {
+  uint64_t Offset = 0;
+  // The header is stored as a single blob of data that has a fixed byte size.
+  if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Header)))
+    return createStringError(std::errc::invalid_argument,
+                             "not enough data for a gsym::Header");
+  Header H;
+  H.Magic = Data.getU32(&Offset);
+  H.Version = Data.getU16(&Offset);
+  H.AddrOffSize = Data.getU8(&Offset);
+  H.UUIDSize = Data.getU8(&Offset);
+  H.BaseAddress = Data.getU64(&Offset);
+  H.NumAddresses = Data.getU32(&Offset);
+  H.StrtabOffset = Data.getU32(&Offset);
+  H.StrtabSize = Data.getU32(&Offset);
+  Data.getU8(&Offset, H.UUID, GSYM_MAX_UUID_SIZE);
+  if (llvm::Error Err = H.checkForError())
+    return std::move(Err);
+  return H;
+}
+
+llvm::Error Header::encode(FileWriter &O) const {
+  // Users must verify the Header is valid prior to calling this funtion.
+  if (llvm::Error Err = checkForError())
+    return Err;
+  O.writeU32(Magic);
+  O.writeU16(Version);
+  O.writeU8(AddrOffSize);
+  O.writeU8(UUIDSize);
+  O.writeU64(BaseAddress);
+  O.writeU32(NumAddresses);
+  O.writeU32(StrtabOffset);
+  O.writeU32(StrtabSize);
+  O.writeData(llvm::ArrayRef<uint8_t>(UUID));
+  return Error::success();
+}
+
+bool llvm::gsym::operator==(const Header &LHS, const Header &RHS) {
+  return LHS.Magic == RHS.Magic && LHS.Version == RHS.Version &&
+      LHS.AddrOffSize == RHS.AddrOffSize && LHS.UUIDSize == RHS.UUIDSize &&
+      LHS.BaseAddress == RHS.BaseAddress &&
+      LHS.NumAddresses == RHS.NumAddresses &&
+      LHS.StrtabOffset == RHS.StrtabOffset &&
+      LHS.StrtabSize == RHS.StrtabSize &&
+      memcmp(LHS.UUID, RHS.UUID, LHS.UUIDSize) == 0;
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
index 781c175..1b8c974 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
@@ -1,14 +1,16 @@
 //===- InlineInfo.cpp -------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/GsymReader.h"
 #include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/Support/DataExtractor.h"
 #include <algorithm>
 #include <inttypes.h>
 
@@ -57,3 +59,203 @@
     return Result;
   return llvm::None;
 }
+
+/// Skip an InlineInfo object in the specified data at the specified offset.
+///
+/// Used during the InlineInfo::lookup() call to quickly skip child InlineInfo
+/// objects where the addres ranges isn't contained in the InlineInfo object
+/// or its children. This avoids allocations by not appending child InlineInfo
+/// objects to the InlineInfo::Children array.
+///
+/// \param Data The binary stream to read the data from.
+///
+/// \param Offset The byte offset within \a Data.
+///
+/// \param SkippedRanges If true, address ranges have already been skipped.
+
+static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges) {
+  if (!SkippedRanges) {
+    if (AddressRanges::skip(Data, Offset) == 0)
+      return false;
+  }
+  bool HasChildren = Data.getU8(&Offset) != 0;
+  Data.getU32(&Offset); // Skip Inline.Name.
+  Data.getULEB128(&Offset); // Skip Inline.CallFile.
+  Data.getULEB128(&Offset); // Skip Inline.CallLine.
+  if (HasChildren) {
+    while (skip(Data, Offset, false /* SkippedRanges */))
+      /* Do nothing */;
+  }
+  // We skipped a valid InlineInfo.
+  return true;
+}
+
+/// A Lookup helper functions.
+///
+/// Used during the InlineInfo::lookup() call to quickly only parse an
+/// InlineInfo object if the address falls within this object. This avoids
+/// allocations by not appending child InlineInfo objects to the
+/// InlineInfo::Children array and also skips any InlineInfo objects that do
+/// not contain the address we are looking up.
+///
+/// \param Data The binary stream to read the data from.
+///
+/// \param Offset The byte offset within \a Data.
+///
+/// \param BaseAddr The address that the relative address range offsets are
+///                 relative to.
+
+static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset,
+                   uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs,
+                   llvm::Error &Err) {
+  InlineInfo Inline;
+  Inline.Ranges.decode(Data, BaseAddr, Offset);
+  if (Inline.Ranges.empty())
+    return true;
+  // Check if the address is contained within the inline information, and if
+  // not, quickly skip this InlineInfo object and all its children.
+  if (!Inline.Ranges.contains(Addr)) {
+    skip(Data, Offset, true /* SkippedRanges */);
+    return false;
+  }
+
+  // The address range is contained within this InlineInfo, add the source
+  // location for this InlineInfo and any children that contain the address.
+  bool HasChildren = Data.getU8(&Offset) != 0;
+  Inline.Name = Data.getU32(&Offset);
+  Inline.CallFile = (uint32_t)Data.getULEB128(&Offset);
+  Inline.CallLine = (uint32_t)Data.getULEB128(&Offset);
+  if (HasChildren) {
+    // Child address ranges are encoded relative to the first address in the
+    // parent InlineInfo object.
+    const auto ChildBaseAddr = Inline.Ranges[0].Start;
+    bool Done = false;
+    while (!Done)
+      Done = lookup(GR, Data, Offset, ChildBaseAddr, Addr, SrcLocs, Err);
+  }
+
+  Optional<FileEntry> CallFile = GR.getFile(Inline.CallFile);
+  if (!CallFile) {
+    Err = createStringError(std::errc::invalid_argument,
+                            "failed to extract file[%" PRIu32 "]",
+                            Inline.CallFile);
+    return false;
+  }
+
+  SourceLocation SrcLoc;
+  SrcLoc.Name = SrcLocs.back().Name;
+  SrcLoc.Dir = GR.getString(CallFile->Dir);
+  SrcLoc.Base = GR.getString(CallFile->Base);
+  SrcLoc.Line = Inline.CallLine;
+  SrcLocs.back().Name = GR.getString(Inline.Name);
+  SrcLocs.push_back(SrcLoc);
+  return true;
+}
+
+llvm::Error InlineInfo::lookup(const GsymReader &GR, DataExtractor &Data,
+                               uint64_t BaseAddr, uint64_t Addr,
+                               SourceLocations &SrcLocs) {
+  // Call our recursive helper function starting at offset zero.
+  uint64_t Offset = 0;
+  llvm::Error Err = Error::success();
+  ::lookup(GR, Data, Offset, BaseAddr, Addr, SrcLocs, Err);
+  return Err;
+}
+
+/// Decode an InlineInfo in Data at the specified offset.
+///
+/// A local helper function to decode InlineInfo objects. This function is
+/// called recursively when parsing child InlineInfo objects.
+///
+/// \param Data The data extractor to decode from.
+/// \param Offset The offset within \a Data to decode from.
+/// \param BaseAddr The base address to use when decoding address ranges.
+/// \returns An InlineInfo or an error describing the issue that was
+/// encountered during decoding.
+static llvm::Expected<InlineInfo> decode(DataExtractor &Data, uint64_t &Offset,
+                                         uint64_t BaseAddr) {
+  InlineInfo Inline;
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing InlineInfo address ranges data", Offset);
+  Inline.Ranges.decode(Data, BaseAddr, Offset);
+  if (Inline.Ranges.empty())
+    return Inline;
+  if (!Data.isValidOffsetForDataOfSize(Offset, 1))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing InlineInfo uint8_t indicating children",
+        Offset);
+  bool HasChildren = Data.getU8(&Offset) != 0;
+  if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing InlineInfo uint32_t for name", Offset);
+  Inline.Name = Data.getU32(&Offset);
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call file", Offset);
+  Inline.CallFile = (uint32_t)Data.getULEB128(&Offset);
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call line", Offset);
+  Inline.CallLine = (uint32_t)Data.getULEB128(&Offset);
+  if (HasChildren) {
+    // Child address ranges are encoded relative to the first address in the
+    // parent InlineInfo object.
+    const auto ChildBaseAddr = Inline.Ranges[0].Start;
+    while (true) {
+      llvm::Expected<InlineInfo> Child = decode(Data, Offset, ChildBaseAddr);
+      if (!Child)
+        return Child.takeError();
+      // InlineInfo with empty Ranges termintes a child sibling chain.
+      if (Child.get().Ranges.empty())
+        break;
+      Inline.Children.emplace_back(std::move(*Child));
+    }
+  }
+  return Inline;
+}
+
+llvm::Expected<InlineInfo> InlineInfo::decode(DataExtractor &Data,
+                                              uint64_t BaseAddr) {
+  uint64_t Offset = 0;
+  return ::decode(Data, Offset, BaseAddr);
+}
+
+llvm::Error InlineInfo::encode(FileWriter &O, uint64_t BaseAddr) const {
+  // Users must verify the InlineInfo is valid prior to calling this funtion.
+  // We don't want to emit any InlineInfo objects if they are not valid since
+  // it will waste space in the GSYM file.
+  if (!isValid())
+    return createStringError(std::errc::invalid_argument,
+                             "attempted to encode invalid InlineInfo object");
+  Ranges.encode(O, BaseAddr);
+  bool HasChildren = !Children.empty();
+  O.writeU8(HasChildren);
+  O.writeU32(Name);
+  O.writeULEB(CallFile);
+  O.writeULEB(CallLine);
+  if (HasChildren) {
+    // Child address ranges are encoded as relative to the first
+    // address in the Ranges for this object. This keeps the offsets
+    // small and allows for efficient encoding using ULEB offsets.
+    const uint64_t ChildBaseAddr = Ranges[0].Start;
+    for (const auto &Child : Children) {
+      // Make sure all child address ranges are contained in the parent address
+      // ranges.
+      for (const auto &ChildRange: Child.Ranges) {
+        if (!Ranges.contains(ChildRange))
+          return createStringError(std::errc::invalid_argument,
+                                   "child range not contained in parent");
+      }
+      llvm::Error Err = Child.encode(O, ChildBaseAddr);
+      if (Err)
+        return Err;
+    }
+
+    // Terminate child sibling chain by emitting a zero. This zero will cause
+    // the decodeAll() function above to return false and stop the decoding
+    // of child InlineInfo objects that are siblings.
+    O.writeULEB(0);
+  }
+  return Error::success();
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/LLVMBuild.txt b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LLVMBuild.txt
index ff32425..d3cf765 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/GSYM/LLVMBuild.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LLVMBuild.txt
@@ -18,4 +18,4 @@
 type = Library
 name = DebugInfoGSYM
 parent = DebugInfo
-required_libraries = Support
+required_libraries = MC Support
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/LineTable.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LineTable.cpp
new file mode 100644
index 0000000..a49a3ba
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LineTable.cpp
@@ -0,0 +1,293 @@
+//===- LineTable.cpp --------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
+
+using namespace llvm;
+using namespace gsym;
+
+enum LineTableOpCode {
+  EndSequence = 0x00,  ///< End of the line table.
+  SetFile = 0x01,      ///< Set LineTableRow.file_idx, don't push a row.
+  AdvancePC = 0x02,    ///< Increment LineTableRow.address, and push a row.
+  AdvanceLine = 0x03,  ///< Set LineTableRow.file_line, don't push a row.
+  FirstSpecial = 0x04, ///< All special opcodes push a row.
+};
+
+struct DeltaInfo {
+  int64_t Delta;
+  uint32_t Count;
+  DeltaInfo(int64_t D, uint32_t C) : Delta(D), Count(C) {}
+};
+
+inline bool operator<(const DeltaInfo &LHS, int64_t Delta) {
+  return LHS.Delta < Delta;
+}
+
+static bool encodeSpecial(int64_t MinLineDelta, int64_t MaxLineDelta,
+                          int64_t LineDelta, uint64_t AddrDelta,
+                          uint8_t &SpecialOp) {
+  if (LineDelta < MinLineDelta)
+    return false;
+  if (LineDelta > MaxLineDelta)
+    return false;
+  int64_t LineRange = MaxLineDelta - MinLineDelta + 1;
+  int64_t AdjustedOp = ((LineDelta - MinLineDelta) + AddrDelta * LineRange);
+  int64_t Op = AdjustedOp + FirstSpecial;
+  if (Op < 0)
+    return false;
+  if (Op > 255)
+    return false;
+  SpecialOp = (uint8_t)Op;
+  return true;
+}
+
+typedef std::function<bool(const LineEntry &Row)> LineEntryCallback;
+
+static llvm::Error parse(DataExtractor &Data, uint64_t BaseAddr,
+                         LineEntryCallback const &Callback) {
+  uint64_t Offset = 0;
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing LineTable MinDelta", Offset);
+  int64_t MinDelta = Data.getSLEB128(&Offset);
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing LineTable MaxDelta", Offset);
+  int64_t MaxDelta = Data.getSLEB128(&Offset);
+  int64_t LineRange = MaxDelta - MinDelta + 1;
+  if (!Data.isValidOffset(Offset))
+    return createStringError(std::errc::io_error,
+        "0x%8.8" PRIx64 ": missing LineTable FirstLine", Offset);
+  const uint32_t FirstLine = (uint32_t)Data.getULEB128(&Offset);
+  LineEntry Row(BaseAddr, 1, FirstLine);
+  bool Done = false;
+  while (!Done) {
+    if (!Data.isValidOffset(Offset))
+      return createStringError(std::errc::io_error,
+          "0x%8.8" PRIx64 ": EOF found before EndSequence", Offset);
+    uint8_t Op = Data.getU8(&Offset);
+    switch (Op) {
+    case EndSequence:
+      Done = true;
+      break;
+    case SetFile:
+      if (!Data.isValidOffset(Offset))
+        return createStringError(std::errc::io_error,
+            "0x%8.8" PRIx64 ": EOF found before SetFile value",
+            Offset);
+      Row.File = (uint32_t)Data.getULEB128(&Offset);
+      break;
+    case AdvancePC:
+      if (!Data.isValidOffset(Offset))
+        return createStringError(std::errc::io_error,
+            "0x%8.8" PRIx64 ": EOF found before AdvancePC value",
+            Offset);
+      Row.Addr += Data.getULEB128(&Offset);
+      // If the function callback returns false, we stop parsing.
+      if (Callback(Row) == false)
+        return Error::success();
+      break;
+    case AdvanceLine:
+      if (!Data.isValidOffset(Offset))
+        return createStringError(std::errc::io_error,
+            "0x%8.8" PRIx64 ": EOF found before AdvanceLine value",
+            Offset);
+      Row.Line += Data.getSLEB128(&Offset);
+      break;
+    default: {
+        // A byte that contains both address and line increment.
+        uint8_t AdjustedOp = Op - FirstSpecial;
+        int64_t LineDelta = MinDelta + (AdjustedOp % LineRange);
+        uint64_t AddrDelta = (AdjustedOp / LineRange);
+        Row.Line += LineDelta;
+        Row.Addr += AddrDelta;
+        // If the function callback returns false, we stop parsing.
+        if (Callback(Row) == false)
+          return Error::success();
+        break;
+      }
+    }
+  }
+  return Error::success();
+}
+
+llvm::Error LineTable::encode(FileWriter &Out, uint64_t BaseAddr) const {
+  // Users must verify the LineTable is valid prior to calling this funtion.
+  // We don't want to emit any LineTable objects if they are not valid since
+  // it will waste space in the GSYM file.
+  if (!isValid())
+    return createStringError(std::errc::invalid_argument,
+                             "attempted to encode invalid LineTable object");
+
+  int64_t MinLineDelta = INT64_MAX;
+  int64_t MaxLineDelta = INT64_MIN;
+  std::vector<DeltaInfo> DeltaInfos;
+  if (Lines.size() == 1) {
+    MinLineDelta = 0;
+    MaxLineDelta = 0;
+  } else {
+    int64_t PrevLine = 1;
+    bool First = true;
+    for (const auto &line_entry : Lines) {
+      if (First)
+        First = false;
+      else {
+        int64_t LineDelta = (int64_t)line_entry.Line - PrevLine;
+        auto End = DeltaInfos.end();
+        auto Pos = std::lower_bound(DeltaInfos.begin(), End, LineDelta);
+        if (Pos != End && Pos->Delta == LineDelta)
+          ++Pos->Count;
+        else
+          DeltaInfos.insert(Pos, DeltaInfo(LineDelta, 1));
+        if (LineDelta < MinLineDelta)
+          MinLineDelta = LineDelta;
+        if (LineDelta > MaxLineDelta)
+          MaxLineDelta = LineDelta;
+      }
+      PrevLine = (int64_t)line_entry.Line;
+    }
+    assert(MinLineDelta <= MaxLineDelta);
+  }
+  // Set the min and max line delta intelligently based on the counts of
+  // the line deltas. if our range is too large.
+  const int64_t MaxLineRange = 14;
+  if (MaxLineDelta - MinLineDelta > MaxLineRange) {
+    uint32_t BestIndex = 0;
+    uint32_t BestEndIndex = 0;
+    uint32_t BestCount = 0;
+    const size_t NumDeltaInfos = DeltaInfos.size();
+    for (uint32_t I = 0; I < NumDeltaInfos; ++I) {
+      const int64_t FirstDelta = DeltaInfos[I].Delta;
+      uint32_t CurrCount = 0;
+      uint32_t J;
+      for (J = I; J < NumDeltaInfos; ++J) {
+        auto LineRange = DeltaInfos[J].Delta - FirstDelta;
+        if (LineRange > MaxLineRange)
+          break;
+        CurrCount += DeltaInfos[J].Count;
+      }
+      if (CurrCount > BestCount) {
+        BestIndex = I;
+        BestEndIndex = J - 1;
+        BestCount = CurrCount;
+      }
+    }
+    MinLineDelta = DeltaInfos[BestIndex].Delta;
+    MaxLineDelta = DeltaInfos[BestEndIndex].Delta;
+  }
+  if (MinLineDelta == MaxLineDelta && MinLineDelta > 0 &&
+      MinLineDelta < MaxLineRange)
+    MinLineDelta = 0;
+  assert(MinLineDelta <= MaxLineDelta);
+
+  // Initialize the line entry state as a starting point. All line entries
+  // will be deltas from this.
+  LineEntry Prev(BaseAddr, 1, Lines.front().Line);
+
+  // Write out the min and max line delta as signed LEB128.
+  Out.writeSLEB(MinLineDelta);
+  Out.writeSLEB(MaxLineDelta);
+  // Write out the starting line number as a unsigned LEB128.
+  Out.writeULEB(Prev.Line);
+
+  for (const auto &Curr : Lines) {
+    if (Curr.Addr < BaseAddr)
+      return createStringError(std::errc::invalid_argument,
+                               "LineEntry has address 0x%" PRIx64 " which is "
+                               "less than the function start address 0x%"
+                               PRIx64, Curr.Addr, BaseAddr);
+    if (Curr.Addr < Prev.Addr)
+      return createStringError(std::errc::invalid_argument,
+                               "LineEntry in LineTable not in ascending order");
+    const uint64_t AddrDelta = Curr.Addr - Prev.Addr;
+    int64_t LineDelta = 0;
+    if (Curr.Line > Prev.Line)
+      LineDelta = Curr.Line - Prev.Line;
+    else if (Prev.Line > Curr.Line)
+      LineDelta = -((int32_t)(Prev.Line - Curr.Line));
+
+    // Set the file if it doesn't match the current one.
+    if (Curr.File != Prev.File) {
+      Out.writeU8(SetFile);
+      Out.writeULEB(Curr.File);
+    }
+
+    uint8_t SpecialOp;
+    if (encodeSpecial(MinLineDelta, MaxLineDelta, LineDelta, AddrDelta,
+                      SpecialOp)) {
+      // Advance the PC and line and push a row.
+      Out.writeU8(SpecialOp);
+    } else {
+      // We can't encode the address delta and line delta into
+      // a single special opcode, we must do them separately.
+
+      // Advance the line.
+      if (LineDelta != 0) {
+        Out.writeU8(AdvanceLine);
+        Out.writeSLEB(LineDelta);
+      }
+
+      // Advance the PC and push a row.
+      Out.writeU8(AdvancePC);
+      Out.writeULEB(AddrDelta);
+    }
+    Prev = Curr;
+  }
+  Out.writeU8(EndSequence);
+  return Error::success();
+}
+
+// Parse all line table entries into the "LineTable" vector. We can
+// cache the results of this if needed, or we can call LineTable::lookup()
+// below.
+llvm::Expected<LineTable> LineTable::decode(DataExtractor &Data,
+                                            uint64_t BaseAddr) {
+  LineTable LT;
+  llvm::Error Err = parse(Data, BaseAddr, [&](const LineEntry &Row) -> bool {
+    LT.Lines.push_back(Row);
+    return true; // Keep parsing by returning true.
+  });
+  if (Err)
+    return std::move(Err);
+  return LT;
+}
+// Parse the line table on the fly and find the row we are looking for.
+// We will need to determine if we need to cache the line table by calling
+// LineTable::parseAllEntries(...) or just call this function each time.
+// There is a CPU vs memory tradeoff we will need to determined.
+Expected<LineEntry> LineTable::lookup(DataExtractor &Data, uint64_t BaseAddr, uint64_t Addr) {
+  LineEntry Result;
+  llvm::Error Err = parse(Data, BaseAddr,
+                          [Addr, &Result](const LineEntry &Row) -> bool {
+    if (Addr < Row.Addr)
+      return false; // Stop parsing, result contains the line table row!
+    Result = Row;
+    if (Addr == Row.Addr) {
+      // Stop parsing, this is the row we are looking for since the address
+      // matches.
+      return false;
+    }
+    return true; // Keep parsing till we find the right row.
+  });
+  if (Err)
+    return std::move(Err);
+  if (Result.isValid())
+    return Result;
+  return createStringError(std::errc::invalid_argument,
+                           "address 0x%" PRIx64 " is not in the line table",
+                           Addr);
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const LineTable &LT) {
+  for (const auto &LineEntry : LT)
+    OS << LineEntry << '\n';
+  return OS;
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/LookupResult.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LookupResult.cpp
new file mode 100644
index 0000000..c54b166
--- /dev/null
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/LookupResult.cpp
@@ -0,0 +1,69 @@
+//===- LookupResult.cpp -------------------------------------------------*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/LookupResult.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <ciso646>
+
+using namespace llvm;
+using namespace gsym;
+
+std::string LookupResult::getSourceFile(uint32_t Index) const {
+  std::string Fullpath;
+  if (Index < Locations.size()) {
+    if (!Locations[Index].Dir.empty()) {
+      if (Locations[Index].Base.empty()) {
+        Fullpath = Locations[Index].Dir;
+      } else {
+        llvm::SmallString<64> Storage;
+        llvm::sys::path::append(Storage, Locations[Index].Dir,
+                                Locations[Index].Base);
+        Fullpath.assign(Storage.begin(), Storage.end());
+      }
+    } else if (!Locations[Index].Base.empty())
+      Fullpath = Locations[Index].Base;
+  }
+  return Fullpath;
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const SourceLocation &SL) {
+  OS << SL.Name << " @ ";
+  if (!SL.Dir.empty()) {
+    OS << SL.Dir;
+    if (SL.Dir.contains('\\') and not SL.Dir.contains('/'))
+      OS << '\\';
+    else
+      OS << '/';
+  }
+  if (SL.Base.empty())
+    OS << "<invalid-file>";
+  else
+    OS << SL.Base;
+  OS << ':' << SL.Line;
+  return OS;
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const LookupResult &LR) {
+  OS << HEX64(LR.LookupAddr) << ": ";
+  auto NumLocations = LR.Locations.size();
+  for (size_t I = 0; I < NumLocations; ++I) {
+    if (I > 0) {
+      OS << '\n';
+      OS.indent(20);
+    }
+    const bool IsInlined = I + 1 != NumLocations;
+    OS << LR.Locations[I];
+    if (IsInlined)
+      OS << " [inlined]";
+  }
+  OS << '\n';
+  return OS;
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/GSYM/Range.cpp b/src/llvm-project/llvm/lib/DebugInfo/GSYM/Range.cpp
index ca61984..f78101e 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/GSYM/Range.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/GSYM/Range.cpp
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
 #include <algorithm>
 #include <inttypes.h>
 
@@ -40,6 +42,17 @@
   return It != Ranges.begin() && Addr < It[-1].End;
 }
 
+bool AddressRanges::contains(AddressRange Range) const {
+  if (Range.size() == 0)
+    return false;
+  auto It = std::partition_point(
+      Ranges.begin(), Ranges.end(),
+      [=](const AddressRange &R) { return R.Start <= Range.Start; });
+  if (It == Ranges.begin())
+    return false;
+  return Range.End <= It[-1].End;
+}
+
 raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) {
   return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")";
 }
@@ -53,3 +66,49 @@
   }
   return OS;
 }
+
+void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const {
+  assert(Start >= BaseAddr);
+  O.writeULEB(Start - BaseAddr);
+  O.writeULEB(size());
+}
+
+void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr,
+                          uint64_t &Offset) {
+  const uint64_t AddrOffset = Data.getULEB128(&Offset);
+  const uint64_t Size = Data.getULEB128(&Offset);
+  const uint64_t StartAddr = BaseAddr + AddrOffset;
+  Start = StartAddr;
+  End = StartAddr + Size;
+}
+
+void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const {
+  O.writeULEB(Ranges.size());
+  if (Ranges.empty())
+    return;
+  for (auto Range : Ranges)
+    Range.encode(O, BaseAddr);
+}
+
+void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr,
+                           uint64_t &Offset) {
+  clear();
+  uint64_t NumRanges = Data.getULEB128(&Offset);
+  if (NumRanges == 0)
+    return;
+  Ranges.resize(NumRanges);
+  for (auto &Range : Ranges)
+    Range.decode(Data, BaseAddr, Offset);
+}
+
+void AddressRange::skip(DataExtractor &Data, uint64_t &Offset) {
+  Data.getULEB128(&Offset);
+  Data.getULEB128(&Offset);
+}
+
+uint64_t AddressRanges::skip(DataExtractor &Data, uint64_t &Offset) {
+  uint64_t NumRanges = Data.getULEB128(&Offset);
+  for (uint64_t I=0; I<NumRanges; ++I)
+    AddressRange::skip(Data, Offset);
+  return NumRanges;
+}
diff --git a/src/llvm-project/llvm/lib/DebugInfo/MSF/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/MSF/CMakeLists.txt
index 6f38de3..828e261 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/MSF/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/MSF/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_library(LLVMDebugInfoMSF
+add_llvm_component_library(LLVMDebugInfoMSF
   MappedBlockStream.cpp
   MSFBuilder.cpp
   MSFCommon.cpp
diff --git a/src/llvm-project/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/src/llvm-project/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
index df92577..5dc9c86 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -52,7 +52,7 @@
 std::unique_ptr<MappedBlockStream> MappedBlockStream::createStream(
     uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData,
     BumpPtrAllocator &Allocator) {
-  return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+  return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
       BlockSize, Layout, MsfData, Allocator);
 }
 
@@ -63,7 +63,7 @@
   MSFStreamLayout SL;
   SL.Blocks = Layout.StreamMap[StreamIndex];
   SL.Length = Layout.StreamSizes[StreamIndex];
-  return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+  return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
       Layout.SB->BlockSize, SL, MsfData, Allocator);
 }
 
@@ -318,7 +318,7 @@
                                         const MSFStreamLayout &Layout,
                                         WritableBinaryStreamRef MsfData,
                                         BumpPtrAllocator &Allocator) {
-  return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
+  return std::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
       BlockSize, Layout, MsfData, Allocator);
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 0e842af..320ca78 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -84,7 +84,7 @@
 list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/Native")
 list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")
 
-add_llvm_library(LLVMDebugInfoPDB
+add_llvm_component_library(LLVMDebugInfoPDB
   GenericError.cpp
   IPDBSourceFile.cpp
   PDB.cpp
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index a8ae076..c2552f5 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -405,7 +405,7 @@
       return nullptr;
   }
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -423,7 +423,7 @@
       Symbol->findChildrenEx(EnumVal, Name16Str, CompareFlags, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -443,7 +443,7 @@
                                            Section, Offset, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -462,7 +462,7 @@
                                          &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -480,7 +480,7 @@
                                           &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -489,7 +489,7 @@
   if (S_OK != Symbol->findInlineFramesByAddr(Section, Offset, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -498,7 +498,7 @@
   if (S_OK != Symbol->findInlineFramesByRVA(RVA, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumSymbols>
@@ -507,7 +507,7 @@
   if (S_OK != Symbol->findInlineFramesByVA(VA, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+  return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers> DIARawSymbol::findInlineeLines() const {
@@ -515,7 +515,7 @@
   if (S_OK != Symbol->findInlineeLines(&DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+  return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -526,7 +526,7 @@
       Symbol->findInlineeLinesByAddr(Section, Offset, Length, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+  return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -535,7 +535,7 @@
   if (S_OK != Symbol->findInlineeLinesByRVA(RVA, Length, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+  return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -544,7 +544,7 @@
   if (S_OK != Symbol->findInlineeLinesByVA(VA, Length, &DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+  return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
 }
 
 void DIARawSymbol::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const {
@@ -776,7 +776,7 @@
   if (FAILED(Symbol->getSrcLineOnTypeDefn(&LineNumber)) || !LineNumber)
     return nullptr;
 
-  return llvm::make_unique<DIALineNumber>(LineNumber);
+  return std::make_unique<DIALineNumber>(LineNumber);
 }
 
 uint32_t DIARawSymbol::getStride() const {
@@ -871,7 +871,7 @@
   if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType)
     return nullptr;
 
-  auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
+  auto RawVT = std::make_unique<DIARawSymbol>(Session, TableType);
   auto Pointer =
       PDBSymbol::createAs<PDBSymbolTypePointer>(Session, std::move(RawVT));
   return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
index e2d928f..4f0e078 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
@@ -23,7 +23,7 @@
   if (FAILED(Section->get_compiland(&Symbol)))
     return nullptr;
 
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(Session, Symbol);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(Session, Symbol);
   return PDBSymbol::createAs<PDBSymbolCompiland>(Session, std::move(RawSymbol));
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
index 4e0b858..64ffa77 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -73,15 +73,7 @@
 #if !defined(_MSC_VER)
   return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading);
 #else
-  const wchar_t *msdia_dll = nullptr;
-#if _MSC_VER >= 1900 && _MSC_VER < 2000
-  msdia_dll = L"msdia140.dll"; // VS2015
-#elif _MSC_VER >= 1800
-  msdia_dll = L"msdia120.dll"; // VS2013
-#else
-#error "Unknown Visual Studio version."
-#endif
-
+  const wchar_t *msdia_dll = L"msdia140.dll";
   HRESULT HR;
   if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
                                 reinterpret_cast<LPVOID *>(&DiaDataSource))))
@@ -158,7 +150,7 @@
   if (S_OK != Session->get_globalScope(&GlobalScope))
     return nullptr;
 
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(*this, GlobalScope);
   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
   std::unique_ptr<PDBSymbolExe> ExeSymbol(
       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
@@ -193,7 +185,7 @@
   if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
     return nullptr;
 
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(*this, LocatedSymbol);
   return PDBSymbol::create(*this, std::move(RawSymbol));
 }
 
@@ -210,7 +202,7 @@
     if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
       return nullptr;
   }
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
   return PDBSymbol::create(*this, std::move(RawSymbol));
 }
 
@@ -222,7 +214,7 @@
   if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
     return nullptr;
 
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
   return PDBSymbol::create(*this, std::move(RawSymbol));
 }
 
@@ -235,7 +227,7 @@
   if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol))
     return nullptr;
 
-  auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+  auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
   return PDBSymbol::create(*this, std::move(RawSymbol));
 }
 
@@ -251,7 +243,7 @@
                                  RawFile.getDiaFile(), &LineNumbers))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+  return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -265,7 +257,7 @@
     if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
       return nullptr;
   }
-  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+  return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -274,7 +266,7 @@
   if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+  return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
@@ -284,7 +276,7 @@
   if (S_OK != Session->findLinesByAddr(Section, Offset, Length, &LineNumbers))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+  return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
 }
 
 std::unique_ptr<IPDBEnumSourceFiles>
@@ -306,7 +298,7 @@
   if (S_OK !=
       Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles))
     return nullptr;
-  return llvm::make_unique<DIAEnumSourceFiles>(*this, SourceFiles);
+  return std::make_unique<DIAEnumSourceFiles>(*this, SourceFiles);
 }
 
 std::unique_ptr<IPDBSourceFile>
@@ -342,7 +334,7 @@
   if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
+  return std::make_unique<DIAEnumSourceFiles>(*this, Files);
 }
 
 std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
@@ -355,7 +347,7 @@
       Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
+  return std::make_unique<DIAEnumSourceFiles>(*this, Files);
 }
 
 std::unique_ptr<IPDBSourceFile>
@@ -364,7 +356,7 @@
   if (S_OK != Session->findFileById(FileId, &LocatedFile))
     return nullptr;
 
-  return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
+  return std::make_unique<DIASourceFile>(*this, LocatedFile);
 }
 
 std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
@@ -372,7 +364,7 @@
   if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
+  return std::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
 }
 
 std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const {
@@ -380,7 +372,7 @@
   if (S_OK != Session->getEnumTables(&DiaEnumerator))
     return nullptr;
 
-  return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
+  return std::make_unique<DIAEnumTables>(DiaEnumerator);
 }
 
 template <class T> static CComPtr<T> getTableEnumerator(IDiaSession &Session) {
@@ -407,7 +399,7 @@
   if (!Files)
     return nullptr;
 
-  return llvm::make_unique<DIAEnumInjectedSources>(Files);
+  return std::make_unique<DIAEnumInjectedSources>(Files);
 }
 
 std::unique_ptr<IPDBEnumSectionContribs>
@@ -417,7 +409,7 @@
   if (!Sections)
     return nullptr;
 
-  return llvm::make_unique<DIAEnumSectionContribs>(*this, Sections);
+  return std::make_unique<DIAEnumSectionContribs>(*this, Sections);
 }
 
 std::unique_ptr<IPDBEnumFrameData>
@@ -427,5 +419,5 @@
   if (!FD)
     return nullptr;
 
-  return llvm::make_unique<DIAEnumFrameData>(FD);
+  return std::make_unique<DIAEnumFrameData>(FD);
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/GenericError.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/GenericError.cpp
index 70dc094..0e4cba3 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/GenericError.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/GenericError.cpp
@@ -34,8 +34,8 @@
       return "The PDB file path is an invalid UTF8 sequence.";
     case pdb_error_code::signature_out_of_date:
       return "The signature does not match; the file(s) might be out of date.";
-    case pdb_error_code::external_cmdline_ref:
-      return "The path to this file must be provided on the command-line.";
+    case pdb_error_code::no_matching_pch:
+      return "No matching precompiled header could be located.";
     }
     llvm_unreachable("Unrecognized generic_error_code");
   }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
index 5095efc..9755f2c 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
@@ -18,13 +18,6 @@
 using namespace llvm::pdb;
 using namespace llvm::support;
 
-DbiModuleDescriptor::DbiModuleDescriptor() = default;
-
-DbiModuleDescriptor::DbiModuleDescriptor(const DbiModuleDescriptor &Info) =
-    default;
-
-DbiModuleDescriptor::~DbiModuleDescriptor() = default;
-
 Error DbiModuleDescriptor::initialize(BinaryStreamRef Stream,
                                       DbiModuleDescriptor &Info) {
   BinaryStreamReader Reader(Stream);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 20b6c61..4197347 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -180,12 +180,12 @@
 void DbiModuleDescriptorBuilder::addDebugSubsection(
     std::shared_ptr<DebugSubsection> Subsection) {
   assert(Subsection);
-  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+  C13Builders.push_back(std::make_unique<DebugSubsectionRecordBuilder>(
       std::move(Subsection), CodeViewContainer::Pdb));
 }
 
 void DbiModuleDescriptorBuilder::addDebugSubsection(
     const DebugSubsectionRecord &SubsectionContents) {
-  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+  C13Builders.push_back(std::make_unique<DebugSubsectionRecordBuilder>(
       SubsectionContents, CodeViewContainer::Pdb));
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index b7ade007..0e00c2f 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -114,7 +114,7 @@
 DbiStreamBuilder::addModuleInfo(StringRef ModuleName) {
   uint32_t Index = ModiList.size();
   ModiList.push_back(
-      llvm::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
+      std::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
   return *ModiList.back();
 }
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 8ed5b8b..432f1e9 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -183,8 +183,8 @@
 }
 
 GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
-    : Msf(Msf), PSH(llvm::make_unique<GSIHashStreamBuilder>()),
-      GSH(llvm::make_unique<GSIHashStreamBuilder>()) {}
+    : Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
+      GSH(std::make_unique<GSIHashStreamBuilder>()) {}
 
 GSIStreamBuilder::~GSIStreamBuilder() {}
 
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/Hash.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/Hash.cpp
index b5c139e..7fb6b4b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/Hash.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/Hash.cpp
@@ -8,8 +8,8 @@
 
 #include "llvm/DebugInfo/PDB/Native/Hash.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/CRC.h"
 #include "llvm/Support/Endian.h"
-#include "llvm/Support/JamCRC.h"
 #include <cstdint>
 
 using namespace llvm;
@@ -79,7 +79,6 @@
 // Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
 uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
   JamCRC JC(/*Init=*/0U);
-  JC.update(makeArrayRef<char>(reinterpret_cast<const char *>(Buf.data()),
-                               Buf.size()));
+  JC.update(Buf);
   return JC.getCRC();
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
index f17ff5b..2f6a5bc 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
@@ -46,30 +46,31 @@
   uint64_t getCodeByteSize() const override { return Entry.FileSize; }
 
   std::string getFileName() const override {
-    auto Name = Strings.getStringForID(Entry.FileNI);
-    assert(Name && "InjectedSourceStream should have rejected this");
-    return *Name;
+    StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
+                             "InjectedSourceStream should have rejected this");
+    return Ret;
   }
 
   std::string getObjectFileName() const override {
-    auto ObjName = Strings.getStringForID(Entry.ObjNI);
-    assert(ObjName && "InjectedSourceStream should have rejected this");
-    return *ObjName;
+    StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
+                             "InjectedSourceStream should have rejected this");
+    return Ret;
   }
 
   std::string getVirtualFileName() const override {
-    auto VName = Strings.getStringForID(Entry.VFileNI);
-    assert(VName && "InjectedSourceStream should have rejected this");
-    return *VName;
+    StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
+                             "InjectedSourceStream should have rejected this");
+    return Ret;
   }
 
   uint32_t getCompression() const override { return Entry.Compression; }
 
   std::string getCode() const override {
     // Get name of stream storing the data.
-    auto VName = Strings.getStringForID(Entry.VFileNI);
-    assert(VName && "InjectedSourceStream should have rejected this");
-    std::string StreamName = ("/src/files/" + *VName).str();
+    StringRef VName =
+        cantFail(Strings.getStringForID(Entry.VFileNI),
+                 "InjectedSourceStream should have rejected this");
+    std::string StreamName = ("/src/files/" + VName).str();
 
     // Find stream with that name and read its data.
     // FIXME: Consider validating (or even loading) all this in
@@ -104,14 +105,14 @@
 NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
   if (N >= getChildCount())
     return nullptr;
-  return make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
+  return std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
                                            File, Strings);
 }
 
 std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
   if (Cur == Stream.end())
     return nullptr;
-  return make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
+  return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
 }
 
 void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 8e43cf2..2ad5524 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -30,68 +30,68 @@
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findChildren(PDB_SymType Type) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
     PDB_NameSearchFlags Flags) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
     PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
    PDB_NameSearchFlags Flags, uint64_t VA) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
     PDB_NameSearchFlags Flags, uint32_t RVA) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
                                         uint32_t Offset) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
-  return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+  return std::make_unique<NullEnumerator<PDBSymbol>>();
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
 NativeRawSymbol::findInlineeLines() const {
-  return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+  return std::make_unique<NullEnumerator<IPDBLineNumber>>();
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
 NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
                                         uint32_t Length) const {
-  return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+  return std::make_unique<NullEnumerator<IPDBLineNumber>>();
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
 NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
-  return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+  return std::make_unique<NullEnumerator<IPDBLineNumber>>();
 }
 
 std::unique_ptr<IPDBEnumLineNumbers>
 NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
-  return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+  return std::make_unique<NullEnumerator<IPDBLineNumber>>();
 }
 
 void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 8a49cb1..b45a588 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -59,18 +59,18 @@
 Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
                                    std::unique_ptr<IPDBSession> &Session) {
   StringRef Path = Buffer->getBufferIdentifier();
-  auto Stream = llvm::make_unique<MemoryBufferByteStream>(
+  auto Stream = std::make_unique<MemoryBufferByteStream>(
       std::move(Buffer), llvm::support::little);
 
-  auto Allocator = llvm::make_unique<BumpPtrAllocator>();
-  auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
+  auto Allocator = std::make_unique<BumpPtrAllocator>();
+  auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
   if (auto EC = File->parseFileHeaders())
     return EC;
   if (auto EC = File->parseStreamData())
     return EC;
 
   Session =
-      llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
+      std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
 
   return Error::success();
 }
@@ -202,7 +202,7 @@
     consumeError(Strings.takeError());
     return nullptr;
   }
-  return make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
+  return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
 }
 
 std::unique_ptr<IPDBEnumSectionContribs>
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
index 9f5e862..26ccb7d 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -163,14 +163,14 @@
 std::unique_ptr<IPDBEnumSymbols>
 NativeTypeEnum::findChildren(PDB_SymType Type) const {
   if (Type != PDB_SymType::Data)
-    return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+    return std::make_unique<NullEnumerator<PDBSymbol>>();
 
   const NativeTypeEnum *ClassParent = nullptr;
   if (!Modifiers)
     ClassParent = this;
   else
     ClassParent = UnmodifiedType;
-  return llvm::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
+  return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
 }
 
 PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
index 4053034..f98a4c3 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
@@ -65,7 +65,7 @@
   std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
     if (!S)
       return nullptr;
-    auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
+    auto NTFA = std::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
     return PDBSymbol::create(Session, std::move(NTFA));
   }
   NativeSession &Session;
@@ -133,9 +133,9 @@
 std::unique_ptr<IPDBEnumSymbols>
 NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
   if (Type != PDB_SymType::FunctionArg)
-    return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+    return std::make_unique<NullEnumerator<PDBSymbol>>();
 
-  auto NET = llvm::make_unique<NativeEnumTypes>(Session,
+  auto NET = std::make_unique<NativeEnumTypes>(Session,
                                                 /* copy */ ArgList.ArgIndices);
   return std::unique_ptr<IPDBEnumSymbols>(
       new NativeEnumFunctionArgs(Session, std::move(NET)));
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 983031d..9ac226b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -264,7 +264,7 @@
         safelyCreateIndexedStream(DbiS->getGlobalSymbolStreamIndex());
     if (!GlobalS)
       return GlobalS.takeError();
-    auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS));
+    auto TempGlobals = std::make_unique<GlobalsStream>(std::move(*GlobalS));
     if (auto EC = TempGlobals->reload())
       return std::move(EC);
     Globals = std::move(TempGlobals);
@@ -277,7 +277,7 @@
     auto InfoS = safelyCreateIndexedStream(StreamPDB);
     if (!InfoS)
       return InfoS.takeError();
-    auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
+    auto TempInfo = std::make_unique<InfoStream>(std::move(*InfoS));
     if (auto EC = TempInfo->reload())
       return std::move(EC);
     Info = std::move(TempInfo);
@@ -290,7 +290,7 @@
     auto DbiS = safelyCreateIndexedStream(StreamDBI);
     if (!DbiS)
       return DbiS.takeError();
-    auto TempDbi = llvm::make_unique<DbiStream>(std::move(*DbiS));
+    auto TempDbi = std::make_unique<DbiStream>(std::move(*DbiS));
     if (auto EC = TempDbi->reload(this))
       return std::move(EC);
     Dbi = std::move(TempDbi);
@@ -303,7 +303,7 @@
     auto TpiS = safelyCreateIndexedStream(StreamTPI);
     if (!TpiS)
       return TpiS.takeError();
-    auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
+    auto TempTpi = std::make_unique<TpiStream>(*this, std::move(*TpiS));
     if (auto EC = TempTpi->reload())
       return std::move(EC);
     Tpi = std::move(TempTpi);
@@ -319,7 +319,7 @@
     auto IpiS = safelyCreateIndexedStream(StreamIPI);
     if (!IpiS)
       return IpiS.takeError();
-    auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
+    auto TempIpi = std::make_unique<TpiStream>(*this, std::move(*IpiS));
     if (auto EC = TempIpi->reload())
       return std::move(EC);
     Ipi = std::move(TempIpi);
@@ -337,7 +337,7 @@
         safelyCreateIndexedStream(DbiS->getPublicSymbolStreamIndex());
     if (!PublicS)
       return PublicS.takeError();
-    auto TempPublics = llvm::make_unique<PublicsStream>(std::move(*PublicS));
+    auto TempPublics = std::make_unique<PublicsStream>(std::move(*PublicS));
     if (auto EC = TempPublics->reload())
       return std::move(EC);
     Publics = std::move(TempPublics);
@@ -356,7 +356,7 @@
     if (!SymbolS)
       return SymbolS.takeError();
 
-    auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
+    auto TempSymbols = std::make_unique<SymbolStream>(std::move(*SymbolS));
     if (auto EC = TempSymbols->reload())
       return std::move(EC);
     Symbols = std::move(TempSymbols);
@@ -370,7 +370,7 @@
     if (!NS)
       return NS.takeError();
 
-    auto N = llvm::make_unique<PDBStringTable>();
+    auto N = std::make_unique<PDBStringTable>();
     BinaryStreamReader Reader(**NS);
     if (auto EC = N->reload(Reader))
       return std::move(EC);
@@ -391,7 +391,7 @@
     if (!Strings)
       return Strings.takeError();
 
-    auto IJ = llvm::make_unique<InjectedSourceStream>(std::move(*IJS));
+    auto IJ = std::make_unique<InjectedSourceStream>(std::move(*IJS));
     if (auto EC = IJ->reload(*Strings))
       return std::move(EC);
     InjectedSources = std::move(IJ);
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 8f5a048..aa32887 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -22,7 +22,7 @@
 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
 #include "llvm/Support/BinaryStream.h"
 #include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/CRC.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/xxhash.h"
 
@@ -42,7 +42,7 @@
   auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
   if (!ExpectedMsf)
     return ExpectedMsf.takeError();
-  Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
+  Msf = std::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
   return Error::success();
 }
 
@@ -50,25 +50,25 @@
 
 InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
   if (!Info)
-    Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
+    Info = std::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
   return *Info;
 }
 
 DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
   if (!Dbi)
-    Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
+    Dbi = std::make_unique<DbiStreamBuilder>(*Msf);
   return *Dbi;
 }
 
 TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
   if (!Tpi)
-    Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
+    Tpi = std::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
   return *Tpi;
 }
 
 TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
   if (!Ipi)
-    Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
+    Ipi = std::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
   return *Ipi;
 }
 
@@ -78,7 +78,7 @@
 
 GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
   if (!Gsi)
-    Gsi = llvm::make_unique<GSIStreamBuilder>(*Msf);
+    Gsi = std::make_unique<GSIStreamBuilder>(*Msf);
   return *Gsi;
 }
 
@@ -174,8 +174,7 @@
   if (!InjectedSources.empty()) {
     for (const auto &IS : InjectedSources) {
       JamCRC CRC(0);
-      CRC.update(makeArrayRef(IS.Content->getBufferStart(),
-                              IS.Content->getBufferSize()));
+      CRC.update(arrayRefFromStringRef(IS.Content->getBuffer()));
 
       SrcHeaderBlockEntry Entry;
       ::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp
index b21b82b..b71b2b1 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiHashing.cpp
@@ -10,7 +10,7 @@
 
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/CRC.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
@@ -124,8 +124,6 @@
 
   // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
   JamCRC JC(/*Init=*/0U);
-  ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()),
-                       Rec.data().size());
-  JC.update(Bytes);
+  JC.update(Rec.data());
   return JC.getCRC();
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp
index 8ee7f89..ac19db0 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -112,7 +112,7 @@
     HashStream = std::move(*HS);
   }
 
-  Types = llvm::make_unique<LazyRandomTypeCollection>(
+  Types = std::make_unique<LazyRandomTypeCollection>(
       TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
   return Error::success();
 }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 6b30845..51a1f0a 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -44,6 +44,9 @@
 void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
                                      Optional<uint32_t> Hash) {
   // If we just crossed an 8KB threshold, add a type index offset.
+  assert(((Record.size() & 3) == 0) &&
+         "The type record's size is not a multiple of 4 bytes which will "
+         "cause misalignment in the output TPI stream!");
   size_t NewSize = TypeRecordBytes + Record.size();
   constexpr size_t EightKB = 8 * 1024;
   if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) {
@@ -135,7 +138,7 @@
         reinterpret_cast<const uint8_t *>(HashBuffer.data()),
         calculateHashBufferSize());
     HashValueStream =
-        llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
+        std::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
   }
   return Error::success();
 }
@@ -153,8 +156,11 @@
     return EC;
 
   for (auto Rec : TypeRecords) {
-    assert(!Rec.empty()); // An empty record will not write anything, but it
-                          // would shift all offsets from here on.
+    assert(!Rec.empty() && "Attempting to write an empty type record shifts "
+                           "all offsets in the TPI stream!");
+    assert(((Rec.size() & 3) == 0) &&
+           "The type record's size is not a multiple of 4 bytes which will "
+           "cause misalignment in the output TPI stream!");
     if (auto EC = Writer.writeBytes(Rec))
       return EC;
   }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index 7c3ba98..cb0329b 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -79,7 +79,7 @@
 
 std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
 PDBSymbolFunc::getArguments() const {
-  return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+  return std::make_unique<FunctionArgEnumerator>(Session, *this);
 }
 
 void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
index 292320a..1373615 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
@@ -63,7 +63,7 @@
 
 std::unique_ptr<IPDBEnumSymbols>
 PDBSymbolTypeFunctionSig::getArguments() const {
-  return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+  return std::make_unique<FunctionArgEnumerator>(Session, *this);
 }
 
 void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
diff --git a/src/llvm-project/llvm/lib/DebugInfo/PDB/UDTLayout.cpp b/src/llvm-project/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
index acb1599..a8e1d0a 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -71,7 +71,7 @@
       DataMember(std::move(Member)) {
   auto Type = DataMember->getType();
   if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
-    UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
+    UdtLayout = std::make_unique<ClassLayout>(std::move(UDT));
     UsedBytes = UdtLayout->usedBytes();
   }
 }
@@ -84,7 +84,7 @@
 }
 
 const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
-  return *dyn_cast<PDBSymbolData>(Symbol);
+  return *cast<PDBSymbolData>(Symbol);
 }
 
 bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
@@ -205,7 +205,7 @@
   for (auto &Base : Bases) {
     uint32_t Offset = Base->getOffset();
     // Non-virtual bases never get elided.
-    auto BL = llvm::make_unique<BaseClassLayout>(*this, Offset, false,
+    auto BL = std::make_unique<BaseClassLayout>(*this, Offset, false,
                                                  std::move(Base));
 
     AllBases.push_back(BL.get());
@@ -216,7 +216,7 @@
   assert(VTables.size() <= 1);
   if (!VTables.empty()) {
     auto VTLayout =
-        llvm::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
+        std::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
 
     VTable = VTLayout.get();
 
@@ -224,7 +224,7 @@
   }
 
   for (auto &Data : Members) {
-    auto DM = llvm::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
+    auto DM = std::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
 
     addChildToLayout(std::move(DM));
   }
@@ -236,7 +236,7 @@
     int VBPO = VB->getVirtualBasePointerOffset();
     if (!hasVBPtrAtOffset(VBPO)) {
       if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
-        auto VBPL = llvm::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+        auto VBPL = std::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
                                                        VBPO, VBP->getLength());
         VBPtr = VBPL.get();
         addChildToLayout(std::move(VBPL));
@@ -250,7 +250,7 @@
     uint32_t Offset = UsedBytes.find_last() + 1;
     bool Elide = (Parent != nullptr);
     auto BL =
-        llvm::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+        std::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
     AllBases.push_back(BL.get());
 
     // Only lay this virtual base out directly inside of *this* class if this
diff --git a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/CMakeLists.txt b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/CMakeLists.txt
index fe5c4bf..79fbb14 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/CMakeLists.txt
+++ b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/CMakeLists.txt
@@ -1,4 +1,4 @@
-add_llvm_library(LLVMSymbolize
+add_llvm_component_library(LLVMSymbolize
   DIPrinter.cpp
   SymbolizableObjectFile.cpp
   Symbolize.cpp
diff --git a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index b2bfef2..2f3a250 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -30,11 +30,6 @@
 namespace llvm {
 namespace symbolize {
 
-// By default, DILineInfo contains "<invalid>" for function/filename it
-// cannot fetch. We replace it to "??" to make our output closer to addr2line.
-static const char kDILineInfoBadString[] = "<invalid>";
-static const char kBadString[] = "??";
-
 // Prints source code around in the FileName the Line.
 void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
   if (PrintSourceContext <= 0)
@@ -68,16 +63,16 @@
 void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
   if (PrintFunctionNames) {
     std::string FunctionName = Info.FunctionName;
-    if (FunctionName == kDILineInfoBadString)
-      FunctionName = kBadString;
+    if (FunctionName == DILineInfo::BadString)
+      FunctionName = DILineInfo::Addr2LineBadString;
 
     StringRef Delimiter = PrintPretty ? " at " : "\n";
     StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
     OS << Prefix << FunctionName << Delimiter;
   }
   std::string Filename = Info.FileName;
-  if (Filename == kDILineInfoBadString)
-    Filename = kBadString;
+  if (Filename == DILineInfo::BadString)
+    Filename = DILineInfo::Addr2LineBadString;
   else if (Basenames)
     Filename = llvm::sys::path::filename(Filename);
   if (!Verbose) {
@@ -115,29 +110,40 @@
 
 DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
   std::string Name = Global.Name;
-  if (Name == kDILineInfoBadString)
-    Name = kBadString;
+  if (Name == DILineInfo::BadString)
+    Name = DILineInfo::Addr2LineBadString;
   OS << Name << "\n";
   OS << Global.Start << " " << Global.Size << "\n";
   return *this;
 }
 
 DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
-  OS << Local.FunctionName << '\n';
-  OS << Local.Name << '\n';
+  if (Local.FunctionName.empty())
+    OS << "??\n";
+  else
+    OS << Local.FunctionName << '\n';
+
+  if (Local.Name.empty())
+    OS << "??\n";
+  else
+    OS << Local.Name << '\n';
+
   if (Local.DeclFile.empty())
     OS << "??";
   else
     OS << Local.DeclFile;
   OS << ':' << Local.DeclLine << '\n';
+
   if (Local.FrameOffset)
     OS << *Local.FrameOffset << ' ';
   else
     OS << "?? ";
+
   if (Local.Size)
     OS << *Local.Size << ' ';
   else
     OS << "?? ";
+
   if (Local.TagOffset)
     OS << *Local.TagOffset << '\n';
   else
diff --git a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 2765bf4..b4d49d9 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -43,20 +43,22 @@
 
 ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
 SymbolizableObjectFile::create(const object::ObjectFile *Obj,
-                               std::unique_ptr<DIContext> DICtx) {
+                               std::unique_ptr<DIContext> DICtx,
+                               bool UntagAddresses) {
   assert(DICtx);
   std::unique_ptr<SymbolizableObjectFile> res(
-      new SymbolizableObjectFile(Obj, std::move(DICtx)));
+      new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses));
   std::unique_ptr<DataExtractor> OpdExtractor;
   uint64_t OpdAddress = 0;
   // Find the .opd (function descriptor) section if any, for big-endian
   // PowerPC64 ELF.
   if (Obj->getArch() == Triple::ppc64) {
     for (section_iterator Section : Obj->sections()) {
-      StringRef Name;
-      if (auto EC = Section->getName(Name))
-        return EC;
-      if (Name == ".opd") {
+      Expected<StringRef> NameOrErr = Section->getName();
+      if (!NameOrErr)
+        return errorToErrorCode(NameOrErr.takeError());
+
+      if (*NameOrErr == ".opd") {
         Expected<StringRef> E = Section->getContents();
         if (!E)
           return errorToErrorCode(E.takeError());
@@ -103,8 +105,10 @@
 }
 
 SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj,
-                                               std::unique_ptr<DIContext> DICtx)
-    : Module(Obj), DebugInfoContext(std::move(DICtx)) {}
+                                               std::unique_ptr<DIContext> DICtx,
+                                               bool UntagAddresses)
+    : Module(Obj), DebugInfoContext(std::move(DICtx)),
+      UntagAddresses(UntagAddresses) {}
 
 namespace {
 
@@ -172,6 +176,12 @@
   if (!SymbolAddressOrErr)
     return errorToErrorCode(SymbolAddressOrErr.takeError());
   uint64_t SymbolAddress = *SymbolAddressOrErr;
+  if (UntagAddresses) {
+    // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55
+    // into bits 56-63 instead of masking them out.
+    SymbolAddress &= (1ull << 56) - 1;
+    SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8;
+  }
   if (OpdExtractor) {
     // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
     // function descriptors. The first word of the descriptor is a pointer to
@@ -179,10 +189,8 @@
     // For the purposes of symbolization, pretend the symbol's address is that
     // of the function's code, not the descriptor.
     uint64_t OpdOffset = SymbolAddress - OpdAddress;
-    uint32_t OpdOffset32 = OpdOffset;
-    if (OpdOffset == OpdOffset32 &&
-        OpdExtractor->isValidOffsetForAddress(OpdOffset32))
-      SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
+    if (OpdExtractor->isValidOffsetForAddress(OpdOffset))
+      SymbolAddress = OpdExtractor->getAddress(&OpdOffset);
   }
   Expected<StringRef> SymbolNameOrErr = Symbol.getName();
   if (!SymbolNameOrErr)
diff --git a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 9cab941..b5b9793 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -31,7 +31,8 @@
 class SymbolizableObjectFile : public SymbolizableModule {
 public:
   static ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
-  create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx);
+  create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
+         bool UntagAddresses);
 
   DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
                            FunctionNameKind FNKind,
@@ -70,6 +71,7 @@
 
   const object::ObjectFile *Module;
   std::unique_ptr<DIContext> DebugInfoContext;
+  bool UntagAddresses;
 
   struct SymbolDesc {
     uint64_t Addr;
@@ -85,7 +87,8 @@
   std::vector<std::pair<SymbolDesc, StringRef>> Objects;
 
   SymbolizableObjectFile(const object::ObjectFile *Obj,
-                         std::unique_ptr<DIContext> DICtx);
+                         std::unique_ptr<DIContext> DICtx,
+                         bool UntagAddresses);
 };
 
 } // end namespace symbolize
diff --git a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 6a619f8..35e3ead 100644
--- a/src/llvm-project/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/src/llvm-project/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -35,19 +35,6 @@
 #include <cassert>
 #include <cstring>
 
-#if defined(_MSC_VER)
-#include <Windows.h>
-
-// This must be included after windows.h.
-#include <DbgHelp.h>
-#pragma comment(lib, "dbghelp.lib")
-
-// Windows.h conflicts with our COFF header definitions.
-#ifdef IMAGE_FILE_MACHINE_I386
-#undef IMAGE_FILE_MACHINE_I386
-#endif
-#endif
-
 namespace llvm {
 namespace symbolize {
 
@@ -205,7 +192,7 @@
       MemoryBuffer::getFileOrSTDIN(Path);
   if (!MB)
     return false;
-  return CRCHash == llvm::crc32(0, MB.get()->getBuffer());
+  return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer()));
 }
 
 bool findDebugBinary(const std::string &OrigPath,
@@ -259,7 +246,11 @@
     return false;
   for (const SectionRef &Section : Obj->sections()) {
     StringRef Name;
-    Section.getName(Name);
+    if (Expected<StringRef> NameOrErr = Section.getName())
+      Name = *NameOrErr;
+    else
+      consumeError(NameOrErr.takeError());
+
     Name = Name.substr(Name.find_first_not_of("._"));
     if (Name == "gnu_debuglink") {
       Expected<StringRef> ContentsOrErr = Section.getContents();
@@ -268,7 +259,7 @@
         return false;
       }
       DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0);
-      uint32_t Offset = 0;
+      uint64_t Offset = 0;
       if (const char *DebugNameStr = DE.getCStr(&Offset)) {
         // 4-byte align the offset.
         Offset = (Offset + 3) & ~0x3;
@@ -293,6 +284,79 @@
   return !memcmp(dbg_uuid.data(), bin_uuid.data(), dbg_uuid.size());
 }
 
+template <typename ELFT>
+Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> *Obj) {
+  if (!Obj)
+    return {};
+  auto PhdrsOrErr = Obj->program_headers();
+  if (!PhdrsOrErr) {
+    consumeError(PhdrsOrErr.takeError());
+    return {};
+  }
+  for (const auto &P : *PhdrsOrErr) {
+    if (P.p_type != ELF::PT_NOTE)
+      continue;
+    Error Err = Error::success();
+    for (auto N : Obj->notes(P, Err))
+      if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU)
+        return N.getDesc();
+  }
+  return {};
+}
+
+Optional<ArrayRef<uint8_t>> getBuildID(const ELFObjectFileBase *Obj) {
+  Optional<ArrayRef<uint8_t>> BuildID;
+  if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
+    BuildID = getBuildID(O->getELFFile());
+  else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
+    BuildID = getBuildID(O->getELFFile());
+  else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
+    BuildID = getBuildID(O->getELFFile());
+  else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
+    BuildID = getBuildID(O->getELFFile());
+  else
+    llvm_unreachable("unsupported file format");
+  return BuildID;
+}
+
+bool findDebugBinary(const std::vector<std::string> &DebugFileDirectory,
+                     const ArrayRef<uint8_t> BuildID,
+                     std::string &Result) {
+  auto getDebugPath = [&](StringRef Directory) {
+    SmallString<128> Path{Directory};
+    sys::path::append(Path, ".build-id",
+                      llvm::toHex(BuildID[0], /*LowerCase=*/true),
+                      llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
+    Path += ".debug";
+    return Path;
+  };
+  if (DebugFileDirectory.empty()) {
+    SmallString<128> Path = getDebugPath(
+#if defined(__NetBSD__)
+      // Try /usr/libdata/debug/.build-id/../...
+      "/usr/libdata/debug"
+#else
+      // Try /usr/lib/debug/.build-id/../...
+      "/usr/lib/debug"
+#endif
+    );
+    if (llvm::sys::fs::exists(Path)) {
+      Result = Path.str();
+      return true;
+    }
+  } else {
+    for (const auto &Directory : DebugFileDirectory) {
+      // Try <debug-file-directory>/.build-id/../...
+      SmallString<128> Path = getDebugPath(Directory);
+      if (llvm::sys::fs::exists(Path)) {
+        Result = Path.str();
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 } // end anonymous namespace
 
 ObjectFile *LLVMSymbolizer::lookUpDsymFile(const std::string &ExePath,
@@ -344,6 +408,25 @@
   return DbgObjOrErr.get();
 }
 
+ObjectFile *LLVMSymbolizer::lookUpBuildIDObject(const std::string &Path,
+                                                const ELFObjectFileBase *Obj,
+                                                const std::string &ArchName) {
+  auto BuildID = getBuildID(Obj);
+  if (!BuildID)
+    return nullptr;
+  if (BuildID->size() < 2)
+    return nullptr;
+  std::string DebugBinaryPath;
+  if (!findDebugBinary(Opts.DebugFileDirectory, *BuildID, DebugBinaryPath))
+    return nullptr;
+  auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
+  if (!DbgObjOrErr) {
+    consumeError(DbgObjOrErr.takeError());
+    return nullptr;
+  }
+  return DbgObjOrErr.get();
+}
+
 Expected<LLVMSymbolizer::ObjectPair>
 LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
                                       const std::string &ArchName) {
@@ -364,6 +447,8 @@
 
   if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
     DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
+  else if (auto ELFObj = dyn_cast<const ELFObjectFileBase>(Obj))
+    DbgObj = lookUpBuildIDObject(Path, ELFObj, ArchName);
   if (!DbgObj)
     DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName);
   if (!DbgObj)
@@ -397,7 +482,7 @@
       return I->second.get();
 
     Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
-        UB->getObjectForArch(ArchName);
+        UB->getMachOObjectForArch(ArchName);
     if (!ObjOrErr) {
       ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
                                      std::unique_ptr<ObjectFile>());
@@ -418,8 +503,8 @@
 LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
                                  std::unique_ptr<DIContext> Context,
                                  StringRef ModuleName) {
-  auto InfoOrErr =
-      SymbolizableObjectFile::create(Obj, std::move(Context));
+  auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context),
+                                                  Opts.UntagAddresses);
   std::unique_ptr<SymbolizableModule> SymMod;
   if (InfoOrErr)
     SymMod = std::move(*InfoOrErr);
@@ -530,21 +615,20 @@
     return Result;
   }
 
-#if defined(_MSC_VER)
   if (!Name.empty() && Name.front() == '?') {
     // Only do MSVC C++ demangling on symbols starting with '?'.
-    char DemangledName[1024] = {0};
-    DWORD result = ::UnDecorateSymbolName(
-        Name.c_str(), DemangledName, 1023,
-        UNDNAME_NO_ACCESS_SPECIFIERS |       // Strip public, private, protected
-            UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc
-            UNDNAME_NO_THROW_SIGNATURES |    // Strip throw() specifications
-            UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
-            UNDNAME_NO_MS_KEYWORDS | // Strip all MS extension keywords
-            UNDNAME_NO_FUNCTION_RETURNS); // Strip function return types
-    return (result == 0) ? Name : std::string(DemangledName);
+    int status = 0;
+    char *DemangledName = microsoftDemangle(
+        Name.c_str(), nullptr, nullptr, &status,
+        MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention |
+                        MSDF_NoMemberType | MSDF_NoReturnType));
+    if (status != 0)
+      return Name;
+    std::string Result = DemangledName;
+    free(DemangledName);
+    return Result;
   }
-#endif
+
   if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module())
     return std::string(demanglePE32ExternCFunc(Name));
   return Name;