Importing rustc-1.56.0

Change-Id: I98941481270706fa55f8fb2cb91686ae3bd30f38
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
index 7cae4cc..42d73ce 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -11,6 +11,7 @@
 #include "ABISysV_arm64.h"
 #include "Utility/ARM64_DWARF_Registers.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
 
 LLDB_PLUGIN_DEFINE(ABIAArch64)
 
@@ -24,6 +25,18 @@
   ABIMacOSX_arm64::Terminate();
 }
 
+lldb::addr_t ABIAArch64::FixCodeAddress(lldb::addr_t pc) {
+  if (lldb::ProcessSP process_sp = GetProcessSP())
+    return FixAddress(pc, process_sp->GetCodeAddressMask());
+  return pc;
+}
+
+lldb::addr_t ABIAArch64::FixDataAddress(lldb::addr_t pc) {
+  if (lldb::ProcessSP process_sp = GetProcessSP())
+    return FixAddress(pc, process_sp->GetDataAddressMask());
+  return pc;
+}
+
 std::pair<uint32_t, uint32_t>
 ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
   if (name == "pc")
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
index bdff648..41bbf5c 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
@@ -16,7 +16,14 @@
   static void Initialize();
   static void Terminate();
 
+  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
+  virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
+
 protected:
+  virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) {
+    return pc;
+  }
+
   std::pair<uint32_t, uint32_t>
   GetEHAndDWARFNums(llvm::StringRef name) override;
 
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index 09b319a..348a081 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -66,7 +66,7 @@
 
   if (log) {
     StreamString s;
-    s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
+    s.Printf("ABIMacOSX_arm64::PrepareTrivialCall (tid = 0x%" PRIx64
              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
              ", return_addr = 0x%" PRIx64,
              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
@@ -86,7 +86,7 @@
       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
 
   // x0 - x7 contain first 8 simple args
-  if (args.size() > 8) // TODO handle more than 6 arguments
+  if (args.size() > 8) // TODO handle more than 8 arguments
     return false;
 
   for (size_t i = 0; i < args.size(); ++i) {
@@ -384,6 +384,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
@@ -654,7 +655,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -814,6 +815,11 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
+  lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+  return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
+}
+
 void ABIMacOSX_arm64::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
                                 CreateInstance);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
index fc8ccee..dc3ab35 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -62,6 +62,8 @@
     return true;
   }
 
+  lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
   // Static Functions
 
   static void Initialize();
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index 1214195..16fb38e 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -356,6 +356,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
@@ -622,7 +623,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -781,6 +782,61 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) {
+  lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+  return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
+}
+
+// Reads code or data address mask for the current Linux process.
+static lldb::addr_t ReadLinuxProcessAddressMask(lldb::ProcessSP process_sp,
+                                                llvm::StringRef reg_name) {
+  // Linux configures user-space virtual addresses with top byte ignored.
+  // We set default value of mask such that top byte is masked out.
+  uint64_t address_mask = ~((1ULL << 56) - 1);
+  // If Pointer Authentication feature is enabled then Linux exposes
+  // PAC data and code mask register. Try reading relevant register
+  // below and merge it with default address mask calculated above.
+  lldb::ThreadSP thread_sp = process_sp->GetThreadList().GetSelectedThread();
+  if (thread_sp) {
+    lldb::RegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+    if (reg_ctx_sp) {
+      const RegisterInfo *reg_info =
+          reg_ctx_sp->GetRegisterInfoByName(reg_name, 0);
+      if (reg_info) {
+        lldb::addr_t mask_reg_val = reg_ctx_sp->ReadRegisterAsUnsigned(
+            reg_info->kinds[eRegisterKindLLDB], LLDB_INVALID_ADDRESS);
+        if (mask_reg_val != LLDB_INVALID_ADDRESS)
+          address_mask |= mask_reg_val;
+      }
+    }
+  }
+  return address_mask;
+}
+
+lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t pc) {
+  if (lldb::ProcessSP process_sp = GetProcessSP()) {
+    if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
+        !process_sp->GetCodeAddressMask())
+      process_sp->SetCodeAddressMask(
+          ReadLinuxProcessAddressMask(process_sp, "code_mask"));
+
+    return FixAddress(pc, process_sp->GetCodeAddressMask());
+  }
+  return pc;
+}
+
+lldb::addr_t ABISysV_arm64::FixDataAddress(lldb::addr_t pc) {
+  if (lldb::ProcessSP process_sp = GetProcessSP()) {
+    if (process_sp->GetTarget().GetArchitecture().GetTriple().isOSLinux() &&
+        !process_sp->GetDataAddressMask())
+      process_sp->SetDataAddressMask(
+          ReadLinuxProcessAddressMask(process_sp, "data_mask"));
+
+    return FixAddress(pc, process_sp->GetDataAddressMask());
+  }
+  return pc;
+}
+
 void ABISysV_arm64::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 "SysV ABI for AArch64 targets", CreateInstance);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
index aeb74ac..3428a7a 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -67,6 +67,8 @@
 
   bool GetPointerReturnRegister(const char *&name) override;
 
+  lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
   // Static Functions
 
   static void Initialize();
@@ -83,6 +85,9 @@
 
   uint32_t GetPluginVersion() override;
 
+  lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
+  lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
+
 protected:
   lldb::ValueObjectSP
   GetReturnValueObjectImpl(lldb_private::Thread &thread,
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/src/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
index be85867..60cdbc5 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp
@@ -466,7 +466,7 @@
     if (!SetSizedInteger(value.GetScalar(), raw_value, byte_size, is_signed))
       return ValueObjectSP();
 
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
   }
   // Pointer return type.
   else if (type_flags & eTypeIsPointer) {
@@ -474,7 +474,7 @@
                                                 LLDB_REGNUM_GENERIC_ARG1);
     value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
 
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
   }
   // Floating point return type.
   else if (type_flags & eTypeIsFloat) {
@@ -537,7 +537,7 @@
     auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
                                                 LLDB_REGNUM_GENERIC_ARG1);
     value.GetScalar() = reg_ctx->ReadRegisterAsUnsigned(reg_info_r0, 0);
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
   }
   // Floating point return type.
   else if (retType.isFloatingPointTy()) {
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
index 06c4590..e429f3e 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp
@@ -1824,6 +1824,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
index 26b3152..3e544e0 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp
@@ -1617,7 +1617,7 @@
         thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
         UINT32_MAX;
     value.GetScalar() = ptr;
-  } else if (compiler_type.IsVectorType(nullptr, nullptr)) {
+  } else if (compiler_type.IsVectorType()) {
     if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
       is_vfp_candidate = true;
       vfp_byte_size = 8;
@@ -1704,7 +1704,7 @@
       if (homogeneous_count > 0 && homogeneous_count <= 4) {
         llvm::Optional<uint64_t> base_byte_size =
             base_type.GetByteSize(&thread);
-        if (base_type.IsVectorType(nullptr, nullptr)) {
+        if (base_type.IsVectorType()) {
           if (base_byte_size &&
               (*base_byte_size == 8 || *base_byte_size == 16)) {
             is_vfp_candidate = true;
@@ -1940,6 +1940,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/src/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
index 47aaefd..6794f7d 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
@@ -1225,6 +1225,7 @@
 
   UnwindPlan::RowSP row(new UnwindPlan::Row);
 
+  row->SetUnspecifiedRegistersAreUndefined(true);
   row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
index d66e092..538ec06 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp
@@ -985,6 +985,7 @@
 
   UnwindPlan::RowSP row(new UnwindPlan::Row);
 
+  row->SetUnspecifiedRegistersAreUndefined(true);
   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
 
   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
index 7515557..7220508 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp
@@ -764,7 +764,7 @@
   const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
 
   if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
@@ -1156,6 +1156,7 @@
 
   UnwindPlan::RowSP row(new UnwindPlan::Row);
 
+  row->SetUnspecifiedRegistersAreUndefined(true);
   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
 
   row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
index 91d2e59..98a14b5 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp
@@ -520,7 +520,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
   if (type_flags & eTypeIsScalar) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger) {
@@ -603,7 +603,7 @@
         reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
     value.GetScalar() =
         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     return_valobj_sp = ValueObjectConstResult::Create(
         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
   } else if (type_flags & eTypeIsVector) {
@@ -683,8 +683,6 @@
       r3_value.GetData(r3_data);
       rdx_value.GetData(rdx_data);
 
-      uint32_t fp_bytes =
-          0; // Tracks how much of the xmm registers we've consumed so far
       uint32_t integer_bytes =
           0; // Tracks how much of the r3/rds registers we've consumed so far
 
@@ -751,7 +749,6 @@
             break;
           } else if (*field_bit_width == 64) {
             copy_from_offset = 0;
-            fp_bytes += field_byte_width;
           } else if (*field_bit_width == 32) {
             // This one is kind of complicated.  If we are in an "eightbyte"
             // with another float, we'll be stuffed into an xmm register with
@@ -815,8 +812,6 @@
                 copy_from_offset = integer_bytes - 8;
                 integer_bytes += field_byte_width;
               }
-            } else {
-              fp_bytes += field_byte_width;
             }
           }
         }
@@ -900,6 +895,7 @@
   UnwindPlan::RowSP row(new UnwindPlan::Row);
 
   const int32_t ptr_size = 4;
+  row->SetUnspecifiedRegistersAreUndefined(true);
   row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
 
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
index c7cb773..7cc9482 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
@@ -577,7 +577,7 @@
   ValueSP NewScalarValue(CompilerType &type) {
     ValueSP value_sp(new Value);
     value_sp->SetCompilerType(type);
-    value_sp->SetValueType(Value::eValueTypeScalar);
+    value_sp->SetValueType(Value::ValueType::Scalar);
     return value_sp;
   }
 
@@ -1003,6 +1003,7 @@
 
   UnwindPlan::RowSP row(new UnwindPlan::Row);
   const int32_t ptr_size = 8;
+  row->SetUnspecifiedRegistersAreUndefined(true);
   row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
 
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/src/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
index 22a6417..88e8511 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp
@@ -487,7 +487,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
   if (type_flags & eTypeIsScalar) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger) {
@@ -571,7 +571,7 @@
         reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
     value.GetScalar() =
         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     return_valobj_sp = ValueObjectConstResult::Create(
         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
   }
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
index 89112de..461e4af 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp
@@ -389,6 +389,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
index 2f47d3f..7d2f0a6 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp
@@ -378,14 +378,14 @@
     uint32_t ptr =
         thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
         0xffffffff;
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     value.GetScalar() = ptr;
     return_valobj_sp = ValueObjectConstResult::Create(
         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
   } else if ((type_flags & eTypeIsScalar) ||
              (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
   {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     llvm::Optional<uint64_t> byte_size =
         return_compiler_type.GetByteSize(&thread);
     if (!byte_size)
@@ -453,7 +453,7 @@
       uint32_t enm =
           thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
           0xffffffff;
-      value.SetValueType(Value::eValueTypeScalar);
+      value.SetValueType(Value::ValueType::Scalar);
       value.GetScalar() = enm;
       return_valobj_sp = ValueObjectConstResult::Create(
           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
@@ -652,6 +652,7 @@
 
   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
index 2aa2c02..196b45b 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
@@ -399,7 +399,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
   if (type_flags & eTypeIsScalar) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger) {
@@ -487,7 +487,7 @@
     value.GetScalar() =
         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
                                                                       0);
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     return_valobj_sp = ValueObjectConstResult::Create(
         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
   } else if (type_flags & eTypeIsVector) {
@@ -887,6 +887,7 @@
   const int32_t ptr_size = 8;
   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
index 06e0ce4..6c473c6 100644
--- a/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
@@ -408,7 +408,7 @@
 
   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
   if (type_flags & eTypeIsScalar) {
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
 
     bool success = false;
     if (type_flags & eTypeIsInteger) {
@@ -494,7 +494,7 @@
     value.GetScalar() =
         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
                                                                       0);
-    value.SetValueType(Value::eValueTypeScalar);
+    value.SetValueType(Value::ValueType::Scalar);
     return_valobj_sp = ValueObjectConstResult::Create(
         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
   } else if (type_flags & eTypeIsVector) {
@@ -767,6 +767,7 @@
   const int32_t ptr_size = 8;
   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
   row->SetOffset(0);
+  row->SetUnspecifiedRegistersAreUndefined(true);
 
   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
diff --git a/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
new file mode 100644
index 0000000..9994cc2
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
@@ -0,0 +1,45 @@
+//===-- ArchitectureAArch64.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 "Plugins/Architecture/AArch64/ArchitectureAArch64.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/ArchSpec.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+LLDB_PLUGIN_DEFINE(ArchitectureAArch64)
+
+ConstString ArchitectureAArch64::GetPluginNameStatic() {
+  return ConstString("aarch64");
+}
+
+void ArchitectureAArch64::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                "AArch64-specific algorithms",
+                                &ArchitectureAArch64::Create);
+}
+
+void ArchitectureAArch64::Terminate() {
+  PluginManager::UnregisterPlugin(&ArchitectureAArch64::Create);
+}
+
+std::unique_ptr<Architecture>
+ArchitectureAArch64::Create(const ArchSpec &arch) {
+  auto machine = arch.GetMachine();
+  if (machine != llvm::Triple::aarch64 && machine != llvm::Triple::aarch64_be &&
+      machine != llvm::Triple::aarch64_32) {
+    return nullptr;
+  }
+  return std::unique_ptr<Architecture>(new ArchitectureAArch64());
+}
+
+ConstString ArchitectureAArch64::GetPluginName() {
+  return GetPluginNameStatic();
+}
+uint32_t ArchitectureAArch64::GetPluginVersion() { return 1; }
diff --git a/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
new file mode 100644
index 0000000..775478c
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h
@@ -0,0 +1,40 @@
+//===-- ArchitectureAArch64.h -----------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
+#define LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
+
+#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureAArch64 : public Architecture {
+public:
+  static ConstString GetPluginNameStatic();
+  static void Initialize();
+  static void Terminate();
+
+  ConstString GetPluginName() override;
+  uint32_t GetPluginVersion() override;
+
+  void OverrideStopInfo(Thread &thread) const override{};
+
+  const MemoryTagManager *GetMemoryTagManager() const override {
+    return &m_memory_tag_manager;
+  }
+
+private:
+  static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+  ArchitectureAArch64() = default;
+  MemoryTagManagerAArch64MTE m_memory_tag_manager;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_ARCHITECTURE_AARCH64_ARCHITECTUREAARCH64_H
diff --git a/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/CMakeLists.txt
new file mode 100644
index 0000000..9bcf993
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Architecture/AArch64/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginArchitectureAArch64 PLUGIN
+  ArchitectureAArch64.cpp
+
+  LINK_LIBS
+    lldbPluginProcessUtility
+    lldbCore
+    lldbTarget
+    lldbUtility
+  LINK_COMPONENTS
+    Support
+  )
diff --git a/src/llvm-project/lldb/source/Plugins/Architecture/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Architecture/CMakeLists.txt
index 14ad916..9ed8edf 100644
--- a/src/llvm-project/lldb/source/Plugins/Architecture/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Architecture/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_subdirectory(Arm)
 add_subdirectory(Mips)
 add_subdirectory(PPC64)
+add_subdirectory(AArch64)
diff --git a/src/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/src/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
index 2250896..757c915 100644
--- a/src/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -160,7 +160,6 @@
 
   InstructionList instruction_list;
   InstructionSP prev_insn;
-  bool prefer_file_cache = true; // Read from file
   uint32_t inst_to_choose = 0;
 
   Address addr = resolved_addr;
@@ -171,8 +170,7 @@
     uint32_t insn_size = 0;
 
     disasm_sp->ParseInstructions(target, addr,
-                                 {Disassembler::Limit::Bytes, i * 2}, nullptr,
-                                 prefer_file_cache);
+                                 {Disassembler::Limit::Bytes, i * 2}, nullptr);
 
     uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
     if (num_insns) {
diff --git a/src/llvm-project/lldb/source/Plugins/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/CMakeLists.txt
index 3da23ec..9181a4e 100644
--- a/src/llvm-project/lldb/source/Plugins/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/CMakeLists.txt
@@ -20,6 +20,7 @@
 add_subdirectory(SystemRuntime)
 add_subdirectory(SymbolVendor)
 add_subdirectory(Trace)
+add_subdirectory(TraceExporter)
 add_subdirectory(TypeSystem)
 add_subdirectory(UnwindAssembly)
 
diff --git a/src/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/src/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 8a2d323..7cd505d 100644
--- a/src/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -905,7 +905,8 @@
     return Instance();
 
   std::unique_ptr<llvm::MCContext> context_up(
-      new llvm::MCContext(asm_info_up.get(), reg_info_up.get(), nullptr));
+      new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
+                          reg_info_up.get(), subtarget_info_up.get()));
   if (!context_up)
     return Instance();
 
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index fd1916d..07b3da0 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -35,7 +35,7 @@
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
 #ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
 #else
 #define DEBUG_PRINTF(fmt, ...)
@@ -107,7 +107,7 @@
     m_collection_sp->Initialize(g_dynamicloaderdarwinkernel_properties);
   }
 
-  ~DynamicLoaderDarwinKernelProperties() override {}
+  ~DynamicLoaderDarwinKernelProperties() override = default;
 
   bool GetLoadKexts() const {
     const uint32_t idx = ePropertyLoadKexts;
@@ -1093,16 +1093,16 @@
     uint8_t buf[24];
     DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
     const size_t count = 4 * sizeof(uint32_t) + addr_size;
-    const bool prefer_file_cache = false;
+    const bool force_live_memory = true;
     if (m_process->GetTarget().ReadPointerFromMemory(
-            m_kext_summary_header_ptr_addr, prefer_file_cache, error,
-            m_kext_summary_header_addr)) {
+            m_kext_summary_header_ptr_addr, error,
+            m_kext_summary_header_addr, force_live_memory)) {
       // We got a valid address for our kext summary header and make sure it
       // isn't NULL
       if (m_kext_summary_header_addr.IsValid() &&
           m_kext_summary_header_addr.GetFileAddress() != 0) {
         const size_t bytes_read = m_process->GetTarget().ReadMemory(
-            m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
+            m_kext_summary_header_addr, buf, count, error, force_live_memory);
         if (bytes_read == count) {
           lldb::offset_t offset = 0;
           m_kext_summary_header.version = data.GetU32(&offset);
@@ -1373,10 +1373,9 @@
   DataBufferHeap data(count, 0);
   Status error;
 
-  const bool prefer_file_cache = false;
+  const bool force_live_memory = true;
   const size_t bytes_read = m_process->GetTarget().ReadMemory(
-      kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
-      error);
+      kext_summary_addr, data.GetBytes(), data.GetByteSize(), error, force_live_memory);
   if (bytes_read == count) {
 
     DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index 8659cd5..225d069 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -125,11 +125,7 @@
 
   class KextImageInfo {
   public:
-    KextImageInfo()
-        : m_name(), m_module_sp(), m_memory_module_sp(),
-          m_load_process_stop_id(UINT32_MAX), m_uuid(),
-          m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
-          m_kernel_image(false) {}
+    KextImageInfo() : m_name(), m_module_sp(), m_memory_module_sp(), m_uuid() {}
 
     void Clear() {
       m_load_address = LLDB_INVALID_ADDRESS;
@@ -201,24 +197,24 @@
     std::string m_name;
     lldb::ModuleSP m_module_sp;
     lldb::ModuleSP m_memory_module_sp;
-    uint32_t m_load_process_stop_id; // the stop-id when this module was added
-                                     // to the Target
+    uint32_t m_load_process_stop_id =
+        UINT32_MAX; // the stop-id when this module was added
+                    // to the Target
     lldb_private::UUID
         m_uuid; // UUID for this dylib if it has one, else all zeros
-    lldb::addr_t m_load_address;
-    uint64_t m_size;
-    bool m_kernel_image; // true if this is the kernel, false if this is a kext
+    lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS;
+    uint64_t m_size = 0;
+    bool m_kernel_image =
+        false; // true if this is the kernel, false if this is a kext
   };
 
   struct OSKextLoadedKextSummaryHeader {
-    uint32_t version;
-    uint32_t entry_size;
-    uint32_t entry_count;
-    lldb::addr_t image_infos_addr;
+    uint32_t version = 0;
+    uint32_t entry_size = 0;
+    uint32_t entry_count = 0;
+    lldb::addr_t image_infos_addr = LLDB_INVALID_ADDRESS;
 
-    OSKextLoadedKextSummaryHeader()
-        : version(0), entry_size(0), entry_count(0),
-          image_infos_addr(LLDB_INVALID_ADDRESS) {}
+    OSKextLoadedKextSummaryHeader() = default;
 
     uint32_t GetSize() {
       switch (version) {
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index 5707f88..c34e02e 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -35,15 +35,13 @@
   // the layout of this struct is not binary compatible, it is simply large
   // enough to hold the information on both 32 and 64 bit platforms.
   struct Rendezvous {
-    uint64_t version;
-    lldb::addr_t map_addr;
-    lldb::addr_t brk;
-    uint64_t state;
-    lldb::addr_t ldbase;
+    uint64_t version = 0;
+    lldb::addr_t map_addr = LLDB_INVALID_ADDRESS;
+    lldb::addr_t brk = LLDB_INVALID_ADDRESS;
+    uint64_t state = 0;
+    lldb::addr_t ldbase = 0;
 
-    Rendezvous()
-        : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
-          state(0), ldbase(0) {}
+    Rendezvous() = default;
   };
 
 public:
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index ddf6f12..95bd398 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -36,7 +36,7 @@
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
 #ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
 #else
 #define DEBUG_PRINTF(fmt, ...)
@@ -60,7 +60,7 @@
       m_dyld_image_infos_stop_id(UINT32_MAX), m_dyld(), m_mutex() {}
 
 // Destructor
-DynamicLoaderDarwin::~DynamicLoaderDarwin() {}
+DynamicLoaderDarwin::~DynamicLoaderDarwin() = default;
 
 /// Called after attaching a process.
 ///
@@ -1086,7 +1086,7 @@
     Status error;
     const size_t tsl_data_size = addr_size * 3;
     Target &target = m_process->GetTarget();
-    if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) ==
+    if (target.ReadMemory(tls_addr, buf, tsl_data_size, error, true) ==
         tsl_data_size) {
       const ByteOrder byte_order = m_process->GetByteOrder();
       DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
index 4c9a27f..1b705e9 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -73,19 +73,17 @@
 
   class Segment {
   public:
-    Segment()
-        : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
-          filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
+    Segment() : name() {}
 
     lldb_private::ConstString name;
-    lldb::addr_t vmaddr;
-    lldb::addr_t vmsize;
-    lldb::addr_t fileoff;
-    lldb::addr_t filesize;
-    uint32_t maxprot;
-    uint32_t initprot;
-    uint32_t nsects;
-    uint32_t flags;
+    lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS;
+    lldb::addr_t vmsize = 0;
+    lldb::addr_t fileoff = 0;
+    lldb::addr_t filesize = 0;
+    uint32_t maxprot = 0;
+    uint32_t initprot = 0;
+    uint32_t nsects = 0;
+    uint32_t flags = 0;
 
     bool operator==(const Segment &rhs) const {
       return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 656a5bf..cad8a43 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -244,18 +244,18 @@
         clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
             lldb::eEncodingUint, 32);
 
-    mode_value.SetValueType(Value::eValueTypeScalar);
+    mode_value.SetValueType(Value::ValueType::Scalar);
     mode_value.SetCompilerType(clang_uint32_type);
 
     if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4) {
-      count_value.SetValueType(Value::eValueTypeScalar);
+      count_value.SetValueType(Value::ValueType::Scalar);
       count_value.SetCompilerType(clang_uint32_type);
     } else {
-      count_value.SetValueType(Value::eValueTypeScalar);
+      count_value.SetValueType(Value::ValueType::Scalar);
       count_value.SetCompilerType(clang_uint64_type);
     }
 
-    headers_value.SetValueType(Value::eValueTypeScalar);
+    headers_value.SetValueType(Value::ValueType::Scalar);
     headers_value.SetCompilerType(clang_void_ptr_type);
 
     argument_values.PushValue(mode_value);
@@ -343,29 +343,26 @@
 
 bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
   if (m_break_id == LLDB_INVALID_BREAK_ID) {
-    ConstString g_symbol_name("_dyld_debugger_notification");
-    const Symbol *symbol = nullptr;
     ModuleSP dyld_sp(GetDYLDModule());
     if (dyld_sp) {
-      symbol = dyld_sp->FindFirstSymbolWithNameAndType(g_symbol_name,
-                                                       eSymbolTypeCode);
-    }
-    if (symbol &&
-        (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
-      addr_t symbol_address =
-          symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
-      if (symbol_address != LLDB_INVALID_ADDRESS) {
-        bool internal = true;
-        bool hardware = false;
-        Breakpoint *breakpoint =
-            m_process->GetTarget()
-                .CreateBreakpoint(symbol_address, internal, hardware)
-                .get();
-        breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
-                                true);
-        breakpoint->SetBreakpointKind("shared-library-event");
-        m_break_id = breakpoint->GetID();
-      }
+      bool internal = true;
+      bool hardware = false;
+      LazyBool skip_prologue = eLazyBoolNo;
+      FileSpecList *source_files = nullptr;
+      FileSpecList dyld_filelist;
+      dyld_filelist.Append(dyld_sp->GetObjectFile()->GetFileSpec());
+
+      Breakpoint *breakpoint =
+          m_process->GetTarget()
+              .CreateBreakpoint(&dyld_filelist, source_files,
+                                "_dyld_debugger_notification",
+                                eFunctionNameTypeFull, eLanguageTypeC, 0,
+                                skip_prologue, internal, hardware)
+              .get();
+      breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
+                              true);
+      breakpoint->SetBreakpointKind("shared-library-event");
+      m_break_id = breakpoint->GetID();
     }
   }
   return m_break_id != LLDB_INVALID_BREAK_ID;
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 5d48273..91b1682 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -32,7 +32,7 @@
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
 #ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
 #else
 #define DEBUG_PRINTF(fmt, ...)
@@ -355,7 +355,7 @@
     CompilerType clang_uint32_type =
         clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
             lldb::eEncodingUint, 32);
-    input_value.SetValueType(Value::eValueTypeScalar);
+    input_value.SetValueType(Value::ValueType::Scalar);
     input_value.SetCompilerType(clang_uint32_type);
     //        input_value.SetContext (Value::eContextTypeClangType,
     //        clang_uint32_type);
@@ -1114,6 +1114,12 @@
   return false;
 }
 
+bool DynamicLoaderMacOSXDYLD::IsFullyInitialized() {
+  if (ReadAllImageInfosStructure())
+    return m_dyld_all_image_infos.libSystemInitialized;
+  return false;
+}
+
 void DynamicLoaderMacOSXDYLD::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance);
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 21bf587..4b337d1 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -68,6 +68,8 @@
 
   uint32_t GetPluginVersion() override;
 
+  bool IsFullyInitialized() override;
+
 protected:
   void PutToLog(lldb_private::Log *log) const;
 
@@ -96,20 +98,15 @@
                              lldb_private::FileSpec *lc_id_dylinker);
 
   struct DYLDAllImageInfos {
-    uint32_t version;
-    uint32_t dylib_info_count;            // Version >= 1
-    lldb::addr_t dylib_info_addr;         // Version >= 1
-    lldb::addr_t notification;            // Version >= 1
-    bool processDetachedFromSharedRegion; // Version >= 1
-    bool libSystemInitialized;            // Version >= 2
-    lldb::addr_t dyldImageLoadAddress;    // Version >= 2
+    uint32_t version = 0;
+    uint32_t dylib_info_count = 0;                            // Version >= 1
+    lldb::addr_t dylib_info_addr = LLDB_INVALID_ADDRESS;      // Version >= 1
+    lldb::addr_t notification = LLDB_INVALID_ADDRESS;         // Version >= 1
+    bool processDetachedFromSharedRegion = false;             // Version >= 1
+    bool libSystemInitialized = false;                        // Version >= 2
+    lldb::addr_t dyldImageLoadAddress = LLDB_INVALID_ADDRESS; // Version >= 2
 
-    DYLDAllImageInfos()
-        : version(0), dylib_info_count(0),
-          dylib_info_addr(LLDB_INVALID_ADDRESS),
-          notification(LLDB_INVALID_ADDRESS),
-          processDetachedFromSharedRegion(false), libSystemInitialized(false),
-          dyldImageLoadAddress(LLDB_INVALID_ADDRESS) {}
+    DYLDAllImageInfos() = default;
 
     void Clear() {
       version = 0;
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/src/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 3e88d88..5775f5a 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -38,13 +38,13 @@
   // the layout of this struct is not binary compatible, it is simply large
   // enough to hold the information on both 32 and 64 bit platforms.
   struct Rendezvous {
-    uint64_t version;
-    lldb::addr_t map_addr;
-    lldb::addr_t brk;
-    uint64_t state;
-    lldb::addr_t ldbase;
+    uint64_t version = 0;
+    lldb::addr_t map_addr = 0;
+    lldb::addr_t brk = 0;
+    uint64_t state = 0;
+    lldb::addr_t ldbase = 0;
 
-    Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {}
+    Rendezvous() = default;
   };
 
 public:
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index c1fceeb..8a5528f 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -10,6 +10,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 
 #include "DynamicLoaderStatic.h"
@@ -105,6 +106,15 @@
             // the file...
             SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
             if (section_sp) {
+              // If this section already has a load address set in the target,
+              // don't re-set it to the file address.  Something may have
+              // set it to a more correct value already.
+              if (m_process->GetTarget()
+                      .GetSectionLoadList()
+                      .GetSectionLoadAddress(section_sp) !=
+                  LLDB_INVALID_ADDRESS) {
+                continue;
+              }
               if (m_process->GetTarget().SetSectionLoadAddress(
                       section_sp, section_sp->GetFileAddress()))
                 changed = true;
diff --git a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 7f9504b..54dfa3e 100644
--- a/src/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -28,7 +28,7 @@
 DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
     : DynamicLoader(process) {}
 
-DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {}
+DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() = default;
 
 void DynamicLoaderWindowsDYLD::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -193,7 +193,7 @@
   AddressRange range(pc, 2 * 15);
 
   DisassemblerSP disassembler_sp = Disassembler::DisassembleRange(
-      arch, nullptr, nullptr, m_process->GetTarget(), range, true);
+      arch, nullptr, nullptr, m_process->GetTarget(), range);
   if (!disassembler_sp) {
     return ThreadPlanSP();
   }
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index 3edbc4a..85e2fcf 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -15,7 +15,6 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Log.h"
-#include "stdlib.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
@@ -27,6 +26,7 @@
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
 
 using namespace llvm;
 using namespace clang;
@@ -43,7 +43,7 @@
   m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
 }
 
-ASTResultSynthesizer::~ASTResultSynthesizer() {}
+ASTResultSynthesizer::~ASTResultSynthesizer() = default;
 
 void ASTResultSynthesizer::Initialize(ASTContext &Context) {
   m_ast_context = &Context;
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
index 40f0de4..a2722db 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTStructExtractor.cpp
@@ -9,7 +9,6 @@
 #include "ASTStructExtractor.h"
 
 #include "lldb/Utility/Log.h"
-#include "stdlib.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
@@ -21,6 +20,7 @@
 #include "clang/Sema/Sema.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
 
 using namespace llvm;
 using namespace clang;
@@ -38,7 +38,7 @@
   m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
 }
 
-ASTStructExtractor::~ASTStructExtractor() {}
+ASTStructExtractor::~ASTStructExtractor() = default;
 
 void ASTStructExtractor::Initialize(ASTContext &Context) {
   m_ast_context = &Context;
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
index 1e438ed..a95fce1 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.cpp
@@ -8,17 +8,17 @@
 
 #include "ASTUtils.h"
 
-lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() {}
+lldb_private::ExternalASTSourceWrapper::~ExternalASTSourceWrapper() = default;
 
 void lldb_private::ExternalASTSourceWrapper::PrintStats() {
   m_Source->PrintStats();
 }
 
-lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() {}
+lldb_private::ASTConsumerForwarder::~ASTConsumerForwarder() = default;
 
 void lldb_private::ASTConsumerForwarder::PrintStats() { m_c->PrintStats(); }
 
-lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() {}
+lldb_private::SemaSourceWithPriorities::~SemaSourceWithPriorities() = default;
 
 void lldb_private::SemaSourceWithPriorities::PrintStats() {
   for (size_t i = 0; i < Sources.size(); ++i)
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index e2601a0..94647b0 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -184,7 +184,7 @@
   }
 
 public:
-  DeclContextOverride() {}
+  DeclContextOverride() = default;
 
   void OverrideAllDeclsFromContainingFunction(clang::Decl *decl) {
     for (DeclContext *decl_context = decl->getLexicalDeclContext();
@@ -359,9 +359,6 @@
   if (!ClangUtil::IsClangType(type))
     return false;
 
-  // TODO: remove external completion BOOL
-  // CompleteAndFetchChildren should get the Decl out and check for the
-
   clang::QualType qual_type(
       ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
 
@@ -435,8 +432,6 @@
 bool ClangASTImporter::Import(const CompilerType &type) {
   if (!ClangUtil::IsClangType(type))
     return false;
-  // TODO: remove external completion BOOL
-  // CompleteAndFetchChildren should get the Decl out and check for the
 
   clang::QualType qual_type(
       ClangUtil::GetCanonicalQualType(ClangUtil::RemoveFastQualifiers(type)));
@@ -830,6 +825,10 @@
 
   // Check which ASTContext this declaration originally came from.
   DeclOrigin origin = m_master.GetDeclOrigin(From);
+
+  // Prevent infinite recursion when the origin tracking contains a cycle.
+  assert(origin.decl != From && "Origin points to itself?");
+
   // If it originally came from the target ASTContext then we can just
   // pretend that the original is the one we imported. This can happen for
   // example when inspecting a persistent declaration from the scratch
@@ -889,6 +888,37 @@
     LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
   }
 
+  // Disable the minimal import for fields that have record types. There is
+  // no point in minimally importing the record behind their type as Clang
+  // will anyway request their definition when the FieldDecl is added to the
+  // RecordDecl (as Clang will query the FieldDecl's type for things such
+  // as a deleted constexpr destructor).
+  // By importing the type ahead of time we avoid some corner cases where
+  // the FieldDecl's record is importing in the middle of Clang's
+  // `DeclContext::addDecl` logic.
+  if (clang::FieldDecl *fd = dyn_cast<FieldDecl>(From)) {
+    // This is only necessary because we do the 'minimal import'. Remove this
+    // once LLDB stopped using that mode.
+    assert(isMinimalImport() && "Only necessary for minimal import");
+    QualType field_type = fd->getType();
+    if (field_type->isRecordType()) {
+      // First get the underlying record and minimally import it.
+      clang::TagDecl *record_decl = field_type->getAsTagDecl();
+      llvm::Expected<Decl *> imported = Import(record_decl);
+      if (!imported)
+        return imported.takeError();
+      // Check how/if the import got redirected to a different AST. Now
+      // import the definition of what was actually imported. If there is no
+      // origin then that means the record was imported by just picking a
+      // compatible type in the target AST (in which case there is no more
+      // importing to do).
+      if (clang::Decl *origin = m_master.GetDeclOrigin(*imported).decl) {
+        if (llvm::Error def_err = ImportDefinition(record_decl))
+          return std::move(def_err);
+      }
+    }
+  }
+
   return ASTImporter::ImportImpl(From);
 }
 
@@ -904,16 +934,6 @@
   MapImported(from, to);
   ASTImporter::Imported(from, to);
 
-  /*
-  if (to_objc_interface)
-      to_objc_interface->startDefinition();
-
-  CXXRecordDecl *to_cxx_record = dyn_cast<CXXRecordDecl>(to);
-
-  if (to_cxx_record)
-      to_cxx_record->startDefinition();
-  */
-
   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
 
   if (llvm::Error err = ImportDefinition(from)) {
@@ -1088,22 +1108,23 @@
     DeclOrigin origin = from_context_md->getOrigin(from);
 
     if (origin.Valid()) {
-      if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
-        if (origin.ctx != &to->getASTContext())
+      if (origin.ctx != &to->getASTContext()) {
+        if (!to_context_md->hasOrigin(to) || user_id != LLDB_INVALID_UID)
           to_context_md->setOrigin(to, origin);
 
-      ImporterDelegateSP direct_completer =
-          m_master.GetDelegate(&to->getASTContext(), origin.ctx);
+        ImporterDelegateSP direct_completer =
+            m_master.GetDelegate(&to->getASTContext(), origin.ctx);
 
-      if (direct_completer.get() != this)
-        direct_completer->ASTImporter::Imported(origin.decl, to);
+        if (direct_completer.get() != this)
+          direct_completer->ASTImporter::Imported(origin.decl, to);
 
-      LLDB_LOG(log,
-               "    [ClangASTImporter] Propagated origin "
-               "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
-               "(ASTContext*){3}",
-               origin.decl, origin.ctx, &from->getASTContext(),
-               &to->getASTContext());
+        LLDB_LOG(log,
+                 "    [ClangASTImporter] Propagated origin "
+                 "(Decl*){0}/(ASTContext*){1} from (ASTContext*){2} to "
+                 "(ASTContext*){3}",
+                 origin.decl, origin.ctx, &from->getASTContext(),
+                 &to->getASTContext());
+      }
     } else {
       if (m_new_decl_listener)
         m_new_decl_listener->NewDeclImported(from, to);
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
index bf4ad17..4f589d3 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -23,6 +23,7 @@
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Utility/LLDBAssert.h"
 #include "lldb/lldb-types.h"
 
 #include "Plugins/ExpressionParser/Clang/CxxModuleHandler.h"
@@ -34,6 +35,32 @@
 class ClangASTMetadata;
 class TypeSystemClang;
 
+/// Manages and observes all Clang AST node importing in LLDB.
+///
+/// The ClangASTImporter takes care of two things:
+///
+/// 1. Keeps track of all ASTImporter instances in LLDB.
+///
+/// Clang's ASTImporter takes care of importing types from one ASTContext to
+/// another. This class expands this concept by allowing copying from several
+/// ASTContext instances to several other ASTContext instances. Instead of
+/// constructing a new ASTImporter manually to copy over a type/decl, this class
+/// can be asked to do this. It will construct a ASTImporter for the caller (and
+/// will cache the ASTImporter instance for later use) and then perform the
+/// import.
+///
+/// This mainly prevents that a caller might construct several ASTImporter
+/// instances for the same source/target ASTContext combination. As the
+/// ASTImporter has an internal state that keeps track of already imported
+/// declarations and so on, using only one ASTImporter instance is more
+/// efficient and less error-prone than using multiple.
+///
+/// 2. Keeps track of from where declarations were imported (origin-tracking).
+/// The ASTImporter instances in this class usually only performa a minimal
+/// import, i.e., only a shallow copy is made that is filled out on demand
+/// when more information is requested later on. This requires record-keeping
+/// of where any shallow clone originally came from so that the right original
+/// declaration can be found and used as the source of any missing information.
 class ClangASTImporter {
 public:
   struct LayoutInfo {
@@ -52,12 +79,34 @@
       : m_file_manager(clang::FileSystemOptions(),
                        FileSystem::Instance().GetVirtualFileSystem()) {}
 
+  /// Copies the given type and the respective declarations to the destination
+  /// type system.
+  ///
+  /// This function does a shallow copy and requires that the target AST
+  /// has an ExternalASTSource which queries this ClangASTImporter instance
+  /// for any additional information that is maybe lacking in the shallow copy.
+  /// This also means that the type system of src_type can *not* be deleted
+  /// after this function has been called. If you need to delete the source
+  /// type system you either need to delete the destination type system first
+  /// or use \ref ClangASTImporter::DeportType.
+  ///
+  /// \see ClangASTImporter::DeportType
   CompilerType CopyType(TypeSystemClang &dst, const CompilerType &src_type);
 
+  /// \see ClangASTImporter::CopyType
   clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
 
+  /// Copies the given type and the respective declarations to the destination
+  /// type system.
+  ///
+  /// Unlike CopyType this function ensures that types/declarations which are
+  /// originally from the AST of src_type are fully copied over. The type
+  /// system of src_type can safely be deleted after calling this function.
+  /// \see ClangASTImporter::CopyType
   CompilerType DeportType(TypeSystemClang &dst, const CompilerType &src_type);
 
+  /// Copies the given decl to the destination type system.
+  /// \see ClangASTImporter::DeportType
   clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, clang::Decl *decl);
 
   /// Sets the layout for the given RecordDecl. The layout will later be
@@ -78,8 +127,22 @@
       llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
           &vbase_offsets);
 
+  /// Returns true iff the given type was copied from another TypeSystemClang
+  /// and the original type in this other TypeSystemClang might contain
+  /// additional information (e.g., the definition of a 'class' type) that could
+  /// be imported.
+  ///
+  /// \see ClangASTImporter::Import
   bool CanImport(const CompilerType &type);
 
+  /// If the given type was copied from another TypeSystemClang then copy over
+  /// all missing information (e.g., the definition of a 'class' type).
+  ///
+  /// \return True iff an original type in another TypeSystemClang was found.
+  ///         Note: Does *not* return false if an original type was found but
+  ///               no information was imported over.
+  ///
+  /// \see ClangASTImporter::Import
   bool Import(const CompilerType &type);
 
   bool CompleteType(const CompilerType &compiler_type);
@@ -94,6 +157,14 @@
 
   bool RequireCompleteType(clang::QualType type);
 
+  /// Updates the internal origin-tracking information so that the given
+  /// 'original' decl is from now on used to import additional information
+  /// into the given decl.
+  ///
+  /// Usually the origin-tracking in the ClangASTImporter is automatically
+  /// updated when a declaration is imported, so the only valid reason to ever
+  /// call this is if there is a 'better' original decl and the target decl
+  /// is only a shallow clone that lacks any contents.
   void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl);
 
   ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl);
@@ -145,10 +216,13 @@
   void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx);
 
   struct DeclOrigin {
-    DeclOrigin() : ctx(nullptr), decl(nullptr) {}
+    DeclOrigin() = default;
 
     DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl)
-        : ctx(_ctx), decl(_decl) {}
+        : ctx(_ctx), decl(_decl) {
+      // The decl has to be in its associated ASTContext.
+      assert(_decl == nullptr || &_decl->getASTContext() == _ctx);
+    }
 
     DeclOrigin(const DeclOrigin &rhs) {
       ctx = rhs.ctx;
@@ -162,8 +236,8 @@
 
     bool Valid() const { return (ctx != nullptr || decl != nullptr); }
 
-    clang::ASTContext *ctx;
-    clang::Decl *decl;
+    clang::ASTContext *ctx = nullptr;
+    clang::Decl *decl = nullptr;
   };
 
   /// Listener interface used by the ASTImporterDelegate to inform other code
@@ -190,6 +264,16 @@
         : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx,
                              master.m_file_manager, true /*minimal*/),
           m_master(master), m_source_ctx(source_ctx) {
+      // Target and source ASTContext shouldn't be identical. Importing AST
+      // nodes within the same AST doesn't make any sense as the whole idea
+      // is to import them to a different AST.
+      lldbassert(target_ctx != source_ctx && "Can't import into itself");
+      // This is always doing a minimal import of any declarations. This means
+      // that there has to be an ExternalASTSource in the target ASTContext
+      // (that should implement the callbacks that complete any declarations
+      // on demand). Without an ExternalASTSource, this ASTImporter will just
+      // do a minimal import and the imported declarations won't be completed.
+      assert(target_ctx->getExternalSource() && "Missing ExternalSource");
       setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal);
     }
 
@@ -272,6 +356,13 @@
     /// Sets the DeclOrigin for the given Decl and overwrites any existing
     /// DeclOrigin.
     void setOrigin(const clang::Decl *decl, DeclOrigin origin) {
+      // Setting the origin of any decl to itself (or to a different decl
+      // in the same ASTContext) doesn't make any sense. It will also cause
+      // ASTImporterDelegate::ImportImpl to infinite recurse when trying to find
+      // the 'original' Decl when importing code.
+      assert(&decl->getASTContext() != origin.ctx &&
+             "Trying to set decl origin to its own ASTContext?");
+      assert(decl != origin.decl && "Trying to set decl origin to itself?");
       m_origins[decl] = origin;
     }
 
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 0f34c48c..b434237 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -479,10 +479,7 @@
                    decl->getDeclKindName(), ast_dump);
       }
 
-      Decl *copied_decl = CopyDecl(decl);
-
-      if (!copied_decl)
-        continue;
+      CopyDecl(decl);
 
       // FIXME: We should add the copied decl to the 'decls' list. This would
       // add the copied Decl into the DeclContext and make sure that we
@@ -492,12 +489,6 @@
       // lookup issues later on.
       // We can't just add them for now as the ASTImporter already added the
       // decl into the DeclContext and this would add it twice.
-
-      if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
-        QualType copied_field_type = copied_field->getType();
-
-        m_ast_importer_sp->RequireCompleteType(copied_field_type);
-      }
     } else {
       SkippedDecls = true;
     }
@@ -850,8 +841,8 @@
                                        ConstString name) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
 
-  ClangModulesDeclVendor *modules_decl_vendor =
-      m_target->GetClangModulesDeclVendor();
+  std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+      GetClangModulesDeclVendor();
   if (!modules_decl_vendor)
     return;
 
@@ -1143,8 +1134,8 @@
     // Check the modules only if the debug information didn't have a complete
     // interface.
 
-    if (ClangModulesDeclVendor *modules_decl_vendor =
-            m_target->GetClangModulesDeclVendor()) {
+    if (std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+            GetClangModulesDeclVendor()) {
       ConstString interface_name(interface_decl->getNameAsString().c_str());
       bool append = false;
       uint32_t max_matches = 1;
@@ -1313,8 +1304,8 @@
     // Check the modules only if the debug information didn't have a complete
     // interface.
 
-    ClangModulesDeclVendor *modules_decl_vendor =
-        m_target->GetClangModulesDeclVendor();
+    std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+        GetClangModulesDeclVendor();
 
     if (!modules_decl_vendor)
       break;
@@ -1570,10 +1561,10 @@
 
   if (log) {
     LLDB_LOG(log, "LRT returned:");
-    LLDB_LOG(log, "LRT   Original = (RecordDecl*)%p",
+    LLDB_LOG(log, "LRT   Original = (RecordDecl*){0}",
              static_cast<const void *>(origin_record.decl));
-    LLDB_LOG(log, "LRT   Size = %" PRId64, size);
-    LLDB_LOG(log, "LRT   Alignment = %" PRId64, alignment);
+    LLDB_LOG(log, "LRT   Size = {0}", size);
+    LLDB_LOG(log, "LRT   Alignment = {0}", alignment);
     LLDB_LOG(log, "LRT   Fields:");
     for (RecordDecl::field_iterator fi = record->field_begin(),
                                     fe = record->field_end();
@@ -1750,3 +1741,10 @@
 
   return m_clang_ast_context->GetType(copied_qual_type);
 }
+
+std::shared_ptr<ClangModulesDeclVendor>
+ClangASTSource::GetClangModulesDeclVendor() {
+  auto persistent_vars = llvm::cast<ClangPersistentVariables>(
+      m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
+  return persistent_vars->GetClangModulesDeclVendor();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
index 14761fb..3afd1fd 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -314,6 +314,8 @@
   ///     The imported type.
   CompilerType GuardedCopyType(const CompilerType &src_type);
 
+  std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
+
 public:
   /// Returns true if a name should be ignored by name lookup.
   ///
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
index bf52bec..6313117 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangDeclVendor.h
@@ -22,7 +22,7 @@
 public:
   ClangDeclVendor(DeclVendorKind kind) : DeclVendor(kind) {}
 
-  virtual ~ClangDeclVendor() {}
+  virtual ~ClangDeclVendor() = default;
 
   using DeclVendor::FindDecls;
 
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 852ce3b..731b81c 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -350,7 +350,7 @@
   if (!var)
     return false;
 
-  LLDB_LOG(log, "Adding value for (NamedDecl*)%p [%s - %s] to the structure",
+  LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",
            decl, name, var->GetName());
 
   // We know entity->m_parser_vars is valid because we used a parser variable
@@ -752,7 +752,7 @@
     MaybeRegisterFunctionBody(parser_function_decl);
   }
 
-  LLDB_LOG(log, "  CEDM::FEVD Found persistent decl %s", name);
+  LLDB_LOG(log, "  CEDM::FEVD Found persistent decl {0}", name);
 
   context.AddNamedDecl(parser_named_decl);
 }
@@ -1021,7 +1021,8 @@
   if (!m_target)
     return;
 
-  auto *modules_decl_vendor = m_target->GetClangModulesDeclVendor();
+  std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
+      GetClangModulesDeclVendor();
   if (!modules_decl_vendor)
     return;
 
@@ -1213,8 +1214,8 @@
   std::vector<clang::NamedDecl *> decls_from_modules;
 
   if (target) {
-    if (ClangModulesDeclVendor *decl_vendor =
-            target->GetClangModulesDeclVendor()) {
+    if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+            GetClangModulesDeclVendor()) {
       decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
     }
   }
@@ -1493,7 +1494,7 @@
     if (var_location_expr.GetExpressionData(const_value_extractor)) {
       var_location = Value(const_value_extractor.GetDataStart(),
                            const_value_extractor.GetByteSize());
-      var_location.SetValueType(Value::eValueTypeHostAddress);
+      var_location.SetValueType(Value::ValueType::HostAddress);
     } else {
       LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
       return false;
@@ -1512,10 +1513,10 @@
   if (parser_type)
     *parser_type = TypeFromParser(type_to_use);
 
-  if (var_location.GetContextType() == Value::eContextTypeInvalid)
+  if (var_location.GetContextType() == Value::ContextType::Invalid)
     var_location.SetCompilerType(type_to_use);
 
-  if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
+  if (var_location.GetValueType() == Value::ValueType::FileAddress) {
     SymbolContext var_sc;
     var->CalculateSymbolContext(&var_sc);
 
@@ -1529,7 +1530,7 @@
 
     if (load_addr != LLDB_INVALID_ADDRESS) {
       var_location.GetScalar() = load_addr;
-      var_location.SetValueType(Value::eValueTypeLoadAddress);
+      var_location.SetValueType(Value::ValueType::LoadAddress);
     }
   }
 
@@ -1665,11 +1666,11 @@
   const Address symbol_address = symbol.GetAddress();
   lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
 
-  // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
+  // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,
   // user_type.GetOpaqueQualType());
   parser_vars->m_lldb_value.SetCompilerType(user_type);
   parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
-  parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+  parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
 
   parser_vars->m_named_decl = var_decl;
   parser_vars->m_llvm_value = nullptr;
@@ -1860,14 +1861,14 @@
       entity->GetParserVars(GetParserID());
 
   if (load_addr != LLDB_INVALID_ADDRESS) {
-    parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
+    parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
     parser_vars->m_lldb_value.GetScalar() = load_addr;
   } else {
     // We have to try finding a file address.
 
     lldb::addr_t file_addr = fun_address.GetFileAddress();
 
-    parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
+    parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);
     parser_vars->m_lldb_value.GetScalar() = file_addr;
   }
 
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index a9cd5d1..e39dc58 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -9,8 +9,8 @@
 #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
 #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H
 
-#include <signal.h>
-#include <stdint.h>
+#include <csignal>
+#include <cstdint>
 
 #include <vector>
 
@@ -248,10 +248,10 @@
                                 lldb::SymbolType symbol_type);
 
   struct TargetInfo {
-    lldb::ByteOrder byte_order;
-    size_t address_byte_size;
+    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
+    size_t address_byte_size = 0;
 
-    TargetInfo() : byte_order(lldb::eByteOrderInvalid), address_byte_size(0) {}
+    TargetInfo() = default;
 
     bool IsValid() {
       return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);
@@ -308,7 +308,7 @@
   /// The following values should not live beyond parsing
   class ParserVars {
   public:
-    ParserVars() {}
+    ParserVars() = default;
 
     Target *GetTarget() {
       if (m_exe_ctx.GetTargetPtr())
@@ -353,16 +353,15 @@
   /// The following values contain layout information for the materialized
   /// struct, but are not specific to a single materialization
   struct StructVars {
-    StructVars()
-        : m_struct_alignment(0), m_struct_size(0), m_struct_laid_out(false),
-          m_result_name(), m_object_pointer_type(nullptr, nullptr) {}
+    StructVars() : m_result_name(), m_object_pointer_type(nullptr, nullptr) {}
 
-    lldb::offset_t
-        m_struct_alignment; ///< The alignment of the struct in bytes.
-    size_t m_struct_size;   ///< The size of the struct in bytes.
-    bool m_struct_laid_out; ///< True if the struct has been laid out and the
-                            ///layout is valid (that is, no new fields have been
-                            ///added since).
+    lldb::offset_t m_struct_alignment =
+        0;                    ///< The alignment of the struct in bytes.
+    size_t m_struct_size = 0; ///< The size of the struct in bytes.
+    bool m_struct_laid_out =
+        false; ///< True if the struct has been laid out and the
+               /// layout is valid (that is, no new fields have been
+               /// added since).
     ConstString
         m_result_name; ///< The name of the result variable ($1, for example)
     TypeFromUser m_object_pointer_type; ///< The type of the "this" variable, if
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index e33e5df..37bcaf0 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -38,7 +38,7 @@
             ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {}
 
   /// Destructor
-  virtual ~ClangExpressionHelper() {}
+  virtual ~ClangExpressionHelper() = default;
 
   /// Return the object that the parser should use when resolving external
   /// values.  May be NULL if everything should be self-contained.
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 7644a5e..0b5e1ab 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -343,6 +343,7 @@
   const std::vector<const char *> groupsToIgnore = {
       "unused-value",
       "odr",
+      "unused-getter-return-value",
   };
   for (const char *group : groupsToIgnore) {
     compiler.getDiagnostics().setSeverityForGroup(
@@ -513,7 +514,7 @@
     LLDB_LOGF(log, "Using SIMD alignment: %d",
               target_info->getSimdDefaultAlign());
     LLDB_LOGF(log, "Target datalayout string: '%s'",
-              target_info->getDataLayout().getStringRepresentation().c_str());
+              target_info->getDataLayoutString());
     LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str());
     LLDB_LOGF(log, "Target vector alignment: %d",
               target_info->getMaxVectorAlign());
@@ -657,7 +658,8 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  m_compiler->getTarget().adjust(m_compiler->getLangOpts());
+  m_compiler->getTarget().adjust(m_compiler->getDiagnostics(),
+		                 m_compiler->getLangOpts());
 
   // 6. Set up the diagnostic buffer for reporting errors
 
@@ -686,11 +688,11 @@
     break;
   }
 
-  if (ClangModulesDeclVendor *decl_vendor =
-          target_sp->GetClangModulesDeclVendor()) {
-    if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
-            target_sp->GetPersistentExpressionStateForLanguage(
-                lldb::eLanguageTypeC))) {
+  if (auto *clang_persistent_vars = llvm::cast<ClangPersistentVariables>(
+          target_sp->GetPersistentExpressionStateForLanguage(
+              lldb::eLanguageTypeC))) {
+    if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+            clang_persistent_vars->GetClangModulesDeclVendor()) {
       std::unique_ptr<PPCallbacks> pp_callbacks(
           new LLDBPreprocessorCallbacks(*decl_vendor, *clang_persistent_vars,
                                         m_compiler->getSourceManager()));
@@ -723,7 +725,7 @@
       m_compiler->getCodeGenOpts(), *m_llvm_context));
 }
 
-ClangExpressionParser::~ClangExpressionParser() {}
+ClangExpressionParser::~ClangExpressionParser() = default;
 
 namespace {
 
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index 180e08b..31707f8 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -31,6 +31,7 @@
 using namespace lldb_private;
 
 #define PREFIX_NAME "<lldb wrapper prefix>"
+#define SUFFIX_NAME "<lldb wrapper suffix>"
 
 const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME;
 
@@ -73,6 +74,9 @@
 }
 )";
 
+const char *ClangExpressionSourceCode::g_expression_suffix =
+    "\n;\n#line 1 \"" SUFFIX_NAME "\"\n";
+
 namespace {
 
 class AddMacroState {
@@ -180,7 +184,7 @@
   // containing only the user expression. This will hide our wrapper code
   // from the user when we render diagnostics with Clang.
   m_start_marker = "#line 1 \"" + filename.str() + "\"\n";
-  m_end_marker = "\n;\n#line 1 \"<lldb wrapper suffix>\"\n";
+  m_end_marker = g_expression_suffix;
 }
 
 namespace {
@@ -314,10 +318,11 @@
       }
     }
 
-    ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
     auto *persistent_vars = llvm::cast<ClangPersistentVariables>(
         target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
-    if (decl_vendor && persistent_vars) {
+    std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+        persistent_vars->GetClangModulesDeclVendor();
+    if (decl_vendor) {
       const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
           persistent_vars->GetHandLoadedClangModules();
       ClangModulesDeclVendor::ModuleVector modules_for_macros;
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index 9a54f0e..54ae837 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -27,6 +27,7 @@
   /// the user expression.
   static const llvm::StringRef g_prefix_file_name;
   static const char *g_expression_prefix;
+  static const char *g_expression_suffix;
 
   /// The possible ways an expression can be wrapped.
   enum class WrapKind {
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index 58d5899..7bb68e7 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -9,9 +9,9 @@
 #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
 #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
 
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
+#include <csignal>
+#include <cstdint>
+#include <cstring>
 
 #include <map>
 #include <string>
@@ -116,19 +116,19 @@
   /// The following values should not live beyond parsing
   class ParserVars {
   public:
-    ParserVars()
-        : m_named_decl(nullptr), m_llvm_value(nullptr),
-          m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {}
+    ParserVars() : m_lldb_value(), m_lldb_var() {}
 
-    const clang::NamedDecl
-        *m_named_decl;         ///< The Decl corresponding to this variable
-    llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
-                               ///usually a GlobalValue
+    const clang::NamedDecl *m_named_decl =
+        nullptr; ///< The Decl corresponding to this variable
+    llvm::Value *m_llvm_value =
+        nullptr; ///< The IR value corresponding to this variable;
+                 /// usually a GlobalValue
     lldb_private::Value
         m_lldb_value;            ///< The value found in LLDB for this variable
     lldb::VariableSP m_lldb_var; ///< The original variable for this variable
-    const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this
-                                            ///variable, if it was a symbol
+    const lldb_private::Symbol *m_lldb_sym =
+        nullptr; ///< The original symbol for this
+                 /// variable, if it was a symbol
   };
 
 private:
@@ -157,13 +157,13 @@
 
   /// The following values are valid if the variable is used by JIT code
   struct JITVars {
-    JITVars() : m_alignment(0), m_size(0), m_offset(0) {}
+    JITVars() = default;
 
-    lldb::offset_t
-        m_alignment; ///< The required alignment of the variable, in bytes
-    size_t m_size;   ///< The space required for the variable, in bytes
-    lldb::offset_t
-        m_offset; ///< The offset of the variable in the struct, in bytes
+    lldb::offset_t m_alignment =
+        0;             ///< The required alignment of the variable, in bytes
+    size_t m_size = 0; ///< The space required for the variable, in bytes
+    lldb::offset_t m_offset =
+        0; ///< The offset of the variable in the struct, in bytes
   };
 
 private:
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index 0c9ad20..2cfa9a4 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -59,7 +59,7 @@
 }
 
 // Destructor
-ClangFunctionCaller::~ClangFunctionCaller() {}
+ClangFunctionCaller::~ClangFunctionCaller() = default;
 
 unsigned
 
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index c014ad5..336058a 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -42,9 +42,9 @@
 using namespace lldb_private;
 
 namespace {
-// Any Clang compiler requires a consumer for diagnostics.  This one stores
-// them as strings so we can provide them to the user in case a module failed
-// to load.
+/// Any Clang compiler requires a consumer for diagnostics.  This one stores
+/// them as strings so we can provide them to the user in case a module failed
+/// to load.
 class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {
 public:
   StoringDiagnosticConsumer();
@@ -74,8 +74,8 @@
   Log *m_log;
 };
 
-// The private implementation of our ClangModulesDeclVendor.  Contains all the
-// Clang state required to load modules.
+/// The private implementation of our ClangModulesDeclVendor.  Contains all the
+/// Clang state required to load modules.
 class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
 public:
   ClangModulesDeclVendorImpl(
@@ -100,9 +100,9 @@
       std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;
 
 private:
-  void
-  ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports,
-                            clang::Module *module);
+  typedef llvm::DenseSet<ModuleID> ExportedModuleSet;
+  void ReportModuleExportsHelper(ExportedModuleSet &exports,
+                                 clang::Module *module);
 
   void ReportModuleExports(ModuleVector &exports, clang::Module *module);
 
@@ -120,7 +120,7 @@
 
   typedef std::vector<ConstString> ImportedModule;
   typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;
-  typedef std::set<ModuleID> ImportedModuleSet;
+  typedef llvm::DenseSet<ModuleID> ImportedModuleSet;
   ImportedModuleMap m_imported_modules;
   ImportedModuleSet m_user_imported_modules;
   // We assume that every ASTContext has an TypeSystemClang, so we also store
@@ -176,7 +176,7 @@
 ClangModulesDeclVendor::ClangModulesDeclVendor()
     : ClangDeclVendor(eClangModuleDeclVendor) {}
 
-ClangModulesDeclVendor::~ClangModulesDeclVendor() {}
+ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;
 
 ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
     llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,
@@ -195,8 +195,7 @@
 }
 
 void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(
-    std::set<ClangModulesDeclVendor::ModuleID> &exports,
-    clang::Module *module) {
+    ExportedModuleSet &exports, clang::Module *module) {
   if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))
     return;
 
@@ -206,20 +205,18 @@
 
   module->getExportedModules(sub_exports);
 
-  for (clang::Module *module : sub_exports) {
+  for (clang::Module *module : sub_exports)
     ReportModuleExportsHelper(exports, module);
-  }
 }
 
 void ClangModulesDeclVendorImpl::ReportModuleExports(
     ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {
-  std::set<ClangModulesDeclVendor::ModuleID> exports_set;
+  ExportedModuleSet exports_set;
 
   ReportModuleExportsHelper(exports_set, module);
 
-  for (ModuleID module : exports_set) {
+  for (ModuleID module : exports_set)
     exports.push_back(module);
-  }
 }
 
 bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
@@ -237,17 +234,15 @@
 
   std::vector<ConstString> imported_module;
 
-  for (ConstString path_component : module.path) {
+  for (ConstString path_component : module.path)
     imported_module.push_back(path_component);
-  }
 
   {
     ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);
 
     if (mi != m_imported_modules.end()) {
-      if (exported_modules) {
+      if (exported_modules)
         ReportModuleExports(*exported_modules, mi->second);
-      }
       return true;
     }
   }
@@ -338,9 +333,8 @@
   clang::Module *requested_module = DoGetModule(clang_path, true);
 
   if (requested_module != nullptr) {
-    if (exported_modules) {
+    if (exported_modules)
       ReportModuleExports(*exported_modules, requested_module);
-    }
 
     m_imported_modules[imported_module] = requested_module;
 
@@ -388,9 +382,8 @@
 ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
                                       uint32_t max_matches,
                                       std::vector<CompilerDecl> &decls) {
-  if (!m_enabled) {
+  if (!m_enabled)
     return 0;
-  }
 
   if (!append)
     decls.clear();
@@ -423,18 +416,16 @@
 void ClangModulesDeclVendorImpl::ForEachMacro(
     const ClangModulesDeclVendor::ModuleVector &modules,
     std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {
-  if (!m_enabled) {
+  if (!m_enabled)
     return;
-  }
 
   typedef std::map<ModuleID, ssize_t> ModulePriorityMap;
   ModulePriorityMap module_priorities;
 
   ssize_t priority = 0;
 
-  for (ModuleID module : modules) {
+  for (ModuleID module : modules)
     module_priorities[module] = priority++;
-  }
 
   if (m_compiler_instance->getPreprocessor().getExternalSource()) {
     m_compiler_instance->getPreprocessor()
@@ -455,9 +446,8 @@
                   .getExternalIdentifierLookup()) {
         lookup->get(mi->first->getName());
       }
-      if (!ii) {
+      if (!ii)
         ii = mi->first;
-      }
     }
 
     ssize_t found_priority = -1;
@@ -504,24 +494,21 @@
           for (auto pi = macro_info->param_begin(),
                     pe = macro_info->param_end();
                pi != pe; ++pi) {
-            if (!first_arg) {
+            if (!first_arg)
               macro_expansion.append(", ");
-            } else {
+            else
               first_arg = false;
-            }
 
             macro_expansion.append((*pi)->getName().str());
           }
 
           if (macro_info->isC99Varargs()) {
-            if (first_arg) {
+            if (first_arg)
               macro_expansion.append("...");
-            } else {
+            else
               macro_expansion.append(", ...");
-            }
-          } else if (macro_info->isGNUVarargs()) {
+          } else if (macro_info->isGNUVarargs())
             macro_expansion.append("...");
-          }
 
           macro_expansion.append(")");
         }
@@ -533,11 +520,10 @@
         for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
                                                te = macro_info->tokens_end();
              ti != te; ++ti) {
-          if (!first_token) {
+          if (!first_token)
             macro_expansion.append(" ");
-          } else {
+          else
             first_token = false;
-          }
 
           if (ti->isLiteral()) {
             if (const char *literal_data = ti->getLiteralData()) {
@@ -718,7 +704,7 @@
   if (!instance->hasTarget())
     return nullptr;
 
-  instance->getTarget().adjust(instance->getLangOpts());
+  instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts());
 
   if (!action->BeginSourceFile(*instance,
                                instance->getFrontendOpts().Inputs[0]))
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 42afac9..13d6a37 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -8,6 +8,7 @@
 
 #include "ClangPersistentVariables.h"
 #include "ClangASTImporter.h"
+#include "ClangModulesDeclVendor.h"
 
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Core/Value.h"
@@ -23,8 +24,10 @@
 using namespace lldb;
 using namespace lldb_private;
 
-ClangPersistentVariables::ClangPersistentVariables()
-    : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang) {}
+ClangPersistentVariables::ClangPersistentVariables(
+    std::shared_ptr<Target> target_sp)
+    : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang),
+      m_target_sp(target_sp) {}
 
 ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable(
     const lldb::ValueObjectSP &valobj_sp) {
@@ -109,6 +112,15 @@
   return m_ast_importer_sp;
 }
 
+std::shared_ptr<ClangModulesDeclVendor>
+ClangPersistentVariables::GetClangModulesDeclVendor() {
+  if (!m_modules_decl_vendor_sp) {
+    m_modules_decl_vendor_sp.reset(
+        ClangModulesDeclVendor::Create(*m_target_sp.get()));
+  }
+  return m_modules_decl_vendor_sp;
+}
+
 ConstString
 ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) {
   llvm::SmallString<64> name;
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index f888b2d..b8a359d 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -19,6 +19,8 @@
 namespace lldb_private {
 
 class ClangASTImporter;
+class ClangModulesDeclVendor;
+class Target;
 class TypeSystemClang;
 
 /// \class ClangPersistentVariables ClangPersistentVariables.h
@@ -30,7 +32,7 @@
 /// 0-based counter for naming result variables.
 class ClangPersistentVariables : public PersistentExpressionState {
 public:
-  ClangPersistentVariables();
+  ClangPersistentVariables(std::shared_ptr<Target> target_sp);
 
   ~ClangPersistentVariables() override = default;
 
@@ -40,6 +42,7 @@
   }
 
   std::shared_ptr<ClangASTImporter> GetClangASTImporter();
+  std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
 
   lldb::ExpressionVariableSP
   CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp) override;
@@ -106,6 +109,8 @@
                                    ///these are the highest-
                                    ///< priority source for macros.
   std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
+  std::shared_ptr<ClangModulesDeclVendor> m_modules_decl_vendor_sp;
+  std::shared_ptr<Target> m_target_sp;
 };
 
 } // namespace lldb_private
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 9be2947..1b205b1 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -8,7 +8,7 @@
 
 #include "lldb/Host/Config.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -90,7 +90,7 @@
   }
 }
 
-ClangUserExpression::~ClangUserExpression() {}
+ClangUserExpression::~ClangUserExpression() = default;
 
 void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -349,10 +349,6 @@
 
 static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
                             DiagnosticManager &diagnostic_manager) {
-  ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor();
-  if (!decl_vendor)
-    return;
-
   if (!target->GetEnableAutoImportClangModules())
     return;
 
@@ -361,6 +357,11 @@
   if (!persistent_state)
     return;
 
+  std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
+      persistent_state->GetClangModulesDeclVendor();
+  if (!decl_vendor)
+    return;
+
   StackFrame *frame = exe_ctx.GetFramePtr();
   if (!frame)
     return;
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 9788a4e..a781163 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -14,7 +14,7 @@
 #include "ClangExpressionSourceCode.h"
 #include "ClangPersistentVariables.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -34,21 +34,38 @@
 
 char ClangUtilityFunction::ID;
 
-/// Constructor
-///
-/// \param[in] text
-///     The text of the function.  Must be a full translation unit.
-///
-/// \param[in] name
-///     The name of the function, as used in the text.
 ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
-                                           std::string text, std::string name)
+                                           std::string text, std::string name,
+                                           bool enable_debugging)
     : UtilityFunction(
           exe_scope,
-          std::string(ClangExpressionSourceCode::g_expression_prefix) + text,
-          std::move(name)) {}
+          std::string(ClangExpressionSourceCode::g_expression_prefix) + text +
+              std::string(ClangExpressionSourceCode::g_expression_suffix),
+          std::move(name), enable_debugging) {
+  // Write the source code to a file so that LLDB's source manager can display
+  // it when debugging the code.
+  if (enable_debugging) {
+    int temp_fd = -1;
+    llvm::SmallString<128> result_path;
+    llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path);
+    if (temp_fd != -1) {
+      lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true);
+      text = "#line 1 \"" + std::string(result_path) + "\"\n" + text;
+      size_t bytes_written = text.size();
+      file.Write(text.c_str(), bytes_written);
+      if (bytes_written == text.size()) {
+        // If we successfully wrote the source to a temporary file, replace the
+        // function text with the next text containing the line directive.
+        m_function_text =
+            std::string(ClangExpressionSourceCode::g_expression_prefix) + text +
+            std::string(ClangExpressionSourceCode::g_expression_suffix);
+      }
+      file.Close();
+    }
+  }
+}
 
-ClangUtilityFunction::~ClangUtilityFunction() {}
+ClangUtilityFunction::~ClangUtilityFunction() = default;
 
 /// Install the utility function into a process
 ///
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index 7914e14..b8a154b 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -48,8 +48,11 @@
   ///
   /// \param[in] name
   ///     The name of the function, as used in the text.
+  ///
+  /// \param[in] enable_debugging
+  ///     Enable debugging of this function.
   ClangUtilityFunction(ExecutionContextScope &exe_scope, std::string text,
-                       std::string name);
+                       std::string name, bool enable_debugging);
 
   ~ClangUtilityFunction() override;
 
@@ -71,9 +74,9 @@
 private:
   class ClangUtilityFunctionHelper : public ClangExpressionHelper {
   public:
-    ClangUtilityFunctionHelper() {}
+    ClangUtilityFunctionHelper() = default;
 
-    ~ClangUtilityFunctionHelper() override {}
+    ~ClangUtilityFunctionHelper() override = default;
 
     /// Return the object that the parser should use when resolving external
     /// values.  May be NULL if everything should be self-contained.
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
index b984db4..425106b 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h
@@ -59,7 +59,7 @@
   /// Creates a configuration by analyzing the given list of used source files.
   explicit CppModuleConfiguration(const FileSpecList &support_files);
   /// Creates an empty and invalid configuration.
-  CppModuleConfiguration() {}
+  CppModuleConfiguration() = default;
 
   /// Returns true iff this is a valid configuration that can be used to
   /// load and compile modules.
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
index f953e86..74dd046 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp
@@ -33,6 +33,9 @@
       "shared_ptr",
       "unique_ptr",
       "weak_ptr",
+      // iterator
+      "move_iterator",
+      "__wrap_iter",
       // utility
       "allocator",
       "pair",
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index b35bf07..5655d54 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -14,6 +14,7 @@
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Intrinsics.h"
@@ -41,14 +42,12 @@
 
 using namespace llvm;
 
-static char ID;
-
 typedef SmallVector<Instruction *, 2> InstrList;
 
 IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
     : m_maker(maker), m_values() {}
 
-IRForTarget::FunctionValueCache::~FunctionValueCache() {}
+IRForTarget::FunctionValueCache::~FunctionValueCache() = default;
 
 llvm::Value *
 IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
@@ -72,13 +71,9 @@
                          lldb_private::IRExecutionUnit &execution_unit,
                          lldb_private::Stream &error_stream,
                          const char *func_name)
-    : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
-      m_module(nullptr), m_decl_map(decl_map),
-      m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
-      m_objc_getClass(nullptr), m_intptr_ty(nullptr),
-      m_error_stream(error_stream), m_execution_unit(execution_unit),
-      m_result_store(nullptr), m_result_is_pointer(false),
-      m_reloc_placeholder(nullptr),
+    : m_resolve_vars(resolve_vars), m_func_name(func_name),
+      m_decl_map(decl_map), m_error_stream(error_stream),
+      m_execution_unit(execution_unit),
       m_entry_instruction_finder(FindEntryInstruction) {}
 
 /* Handy utility functions used at several places in the code */
@@ -105,8 +100,6 @@
   return s;
 }
 
-IRForTarget::~IRForTarget() {}
-
 bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
   llvm_function.setLinkage(GlobalValue::ExternalLinkage);
 
@@ -1582,20 +1575,14 @@
           FunctionValueCache get_element_pointer_maker(
               [&value_maker, &entry_instruction_finder, old_constant,
                constant_expr](llvm::Function *function) -> llvm::Value * {
-                Value *ptr = constant_expr->getOperand(0);
+                auto *gep = cast<llvm::GEPOperator>(constant_expr);
+                Value *ptr = gep->getPointerOperand();
 
                 if (ptr == old_constant)
                   ptr = value_maker.GetValue(function);
 
                 std::vector<Value *> index_vector;
-
-                unsigned operand_index;
-                unsigned num_operands = constant_expr->getNumOperands();
-
-                for (operand_index = 1; operand_index < num_operands;
-                     ++operand_index) {
-                  Value *operand = constant_expr->getOperand(operand_index);
-
+                for (Value *operand : gep->indices()) {
                   if (operand == old_constant)
                     operand = value_maker.GetValue(function);
 
@@ -1605,7 +1592,7 @@
                 ArrayRef<Value *> indices(index_vector);
 
                 return GetElementPtrInst::Create(
-                    nullptr, ptr, indices, "",
+                    gep->getSourceElementType(), ptr, indices, "",
                     llvm::cast<Instruction>(
                         entry_instruction_finder.GetValue(function)));
               });
@@ -1788,7 +1775,8 @@
             ConstantInt *offset_int(
                 ConstantInt::get(offset_type, offset, true));
             GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
-                nullptr, argument, offset_int, "", entry_instruction);
+                argument->getType()->getPointerElementType(), argument,
+                offset_int, "", entry_instruction);
 
             if (name == m_result_name && !m_result_is_pointer) {
               BitCastInst *bit_cast = new BitCastInst(
@@ -2022,10 +2010,3 @@
 
   return true;
 }
-
-void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
-                                    PassManagerType pass_mgr_type) {}
-
-PassManagerType IRForTarget::getPotentialPassManagerType() const {
-  return PMT_ModulePassManager;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
index ebfc0ca..5f212fa 100644
--- a/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
+++ b/src/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h
@@ -58,7 +58,7 @@
 /// transformations to the IR which make it relocatable.  These
 /// transformations are discussed in more detail next to their relevant
 /// functions.
-class IRForTarget : public llvm::ModulePass {
+class IRForTarget {
 public:
   enum class LookupResult { Success, Fail, Ignore };
 
@@ -87,9 +87,6 @@
               lldb_private::Stream &error_stream,
               const char *func_name = "$__lldb_expr");
 
-  /// Destructor
-  ~IRForTarget() override;
-
   /// Run this IR transformer on a single module
   ///
   /// Implementation of the llvm::ModulePass::runOnModule() function.
@@ -101,20 +98,7 @@
   ///
   /// \return
   ///     True on success; false otherwise
-  bool runOnModule(llvm::Module &llvm_module) override;
-
-  /// Interface stub
-  ///
-  /// Implementation of the llvm::ModulePass::assignPassManager() function.
-  void assignPassManager(llvm::PMStack &pass_mgr_stack,
-                         llvm::PassManagerType pass_mgr_type =
-                             llvm::PMT_ModulePassManager) override;
-
-  /// Returns PMT_ModulePassManager
-  ///
-  /// Implementation of the llvm::ModulePass::getPotentialPassManagerType()
-  /// function.
-  llvm::PassManagerType getPotentialPassManagerType() const override;
+  bool runOnModule(llvm::Module &llvm_module);
 
 private:
   /// Ensures that the current function's linkage is set to external.
@@ -419,51 +403,46 @@
   ///     True on success; false otherwise
   bool ReplaceVariables(llvm::Function &llvm_function);
 
-  /// Flags
-  bool m_resolve_vars; ///< True if external variable references and persistent
-                       ///variable references should be resolved
-  lldb_private::ConstString
-      m_func_name; ///< The name of the function to translate
-  lldb_private::ConstString
-      m_result_name; ///< The name of the result variable ($0, $1, ...)
-  lldb_private::TypeFromParser
-      m_result_type;      ///< The type of the result variable.
-  llvm::Module *m_module; ///< The module being processed, or NULL if that has
-                          ///not been determined yet.
-  std::unique_ptr<llvm::DataLayout> m_target_data; ///< The target data for the
-                                                   ///module being processed, or
-                                                   ///NULL if there is no
-                                                   ///module.
-  lldb_private::ClangExpressionDeclMap
-      *m_decl_map; ///< The DeclMap containing the Decls
-  llvm::FunctionCallee
-      m_CFStringCreateWithBytes; ///< The address of the function
-                                 /// CFStringCreateWithBytes, cast to the
-                                 /// appropriate function pointer type
-  llvm::FunctionCallee m_sel_registerName; ///< The address of the function
-                                           /// sel_registerName, cast to the
-                                           /// appropriate function pointer type
-  llvm::FunctionCallee m_objc_getClass; ///< The address of the function
-                                        /// objc_getClass, cast to the
-                                        /// appropriate function pointer type
-  llvm::IntegerType
-      *m_intptr_ty; ///< The type of an integer large enough to hold a pointer.
-  lldb_private::Stream
-      &m_error_stream; ///< The stream on which errors should be printed
-  lldb_private::IRExecutionUnit &
-      m_execution_unit; ///< The execution unit containing the IR being created.
-
-  llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that
-                                   ///writes to the result variable.  If
-                                   /// m_has_side_effects is true, this is
-                                   /// NULL.
-  bool m_result_is_pointer; ///< True if the function's result in the AST is a
-                            ///pointer (see comments in
-                            /// ASTResultSynthesizer::SynthesizeBodyResult)
-
+  /// True if external variable references and persistent variable references
+  /// should be resolved
+  bool m_resolve_vars;
+  /// The name of the function to translate
+  lldb_private::ConstString m_func_name;
+  /// The name of the result variable ($0, $1, ...)
+  lldb_private::ConstString m_result_name;
+  /// The type of the result variable.
+  lldb_private::TypeFromParser m_result_type;
+  /// The module being processed, or NULL if that has not been determined yet.
+  llvm::Module *m_module = nullptr;
+  /// The target data for the module being processed, or NULL if there is no
+  /// module.
+  std::unique_ptr<llvm::DataLayout> m_target_data;
+  /// The DeclMap containing the Decls
+  lldb_private::ClangExpressionDeclMap *m_decl_map;
+  /// The address of the function CFStringCreateWithBytes, cast to the
+  /// appropriate function pointer type
+  llvm::FunctionCallee m_CFStringCreateWithBytes;
+  /// The address of the function sel_registerName, cast to the appropriate
+  /// function pointer type.
+  llvm::FunctionCallee m_sel_registerName;
+  /// The address of the function objc_getClass, cast to the appropriate
+  /// function pointer type.
+  llvm::FunctionCallee m_objc_getClass;
+  /// The type of an integer large enough to hold a pointer.
+  llvm::IntegerType *m_intptr_ty = nullptr;
+  /// The stream on which errors should be printed.
+  lldb_private::Stream &m_error_stream;
+  /// The execution unit containing the IR being created.
+  lldb_private::IRExecutionUnit &m_execution_unit;
+  /// If non-NULL, the store instruction that writes to the result variable.  If
+  /// m_has_side_effects is true, this is NULL.
+  llvm::StoreInst *m_result_store = nullptr;
+  /// True if the function's result in the AST is a pointer (see comments in
+  /// ASTResultSynthesizer::SynthesizeBodyResult)
+  bool m_result_is_pointer = false;
   /// A placeholder that will be replaced by a pointer to the final location of
   /// the static allocation.
-  llvm::GlobalVariable *m_reloc_placeholder;
+  llvm::GlobalVariable *m_reloc_placeholder = nullptr;
 
   class FunctionValueCache {
   public:
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 5559127..bf0bbda 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include "EmulateInstructionARM.h"
 #include "EmulationStateARM.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index d15d80c..dfd7c92 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -19,8 +19,8 @@
 // ITSession - Keep track of the IT Block progression.
 class ITSession {
 public:
-  ITSession() : ITCounter(0), ITState(0) {}
-  ~ITSession() {}
+  ITSession() = default;
+  ~ITSession() = default;
 
   // InitIT - Initializes ITCounter/ITState.
   bool InitIT(uint32_t bits7_0);
@@ -39,8 +39,8 @@
   uint32_t GetCond();
 
 private:
-  uint32_t ITCounter; // Possible values: 0, 1, 2, 3, 4.
-  uint32_t ITState;   // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
+  uint32_t ITCounter = 0; // Possible values: 0, 1, 2, 3, 4.
+  uint32_t ITState = 0;   // A2.5.2 Consists of IT[7:5] and IT[4:0] initially.
 };
 
 class EmulateInstructionARM : public EmulateInstruction {
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index aef08ba..569482c 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -20,11 +20,11 @@
 using namespace lldb;
 using namespace lldb_private;
 
-EmulationStateARM::EmulationStateARM() : m_gpr(), m_vfp_regs(), m_memory() {
+EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() {
   ClearPseudoRegisters();
 }
 
-EmulationStateARM::~EmulationStateARM() {}
+EmulationStateARM::~EmulationStateARM() = default;
 
 bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
   RegisterContext *reg_ctx = frame.GetRegisterContext().get();
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
index 955c7c6..28bc5d9 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -61,7 +61,7 @@
                       const lldb_private::RegisterValue &reg_value);
 
 private:
-  uint32_t m_gpr[17];
+  uint32_t m_gpr[17] = {0};
   struct _sd_regs {
     uint32_t s_regs[32]; // sregs 0 - 31 & dregs 0 - 15
 
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/src/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index d4cb726..a1a93c0 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -8,7 +8,7 @@
 
 #include "EmulateInstructionMIPS.h"
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Opcode.h"
@@ -159,8 +159,8 @@
       target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
   assert(m_asm_info.get() && m_subtype_info.get());
 
-  m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
-                                                m_reg_info.get(), nullptr);
+  m_context = std::make_unique<llvm::MCContext>(
+      triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get());
   assert(m_context.get());
 
   m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
@@ -1018,8 +1018,9 @@
 
       const size_t bytes_read =
           target->ReadMemory(next_addr, /* Address of next instruction */
-                             true,      /* prefer_file_cache */
-                             buf, sizeof(uint32_t), error, &load_addr);
+                             buf, sizeof(uint32_t), error, 
+                             false,  /* force_live_memory */
+                             &load_addr);
 
       if (bytes_read == 0)
         return true;
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/src/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 4ccaf0d..6044d00 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -8,7 +8,7 @@
 
 #include "EmulateInstructionMIPS64.h"
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Opcode.h"
@@ -163,8 +163,8 @@
       target->createMCSubtargetInfo(triple.getTriple(), cpu, features));
   assert(m_asm_info.get() && m_subtype_info.get());
 
-  m_context = std::make_unique<llvm::MCContext>(m_asm_info.get(),
-                                                m_reg_info.get(), nullptr);
+  m_context = std::make_unique<llvm::MCContext>(
+      triple, m_asm_info.get(), m_reg_info.get(), m_subtype_info.get());
   assert(m_context.get());
 
   m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context));
diff --git a/src/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/src/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
index 5d97513..4e78c36 100644
--- a/src/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
@@ -8,7 +8,7 @@
 
 #include "EmulateInstructionPPC64.h"
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Symbol/UnwindPlan.h"
diff --git a/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
index 99784bd..9a88b34 100644
--- a/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
+++ b/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp
@@ -127,7 +127,7 @@
   StackFrameSP responsible_frame;
   for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) {
     StackFrameSP frame = thread_sp->GetStackFrameAtIndex(I);
-    Address addr = frame->GetFrameCodeAddress();
+    Address addr = frame->GetFrameCodeAddressForSymbolication();
     if (addr.GetModule() == runtime_module_sp) // Skip PCs from the runtime.
       continue;
 
@@ -135,11 +135,6 @@
     if (!responsible_frame)
       responsible_frame = frame;
 
-    // First frame in stacktrace should point to a real PC, not return address.
-    if (I != 0 && trace->GetSize() == 0) {
-      addr.Slide(-1);
-    }
-
     lldb::addr_t PC = addr.GetLoadAddress(&target);
     trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
   }
@@ -271,8 +266,11 @@
       info->GetObjectForDotSeparatedPath("tid");
   tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
 
-  HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs);
-  ThreadSP new_thread_sp(history_thread);
+  // We gather symbolication addresses above, so no need for HistoryThread to
+  // try to infer the call addresses.
+  bool pcs_are_call_addresses = true;
+  ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
+      *process_sp, tid, PCs, pcs_are_call_addresses);
 
   // Save this in the Process' ExtendedThreadList so a strong pointer retains
   // the object
diff --git a/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
index b60eb53..58bc38a 100644
--- a/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
+++ b/src/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -29,7 +29,7 @@
 #include "lldb/Target/Thread.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
-#include <ctype.h>
+#include <cctype>
 
 #include <memory>
 
@@ -150,8 +150,8 @@
   StructuredData::Array *trace = new StructuredData::Array();
   auto trace_sp = StructuredData::ObjectSP(trace);
   for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) {
-    const Address FCA =
-        thread_sp->GetStackFrameAtIndex(I)->GetFrameCodeAddress();
+    const Address FCA = thread_sp->GetStackFrameAtIndex(I)
+                            ->GetFrameCodeAddressForSymbolication();
     if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime.
       continue;
 
@@ -324,8 +324,11 @@
       info->GetObjectForDotSeparatedPath("tid");
   tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;
 
-  HistoryThread *history_thread = new HistoryThread(*process_sp, tid, PCs);
-  ThreadSP new_thread_sp(history_thread);
+  // We gather symbolication addresses above, so no need for HistoryThread to
+  // try to infer the call addresses.
+  bool pcs_are_call_addresses = true;
+  ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
+      *process_sp, tid, PCs, pcs_are_call_addresses);
   std::string stop_reason_description = GetStopReasonDescription(info);
   new_thread_sp->SetName(stop_reason_description.c_str());
 
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 35788a6..1c498a2 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -74,14 +74,12 @@
     const CompilerType reserved_type =
         clang_ast_context->GetBasicType(lldb::eBasicTypeInt);
     const char *const FuncPtr_name("__FuncPtr");
-    const CompilerType FuncPtr_type =
-        clang_ast_importer->CopyType(*clang_ast_context, function_pointer_type);
 
     m_block_struct_type = clang_ast_context->CreateStructForIdentifier(
         ConstString(), {{isa_name, isa_type},
                         {flags_name, flags_type},
                         {reserved_name, reserved_type},
-                        {FuncPtr_name, FuncPtr_type}});
+                        {FuncPtr_name, function_pointer_type}});
   }
 
   ~BlockPointerSyntheticFrontEnd() override = default;
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index d844498..895fd55 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -59,6 +59,11 @@
   return g_name;
 }
 
+bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
+  const char *mangled_name = mangled.GetMangledName().GetCString();
+  return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name);
+}
+
 // PluginInterface protocol
 
 lldb_private::ConstString CPlusPlusLanguage::GetPluginName() {
@@ -1054,7 +1059,7 @@
                       .SetSkipReferences(false),
                   lldb_private::formatters::VectorTypeSummaryProvider,
                   "vector_type pointer summary provider"));
-          if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+          if (valobj.GetCompilerType().IsVectorType()) {
             if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
               return formatter_sp;
           }
@@ -1074,7 +1079,7 @@
                       .SetSkipReferences(false),
                   lldb_private::formatters::BlockPointerSummaryProvider,
                   "block pointer summary provider"));
-          if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+          if (valobj.GetCompilerType().IsBlockPointerType()) {
             return formatter_sp;
           }
           return nullptr;
@@ -1104,7 +1109,7 @@
                   .SetNonCacheable(true),
               "vector_type synthetic children",
               lldb_private::formatters::VectorTypeSyntheticFrontEndCreator));
-      if (valobj.GetCompilerType().IsVectorType(nullptr, nullptr)) {
+      if (valobj.GetCompilerType().IsVectorType()) {
         if (fmt_mgr.GetCategory(g_vectortypes)->IsEnabled())
           return formatter_sp;
       }
@@ -1123,7 +1128,7 @@
                   .SetNonCacheable(true),
               "block pointer synthetic children",
               lldb_private::formatters::BlockPointerSyntheticFrontEndCreator));
-      if (valobj.GetCompilerType().IsBlockPointerType(nullptr)) {
+      if (valobj.GetCompilerType().IsBlockPointerType()) {
         return formatter_sp;
       }
       return nullptr;
@@ -1147,7 +1152,7 @@
   const auto suffixes = {".cpp", ".cxx", ".c++", ".cc",  ".c",
                          ".h",   ".hh",  ".hpp", ".hxx", ".h++"};
   for (auto suffix : suffixes) {
-    if (file_path.endswith_lower(suffix))
+    if (file_path.endswith_insensitive(suffix))
       return true;
   }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index e2b5d29..9163be4 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -28,8 +28,7 @@
   class MethodName {
   public:
     MethodName()
-        : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers(),
-          m_parsed(false), m_parse_error(false) {}
+        : m_full(), m_basename(), m_context(), m_arguments(), m_qualifiers() {}
 
     MethodName(ConstString s)
         : m_full(s), m_basename(), m_context(), m_arguments(), m_qualifiers(),
@@ -68,8 +67,8 @@
     llvm::StringRef m_context;    // Decl context: "lldb::SBTarget"
     llvm::StringRef m_arguments;  // Arguments:    "(unsigned int)"
     llvm::StringRef m_qualifiers; // Qualifiers:   "const"
-    bool m_parsed;
-    bool m_parse_error;
+    bool m_parsed = false;
+    bool m_parse_error = false;
   };
 
   CPlusPlusLanguage() = default;
@@ -105,6 +104,8 @@
 
   static lldb_private::ConstString GetPluginNameStatic();
 
+  bool SymbolNameFitsToLanguage(Mangled mangled) const override;
+
   static bool IsCPPMangledName(llvm::StringRef name);
 
   // Extract C++ context and identifier from a string using heuristic matching
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
index 6fe6b12..426434c 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
@@ -69,7 +69,7 @@
     size_t begin_index = 0;
     size_t end_index = 0;
 
-    Range() {}
+    Range() = default;
     Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
       assert(end >= begin);
     }
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 2b16ebe..8eda422 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -379,8 +379,7 @@
 
 lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
     LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-    : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), m_count_sp(),
-      m_weak_count_sp(), m_ptr_size(0), m_byte_order(lldb::eByteOrderInvalid) {
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) {
   if (valobj_sp)
     Update();
 }
@@ -403,42 +402,23 @@
   if (idx == 0)
     return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true);
 
-  if (idx > 2)
-    return lldb::ValueObjectSP();
-
   if (idx == 1) {
-    if (!m_count_sp) {
-      ValueObjectSP shared_owners_sp(m_cntrl->GetChildMemberWithName(
-          ConstString("__shared_owners_"), true));
-      if (!shared_owners_sp)
-        return lldb::ValueObjectSP();
-      uint64_t count = 1 + shared_owners_sp->GetValueAsUnsigned(0);
-      DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
-      m_count_sp = CreateValueObjectFromData(
-          "count", data, valobj_sp->GetExecutionContextRef(),
-          shared_owners_sp->GetCompilerType());
+    if (auto ptr_sp =
+            valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)) {
+      Status status;
+      auto value_sp = ptr_sp->Dereference(status);
+      if (status.Success()) {
+        auto value_type_sp =
+            valobj_sp->GetCompilerType().GetTypeTemplateArgument(0);
+        return value_sp->Cast(value_type_sp);
+      }
     }
-    return m_count_sp;
-  } else /* if (idx == 2) */
-  {
-    if (!m_weak_count_sp) {
-      ValueObjectSP shared_weak_owners_sp(m_cntrl->GetChildMemberWithName(
-          ConstString("__shared_weak_owners_"), true));
-      if (!shared_weak_owners_sp)
-        return lldb::ValueObjectSP();
-      uint64_t count = 1 + shared_weak_owners_sp->GetValueAsUnsigned(0);
-      DataExtractor data(&count, 8, m_byte_order, m_ptr_size);
-      m_weak_count_sp = CreateValueObjectFromData(
-          "count", data, valobj_sp->GetExecutionContextRef(),
-          shared_weak_owners_sp->GetCompilerType());
-    }
-    return m_weak_count_sp;
   }
+
+  return lldb::ValueObjectSP();
 }
 
 bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
-  m_count_sp.reset();
-  m_weak_count_sp.reset();
   m_cntrl = nullptr;
 
   ValueObjectSP valobj_sp = m_backend.GetSP();
@@ -449,9 +429,6 @@
   if (!target_sp)
     return false;
 
-  m_byte_order = target_sp->GetArchitecture().GetByteOrder();
-  m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize();
-
   lldb::ValueObjectSP cntrl_sp(
       valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true));
 
@@ -469,10 +446,8 @@
     GetIndexOfChildWithName(ConstString name) {
   if (name == "__ptr_")
     return 0;
-  if (name == "count")
+  if (name == "$$dereference$$")
     return 1;
-  if (name == "weak_count")
-    return 2;
   return UINT32_MAX;
 }
 
@@ -488,7 +463,7 @@
 
 lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
     LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
-    : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() {
+    : SyntheticChildrenFrontEnd(*valobj_sp) {
   if (valobj_sp)
     Update();
 }
@@ -505,19 +480,27 @@
 
 size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
     CalculateNumChildren() {
-  return (m_compressed_pair_sp ? 1 : 0);
+  return (m_value_ptr_sp ? 1 : 0);
 }
 
 lldb::ValueObjectSP
 lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex(
     size_t idx) {
-  if (!m_compressed_pair_sp)
+  if (!m_value_ptr_sp)
     return lldb::ValueObjectSP();
 
-  if (idx != 0)
-    return lldb::ValueObjectSP();
+  if (idx == 0)
+    return m_value_ptr_sp;
 
-  return m_compressed_pair_sp;
+  if (idx == 1) {
+    Status status;
+    auto value_sp = m_value_ptr_sp->Dereference(status);
+    if (status.Success()) {
+      return value_sp;
+    }
+  }
+
+  return lldb::ValueObjectSP();
 }
 
 bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() {
@@ -530,7 +513,7 @@
   if (!ptr_sp)
     return false;
 
-  m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
+  m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp);
 
   return false;
 }
@@ -544,6 +527,8 @@
     GetIndexOfChildWithName(ConstString name) {
   if (name == "__value_")
     return 0;
+  if (name == "$$dereference$$")
+    return 1;
   return UINT32_MAX;
 }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index ea5a7c1..99e2065 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -105,10 +105,6 @@
 
 private:
   ValueObject *m_cntrl;
-  lldb::ValueObjectSP m_count_sp;
-  lldb::ValueObjectSP m_weak_count_sp;
-  uint8_t m_ptr_size;
-  lldb::ByteOrder m_byte_order;
 };
 
 class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
@@ -128,7 +124,7 @@
   ~LibcxxUniquePtrSyntheticFrontEnd() override;
 
 private:
-  lldb::ValueObjectSP m_compressed_pair_sp;
+  lldb::ValueObjectSP m_value_ptr_sp;
 };
 
 SyntheticChildrenFrontEnd *
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 6de4637..e5b868f 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -85,7 +85,7 @@
   CompilerType type;
   ValueObjectSP chunk;
   // For small bitsets __first_ is not an array, but a plain size_t.
-  if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) {
+  if (m_first->GetCompilerType().IsArrayType(&type)) {
     llvm::Optional<uint64_t> bit_size =
         type.GetBitSize(ctx.GetBestExecutionContextScope());
     if (!bit_size || *bit_size == 0)
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 0d5ae16..47c6634 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -27,8 +27,7 @@
 class ListEntry {
 public:
   ListEntry() = default;
-  ListEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
-  ListEntry(const ListEntry &rhs) = default;
+  ListEntry(ValueObjectSP entry_sp) : m_entry_sp(std::move(entry_sp)) {}
   ListEntry(ValueObject *entry)
       : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
 
@@ -73,9 +72,8 @@
 class ListIterator {
 public:
   ListIterator() = default;
-  ListIterator(ListEntry entry) : m_entry(entry) {}
-  ListIterator(ValueObjectSP entry) : m_entry(entry) {}
-  ListIterator(const ListIterator &rhs) = default;
+  ListIterator(ListEntry entry) : m_entry(std::move(entry)) {}
+  ListIterator(ValueObjectSP entry) : m_entry(std::move(entry)) {}
   ListIterator(ValueObject *entry) : m_entry(entry) {}
 
   ValueObjectSP value() { return m_entry.GetEntry(); }
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 64a199e..25c2bfd 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -26,7 +26,6 @@
 public:
   MapEntry() = default;
   explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
-  MapEntry(const MapEntry &rhs) = default;
   explicit MapEntry(ValueObject *entry)
       : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}
 
@@ -86,9 +85,9 @@
 public:
   MapIterator() = default;
   MapIterator(MapEntry entry, size_t depth = 0)
-      : m_entry(entry), m_max_depth(depth), m_error(false) {}
+      : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {}
   MapIterator(ValueObjectSP entry, size_t depth = 0)
-      : m_entry(entry), m_max_depth(depth), m_error(false) {}
+      : m_entry(std::move(entry)), m_max_depth(depth), m_error(false) {}
   MapIterator(const MapIterator &rhs)
       : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {}
   MapIterator(ValueObject *entry, size_t depth = 0)
@@ -138,7 +137,7 @@
   }
 
 private:
-  MapEntry tree_min(MapEntry &&x) {
+  MapEntry tree_min(MapEntry x) {
     if (x.null())
       return MapEntry();
     MapEntry left(x.left());
diff --git a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index 0b34b4e..79e864a 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -99,9 +99,17 @@
   if (ptr_obj)
     m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
 
-  ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
-  if (del_obj)
-    m_del_obj = del_obj->Clone(ConstString("deleter")).get();
+  // Add a 'deleter' child if there was a non-empty deleter type specified.
+  //
+  // The object might have size=1 in the TypeSystem but occupies no dedicated
+  // storage due to no_unique_address, so infer the actual size from the total
+  // size of the unique_ptr class. If sizeof(unique_ptr) == sizeof(void*) then
+  // the deleter is empty and should be hidden.
+  if (tuple_sp->GetByteSize() > ptr_obj->GetByteSize()) {
+    ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
+    if (del_obj)
+      m_del_obj = del_obj->Clone(ConstString("deleter")).get();
+  }
 
   if (m_ptr_obj) {
     Status error;
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
index d871d347..1479f4f 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -351,7 +351,7 @@
 }
 
 static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream,
-                                uint64_t value, lldb::LanguageType lang) {
+                                int64_t value, lldb::LanguageType lang) {
   static ConstString g_TypeHint("NSNumber:long");
 
   std::string prefix, suffix;
@@ -367,10 +367,10 @@
 }
 
 static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream,
-                                 const llvm::APInt &value,
-                                 lldb::LanguageType lang) {
+                                  const llvm::APInt &value,
+                                  lldb::LanguageType lang) {
   static ConstString g_TypeHint("NSNumber:int128_t");
-  
+
   std::string prefix, suffix;
   if (Language *language = Language::FindPlugin(lang)) {
     if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix,
@@ -379,11 +379,11 @@
       suffix.clear();
     }
   }
-  
+
   stream.PutCString(prefix.c_str());
   const int radix = 10;
   const bool isSigned = true;
-  std::string str = value.toString(radix, isSigned);
+  std::string str = llvm::toString(value, radix, isSigned);
   stream.PutCString(str.c_str());
   stream.PutCString(suffix.c_str());
 }
@@ -426,6 +426,7 @@
   if (!process_sp)
     return false;
 
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
   ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process_sp);
 
   if (!runtime)
@@ -456,9 +457,18 @@
     return NSDecimalNumberSummaryProvider(valobj, stream, options);
 
   if (class_name == "NSNumber" || class_name == "__NSCFNumber") {
-    uint64_t value = 0;
+    int64_t value = 0;
     uint64_t i_bits = 0;
-    if (descriptor->GetTaggedPointerInfo(&i_bits, &value)) {
+    if (descriptor->GetTaggedPointerInfoSigned(&i_bits, &value)) {
+      // Check for "preserved" numbers.  We still don't support them yet.
+      if (i_bits & 0x8) {
+        if (log)
+          log->Printf(
+              "Unsupported (preserved) NSNumber tagged pointer 0x%" PRIu64,
+              valobj_addr);
+        return false;
+      }
+
       switch (i_bits) {
       case 0:
         NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
@@ -498,49 +508,66 @@
         f64 = 0x5,
         sint128 = 0x6
       };
-      
+
       uint64_t data_location = valobj_addr + 2 * ptr_size;
       TypeCodes type_code;
-      
+
       if (new_format) {
-        uint64_t cfinfoa =
-            process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
-                                                      ptr_size, 0, error);
-        
+        uint64_t cfinfoa = process_sp->ReadUnsignedIntegerFromMemory(
+            valobj_addr + ptr_size, ptr_size, 0, error);
+
         if (error.Fail())
           return false;
 
         bool is_preserved_number = cfinfoa & 0x8;
         if (is_preserved_number) {
-          lldbassert(!static_cast<bool>("We should handle preserved numbers!"));
+          if (log)
+            log->Printf(
+                "Unsupported preserved NSNumber tagged pointer 0x%" PRIu64,
+                valobj_addr);
           return false;
         }
 
         type_code = static_cast<TypeCodes>(cfinfoa & 0x7);
       } else {
-        uint8_t data_type =
-        process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1,
-                                                  0, error) & 0x1F;
-        
+        uint8_t data_type = process_sp->ReadUnsignedIntegerFromMemory(
+                                valobj_addr + ptr_size, 1, 0, error) &
+                            0x1F;
+
         if (error.Fail())
           return false;
-        
+
         switch (data_type) {
-          case 1: type_code = TypeCodes::sint8; break;
-          case 2: type_code = TypeCodes::sint16; break;
-          case 3: type_code = TypeCodes::sint32; break;
-          case 17: data_location += 8; LLVM_FALLTHROUGH;
-          case 4: type_code = TypeCodes::sint64; break;
-          case 5: type_code = TypeCodes::f32; break;
-          case 6: type_code = TypeCodes::f64; break;
-          default: return false;
+        case 1:
+          type_code = TypeCodes::sint8;
+          break;
+        case 2:
+          type_code = TypeCodes::sint16;
+          break;
+        case 3:
+          type_code = TypeCodes::sint32;
+          break;
+        case 17:
+          data_location += 8;
+          LLVM_FALLTHROUGH;
+        case 4:
+          type_code = TypeCodes::sint64;
+          break;
+        case 5:
+          type_code = TypeCodes::f32;
+          break;
+        case 6:
+          type_code = TypeCodes::f64;
+          break;
+        default:
+          return false;
         }
       }
-      
+
       uint64_t value = 0;
       bool success = false;
       switch (type_code) {
-        case TypeCodes::sint8:
+      case TypeCodes::sint8:
         value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
                                                           error);
         if (error.Fail())
@@ -548,7 +575,7 @@
         NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
         success = true;
         break;
-        case TypeCodes::sint16:
+      case TypeCodes::sint16:
         value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
                                                           error);
         if (error.Fail())
@@ -573,8 +600,7 @@
         NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
         success = true;
         break;
-      case TypeCodes::f32:
-      {
+      case TypeCodes::f32: {
         uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(
             data_location, 4, 0, error);
         if (error.Fail())
@@ -585,8 +611,7 @@
         success = true;
         break;
       }
-      case TypeCodes::f64:
-      {
+      case TypeCodes::f64: {
         uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(
             data_location, 8, 0, error);
         if (error.Fail())
@@ -600,16 +625,17 @@
       case TypeCodes::sint128: // internally, this is the same
       {
         uint64_t words[2];
-        words[1] = process_sp->ReadUnsignedIntegerFromMemory(
-            data_location, 8, 0, error);
+        words[1] = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8,
+                                                             0, error);
         if (error.Fail())
           return false;
-        words[0] = process_sp->ReadUnsignedIntegerFromMemory(
-            data_location + 8, 8, 0, error);
+        words[0] = process_sp->ReadUnsignedIntegerFromMemory(data_location + 8,
+                                                             8, 0, error);
         if (error.Fail())
           return false;
         llvm::APInt i128_value(128, words);
-        NSNumber_FormatInt128(valobj, stream, i128_value, options.GetLanguage());
+        NSNumber_FormatInt128(valobj, stream, i128_value,
+                              options.GetLanguage());
         success = true;
         break;
       }
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index efc80cc..a862da5 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -13,7 +13,7 @@
 
 #include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Target/Target.h"
-#include <inttypes.h>
+#include <cinttypes>
 
 using namespace lldb;
 using namespace lldb_private;
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
index afb9c69..326f47a 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -410,6 +410,7 @@
   static const ConstString g_DictionaryM("__NSDictionaryM");
   static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
   static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable");
+  static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM");
   static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
   static const ConstString g_Dictionary0("__NSDictionary0");
   static const ConstString g_DictionaryCF("__CFDictionary");
@@ -427,7 +428,8 @@
       return false;
 
     value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
+  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy 
+             || class_name == g_DictionaryMFrozen) {
     AppleObjCRuntime *apple_runtime =
     llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
     Status error;
@@ -509,6 +511,7 @@
   static const ConstString g_DictionaryM("__NSDictionaryM");
   static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
   static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable");
+  static const ConstString g_DictionaryMFrozen("__NSFrozenDictionaryM");
   static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
   static const ConstString g_Dictionary0("__NSDictionary0");
   static const ConstString g_DictionaryCF("__CFDictionary");
@@ -520,7 +523,7 @@
 
   if (class_name == g_DictionaryI) {
     return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
-  } else if (class_name == g_DictionaryM) {
+  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMFrozen) {
     if (runtime->GetFoundationVersion() >= 1437) {
       return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp));
     } else if (runtime->GetFoundationVersion() >= 1428) {
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index a15b0f6..068bca9 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -209,14 +209,13 @@
         m_process = nullptr;
       }
 
-      InlinedIndexes()
-          : m_indexes(0), m_count(0), m_ptr_size(0), m_process(nullptr) {}
+      InlinedIndexes() {}
 
     private:
-      uint64_t m_indexes;
-      size_t m_count;
-      uint32_t m_ptr_size;
-      Process *m_process;
+      uint64_t m_indexes = 0;
+      size_t m_count = 0;
+      uint32_t m_ptr_size = 0;
+      Process *m_process = nullptr;
 
       // cfr. Foundation for the details of this code
       size_t _lengthForInlinePayload(uint32_t ptr_size) {
@@ -271,10 +270,10 @@
         m_count = 0;
       }
 
-      OutsourcedIndexes() : m_indexes(nullptr), m_count(0) {}
+      OutsourcedIndexes() {}
 
-      ValueObject *m_indexes;
-      size_t m_count;
+      ValueObject *m_indexes = nullptr;
+      size_t m_count = 0;
     };
 
     union {
@@ -288,9 +287,9 @@
       m_outsourced.Clear();
     }
 
-    Impl() : m_mode(Mode::Invalid) {}
+    Impl() {}
 
-    Mode m_mode;
+    Mode m_mode = Mode::Invalid;
   } m_impl;
 
   uint32_t m_ptr_size;
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
index 4dbbe6f..43ef7b6 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -444,18 +444,12 @@
   if (!valobj_sp)
     return false;
   m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  Status error;
-  if (valobj_sp->IsPointerType()) {
-    valobj_sp = valobj_sp->Dereference(error);
-    if (error.Fail() || !valobj_sp)
-      return false;
-  }
-  error.Clear();
   lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
   if (!process_sp)
     return false;
   m_ptr_size = process_sp->GetAddressByteSize();
-  uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+  Status error;
   if (m_ptr_size == 4) {
     m_data_32 = new DataDescriptor_32();
     process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
@@ -728,18 +722,12 @@
   if (!valobj_sp)
     return false;
   m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
-  Status error;
-  if (valobj_sp->IsPointerType()) {
-    valobj_sp = valobj_sp->Dereference(error);
-    if (error.Fail() || !valobj_sp)
-      return false;
-  }
-  error.Clear();
   lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
   if (!process_sp)
     return false;
   m_ptr_size = process_sp->GetAddressByteSize();
-  uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+  Status error;
   if (m_ptr_size == 4) {
     m_data_32 = new D32();
     process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 29391da..379c534 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -225,14 +225,17 @@
   return ConstString();
 }
 
-std::vector<ConstString>
+std::vector<Language::MethodNameVariant>
 ObjCLanguage::GetMethodNameVariants(ConstString method_name) const {
-  std::vector<ConstString> variant_names;
+  std::vector<Language::MethodNameVariant> variant_names;
   ObjCLanguage::MethodName objc_method(method_name.GetCString(), false);
   if (!objc_method.IsValid(false)) {
     return variant_names;
   }
 
+  variant_names.emplace_back(objc_method.GetSelector(),
+                             lldb::eFunctionNameTypeSelector);
+
   const bool is_class_method =
       objc_method.GetType() == MethodName::eTypeClassMethod;
   const bool is_instance_method =
@@ -242,31 +245,43 @@
 
   if (is_class_method || is_instance_method) {
     if (name_sans_category)
-      variant_names.emplace_back(name_sans_category);
+      variant_names.emplace_back(name_sans_category,
+                                 lldb::eFunctionNameTypeFull);
   } else {
     StreamString strm;
 
     strm.Printf("+%s", objc_method.GetFullName().GetCString());
-    variant_names.emplace_back(strm.GetString());
+    variant_names.emplace_back(ConstString(strm.GetString()),
+                               lldb::eFunctionNameTypeFull);
     strm.Clear();
 
     strm.Printf("-%s", objc_method.GetFullName().GetCString());
-    variant_names.emplace_back(strm.GetString());
+    variant_names.emplace_back(ConstString(strm.GetString()),
+                               lldb::eFunctionNameTypeFull);
     strm.Clear();
 
     if (name_sans_category) {
       strm.Printf("+%s", name_sans_category.GetCString());
-      variant_names.emplace_back(strm.GetString());
+      variant_names.emplace_back(ConstString(strm.GetString()),
+                                 lldb::eFunctionNameTypeFull);
       strm.Clear();
 
       strm.Printf("-%s", name_sans_category.GetCString());
-      variant_names.emplace_back(strm.GetString());
+      variant_names.emplace_back(ConstString(strm.GetString()),
+                                 lldb::eFunctionNameTypeFull);
     }
   }
 
   return variant_names;
 }
 
+bool ObjCLanguage::SymbolNameFitsToLanguage(Mangled mangled) const {
+  ConstString demangled_name = mangled.GetDemangledName();
+  if (!demangled_name)
+    return false;
+  return ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString());
+}
+
 static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
   if (!objc_category_sp)
     return;
@@ -990,8 +1005,11 @@
       bool result = false;
 
       if (auto *target = exe_scope->CalculateTarget().get()) {
-        if (auto *clang_modules_decl_vendor =
-                target->GetClangModulesDeclVendor()) {
+        auto *persistent_vars = llvm::cast<ClangPersistentVariables>(
+            target->GetPersistentExpressionStateForLanguage(
+                lldb::eLanguageTypeC));
+        if (std::shared_ptr<ClangModulesDeclVendor> clang_modules_decl_vendor =
+                persistent_vars->GetClangModulesDeclVendor()) {
           ConstString key_cs(key);
           auto types = clang_modules_decl_vendor->FindTypes(
               key_cs, /*max_matches*/ UINT32_MAX);
@@ -1116,7 +1134,7 @@
 bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
   const auto suffixes = {".h", ".m", ".M"};
   for (auto suffix : suffixes) {
-    if (file_path.endswith_lower(suffix))
+    if (file_path.endswith_insensitive(suffix))
       return true;
   }
   return false;
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
index 02c15e8..691c518 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -27,9 +27,7 @@
   public:
     enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
 
-    MethodName()
-        : m_full(), m_class(), m_category(), m_selector(),
-          m_type(eTypeUnspecified), m_category_is_valid(false) {}
+    MethodName() : m_full(), m_class(), m_category(), m_selector() {}
 
     MethodName(const char *name, bool strict)
         : m_full(), m_class(), m_category(), m_selector(),
@@ -81,8 +79,8 @@
         m_class_category;   // Class with category: "NSString(my_additions)"
     ConstString m_category; // Category:    "my_additions"
     ConstString m_selector; // Selector:    "myStringWithCString:"
-    Type m_type;
-    bool m_category_is_valid;
+    Type m_type = eTypeUnspecified;
+    bool m_category_is_valid = false;
   };
 
   ObjCLanguage() = default;
@@ -102,9 +100,12 @@
   //  variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"
   //  variant_names[2] => "+[NSString myStringWithCString:]"
   //  variant_names[3] => "-[NSString myStringWithCString:]"
-  std::vector<ConstString>
+  // Also returns the FunctionNameType of each possible name.
+  std::vector<Language::MethodNameVariant>
   GetMethodNameVariants(ConstString method_name) const override;
 
+  bool SymbolNameFitsToLanguage(Mangled mangled) const override;
+
   lldb::TypeCategoryImplSP GetFormatters() override;
 
   std::vector<ConstString>
diff --git a/src/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/src/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
index 0a4017e..3599785 100644
--- a/src/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
@@ -19,7 +19,7 @@
 bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
   const auto suffixes = {".h", ".mm"};
   for (auto suffix : suffixes) {
-    if (file_path.endswith_lower(suffix))
+    if (file_path.endswith_insensitive(suffix))
       return true;
   }
   return false;
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 24ab9cc..bed2a98 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <string.h>
+#include <cstring>
 
 #include <memory>
 
@@ -322,6 +322,9 @@
     }
   }
 
+  if (symbol == nullptr)
+    return optional_info;
+
   // Case 1 or 3
   if (scl.GetSize() >= 1) {
     optional_info = line_entry_helper(target, scl[0], symbol,
@@ -397,8 +400,8 @@
       // We create a ThreadPlan to keep stepping through using the address range
       // of the current function.
       ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
-          thread, range_of_curr_func, sc, eOnlyThisThread, eLazyBoolYes,
-          eLazyBoolYes);
+          thread, range_of_curr_func, sc, nullptr, eOnlyThisThread,
+          eLazyBoolYes, eLazyBoolYes);
       return ret_plan_sp;
     }
   }
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 6ea9751..f5b587c 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -196,7 +196,7 @@
   //
 
   class_type_or_name.Clear();
-  value_type = Value::ValueType::eValueTypeScalar;
+  value_type = Value::ValueType::Scalar;
 
   // Only a pointer or reference type can have a different dynamic and static
   // type:
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index bdd5c29..405b8a6 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -252,6 +252,7 @@
 }
 
 bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
+                                       lldb::addr_t relative_selector_base_addr,
                                        bool is_small, bool has_direct_sel) {
   size_t ptr_size = process->GetAddressByteSize();
   size_t size = GetSize(process, is_small);
@@ -281,6 +282,8 @@
                                                           0, error);
       if (!error.Success())
         return false;
+    } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
+      m_name_ptr = relative_selector_base_addr + nameref_offset;
     }
     m_types_ptr = addr + 4 + types_offset;
     m_imp_ptr = addr + 8 + imp_offset;
@@ -389,14 +392,14 @@
     if (base_method_list->m_entsize != method_t::GetSize(process, is_small))
       return false;
 
-    std::unique_ptr<method_t> method;
-    method = std::make_unique<method_t>();
-
+    std::unique_ptr<method_t> method = std::make_unique<method_t>();
+    lldb::addr_t relative_selector_base_addr =
+        m_runtime.GetRelativeSelectorBaseAddr();
     for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) {
       method->Read(process,
                    base_method_list->m_first_ptr +
                        (i * base_method_list->m_entsize),
-                   is_small, has_direct_selector);
+                   relative_selector_base_addr, is_small, has_direct_selector);
 
       if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
         break;
@@ -514,8 +517,7 @@
   return 0;
 }
 
-ClassDescriptorV2::iVarsStorage::iVarsStorage()
-    : m_filled(false), m_ivars(), m_mutex() {}
+ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {}
 
 size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 9ef21c6..7ba9579 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -41,6 +41,12 @@
     return false;
   }
 
+  bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+                                  int64_t *value_bits = nullptr,
+                                  uint64_t *payload = nullptr) override {
+    return false;
+  }
+
   uint64_t GetInstanceSize() override;
 
   ObjCLanguageRuntime::ObjCISA GetISA() override { return m_objc_class_ptr; }
@@ -71,16 +77,14 @@
   static const uint32_t RW_REALIZED = (1 << 31);
 
   struct objc_class_t {
-    ObjCLanguageRuntime::ObjCISA m_isa; // The class's metaclass.
-    ObjCLanguageRuntime::ObjCISA m_superclass;
-    lldb::addr_t m_cache_ptr;
-    lldb::addr_t m_vtable_ptr;
-    lldb::addr_t m_data_ptr;
-    uint8_t m_flags;
+    ObjCLanguageRuntime::ObjCISA m_isa = 0; // The class's metaclass.
+    ObjCLanguageRuntime::ObjCISA m_superclass = 0;
+    lldb::addr_t m_cache_ptr = 0;
+    lldb::addr_t m_vtable_ptr = 0;
+    lldb::addr_t m_data_ptr = 0;
+    uint8_t m_flags = 0;
 
-    objc_class_t()
-        : m_isa(0), m_superclass(0), m_cache_ptr(0), m_vtable_ptr(0),
-          m_data_ptr(0), m_flags(0) {}
+    objc_class_t() = default;
 
     void Clear() {
       m_isa = 0;
@@ -162,7 +166,8 @@
              + field_size; // IMP imp;
     }
 
-    bool Read(Process *process, lldb::addr_t addr, bool, bool);
+    bool Read(Process *process, lldb::addr_t addr,
+              lldb::addr_t relative_method_lists_base_addr, bool, bool);
   };
 
   struct ivar_list_t {
@@ -207,7 +212,7 @@
     void fill(AppleObjCRuntimeV2 &runtime, ClassDescriptorV2 &descriptor);
 
   private:
-    bool m_filled;
+    bool m_filled = false;
     std::vector<iVarDescriptor> m_ivars;
     std::recursive_mutex m_mutex;
   };
@@ -253,7 +258,7 @@
 
   ClassDescriptorV2Tagged(
       ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
-      uint64_t payload) {
+      uint64_t u_payload, int64_t s_payload) {
     if (!actual_class_sp) {
       m_valid = false;
       return;
@@ -264,9 +269,10 @@
       return;
     }
     m_valid = true;
-    m_payload = payload;
+    m_payload = u_payload;
     m_info_bits = (m_payload & 0x0FULL);
     m_value_bits = (m_payload & ~0x0FULL) >> 4;
+    m_value_bits_signed = (s_payload & ~0x0FLL) >> 4;
   }
 
   ~ClassDescriptorV2Tagged() override = default;
@@ -308,6 +314,18 @@
     return true;
   }
 
+  bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+                                  int64_t *value_bits = nullptr,
+                                  uint64_t *payload = nullptr) override {
+    if (info_bits)
+      *info_bits = GetInfoBits();
+    if (value_bits)
+      *value_bits = GetValueBitsSigned();
+    if (payload)
+      *payload = GetPayload();
+    return true;
+  }
+
   uint64_t GetInstanceSize() override {
     return (IsValid() ? m_pointer_size : 0);
   }
@@ -319,6 +337,10 @@
   // these calls are not part of any formal tagged pointers specification
   virtual uint64_t GetValueBits() { return (IsValid() ? m_value_bits : 0); }
 
+  virtual int64_t GetValueBitsSigned() {
+    return (IsValid() ? m_value_bits_signed : 0);
+  }
+
   virtual uint64_t GetInfoBits() { return (IsValid() ? m_info_bits : 0); }
 
   virtual uint64_t GetPayload() { return (IsValid() ? m_payload : 0); }
@@ -329,6 +351,7 @@
   bool m_valid;
   uint64_t m_info_bits;
   uint64_t m_value_bits;
+  int64_t m_value_bits_signed;
   uint64_t m_payload;
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 7b33130..9bc40c1 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -59,7 +59,7 @@
       clang::DeclContext::lookup_result result =
           non_const_interface_decl->lookup(name);
 
-      return (result.size() != 0);
+      return (!result.empty());
     } while (false);
 
     SetNoExternalVisibleDeclsForName(decl_ctx, name);
@@ -555,7 +555,7 @@
 
     if (!lookup_result.empty()) {
       if (clang::ObjCInterfaceDecl *result_iface_decl =
-              llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0])) {
+             llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
         if (log) {
           clang::QualType result_iface_type =
               ast_ctx.getObjCInterfaceType(result_iface_decl);
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 973a557..88e86c5 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -48,7 +48,7 @@
 
 char AppleObjCRuntime::ID = 0;
 
-AppleObjCRuntime::~AppleObjCRuntime() {}
+AppleObjCRuntime::~AppleObjCRuntime() = default;
 
 AppleObjCRuntime::AppleObjCRuntime(Process *process)
     : ObjCLanguageRuntime(process), m_read_objc_library(false),
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index b37e5a9..98d0e9c 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -49,7 +49,7 @@
     TypeAndOrName &class_type_or_name, Address &address,
     Value::ValueType &value_type) {
   class_type_or_name.Clear();
-  value_type = Value::ValueType::eValueTypeScalar;
+  value_type = Value::ValueType::Scalar;
   if (CouldHaveDynamicValue(in_value)) {
     auto class_descriptor(GetClassDescriptor(in_value));
     if (class_descriptor && class_descriptor->IsValid() &&
@@ -339,8 +339,6 @@
     if (!objc_module_sp)
       return;
 
-    uint32_t isa_count = 0;
-
     lldb::addr_t hash_table_ptr = GetISAHashTablePointer();
     if (hash_table_ptr != LLDB_INVALID_ADDRESS) {
       // Read the NXHashTable struct:
@@ -383,8 +381,6 @@
               if (bucket_isa_count == 0)
                 continue;
 
-              isa_count += bucket_isa_count;
-
               ObjCISA isa;
               if (bucket_isa_count == 1) {
                 // When we only have one entry in the bucket, the bucket data
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 4eb7d97..12ee2cc 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -64,6 +64,12 @@
       return false;
     }
 
+    bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+                                    int64_t *value_bits = nullptr,
+                                    uint64_t *payload = nullptr) override {
+      return false;
+    }
+
     uint64_t GetInstanceSize() override { return m_instance_size; }
 
     ObjCISA GetISA() override { return m_isa; }
@@ -120,8 +126,7 @@
 
   class HashTableSignature {
   public:
-    HashTableSignature()
-        : m_count(0), m_num_buckets(0), m_buckets_ptr(LLDB_INVALID_ADDRESS) {}
+    HashTableSignature() = default;
 
     bool NeedsUpdate(uint32_t count, uint32_t num_buckets,
                      lldb::addr_t buckets_ptr) {
@@ -137,9 +142,9 @@
     }
 
   protected:
-    uint32_t m_count;
-    uint32_t m_num_buckets;
-    lldb::addr_t m_buckets_ptr;
+    uint32_t m_count = 0;
+    uint32_t m_num_buckets = 0;
+    lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS;
   };
 
   lldb::addr_t GetISAHashTablePointer();
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index ee84ccd..10512a9 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stdint.h>
+#include <cstdint>
 
 #include <memory>
 #include <string>
@@ -39,6 +39,7 @@
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
@@ -75,8 +76,7 @@
 
 static const char *g_get_dynamic_class_info_name =
     "__lldb_apple_objc_v2_get_dynamic_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will need to revert to the code above...
+
 static const char *g_get_dynamic_class_info_body = R"(
 
 extern "C"
@@ -121,14 +121,20 @@
     if (grc)
     {
         const unsigned num_classes = grc->num_classes;
+        DEBUG_PRINTF ("num_classes = %u\n", grc->num_classes);
         if (class_infos_ptr)
         {
+            const unsigned num_buckets_minus_one = grc->num_buckets_minus_one;
+            DEBUG_PRINTF ("num_buckets_minus_one = %u\n", num_buckets_minus_one);
+
             const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+            DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
+
             ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
             BucketInfo *buckets = (BucketInfo *)grc->buckets;
-            
+
             uint32_t idx = 0;
-            for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
+            for (unsigned i=0; i<=num_buckets_minus_one; ++i)
             {
                 if (buckets[i].name_ptr != NX_MAPNOTAKEY)
                 {
@@ -140,6 +146,7 @@
                             h = ((h << 5) + h) + c;
                         class_infos[idx].hash = h;
                         class_infos[idx].isa = buckets[i].isa;
+                        DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, buckets[i].name_ptr);
                     }
                     ++idx;
                 }
@@ -157,6 +164,75 @@
 
 )";
 
+static const char *g_get_dynamic_class_info2_name =
+    "__lldb_apple_objc_v2_get_dynamic_class_info2";
+
+static const char *g_get_dynamic_class_info2_body = R"(
+
+extern "C" {
+    int printf(const char * format, ...);
+    void free(void *ptr);
+    Class* objc_copyRealizedClassList_nolock(unsigned int *outCount);
+    const char* objc_debug_class_getNameRaw(Class cls);
+}
+
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
+
+struct ClassInfo
+{
+    Class isa;
+    uint32_t hash;
+} __attribute__((__packed__));
+
+uint32_t
+__lldb_apple_objc_v2_get_dynamic_class_info2(void *gdb_objc_realized_classes_ptr,
+                                             void *class_infos_ptr,
+                                             uint32_t class_infos_byte_size,
+                                             uint32_t should_log)
+{
+    DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+    DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
+
+    const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+    DEBUG_PRINTF ("max_class_infos = %u\n", max_class_infos);
+
+    ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+
+    uint32_t count = 0;
+    Class* realized_class_list = objc_copyRealizedClassList_nolock(&count);
+    DEBUG_PRINTF ("count = %u\n", count);
+
+    uint32_t idx = 0;
+    for (uint32_t i=0; i<=count; ++i)
+    {
+        if (idx < max_class_infos)
+        {
+            Class isa = realized_class_list[i];
+            const char *name_ptr = objc_debug_class_getNameRaw(isa);
+            if (name_ptr == NULL)
+                continue;
+            const char *s = name_ptr;
+            uint32_t h = 5381;
+            for (unsigned char c = *s; c; c = *++s)
+                h = ((h << 5) + h) + c;
+            class_infos[idx].hash = h;
+            class_infos[idx].isa = isa;
+            DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name_ptr);
+        }
+        idx++;
+    }
+
+    if (idx < max_class_infos)
+    {
+        class_infos[idx].isa = NULL;
+        class_infos[idx].hash = 0;
+    }
+
+    free(realized_class_list);
+    return count;
+}
+)";
+
 // We'll substitute in class_getName or class_getNameRaw depending
 // on which is present.
 static const char *g_shared_cache_class_name_funcptr = R"(
@@ -169,8 +245,7 @@
 
 static const char *g_get_shared_cache_class_info_name =
     "__lldb_apple_objc_v2_get_shared_cache_class_info";
-// Testing using the new C++11 raw string literals. If this breaks GCC then we
-// will need to revert to the code above...
+
 static const char *g_get_shared_cache_class_info_body = R"(
 
 extern "C"
@@ -188,6 +263,12 @@
     int32_t hiOffset;
 };
 
+struct objc_classheader_v16_t {
+    uint64_t isDuplicate       : 1,
+             objectCacheOffset : 47, // Offset from the shared cache base
+             dylibObjCIndex    : 16;
+};
+
 struct objc_clsopt_t {
     uint32_t capacity;
     uint32_t occupied;
@@ -205,6 +286,22 @@
     //  objc_classheader_t duplicateOffsets[duplicateCount];
 };
 
+struct objc_clsopt_v16_t {
+   uint32_t version;
+   uint32_t capacity;
+   uint32_t occupied;
+   uint32_t shift;
+   uint32_t mask;
+   uint64_t salt;
+   uint32_t scramble[256];
+   uint8_t  tab[0]; // tab[mask+1]
+   //  uint8_t checkbytes[capacity];
+   //  int32_t offset[capacity];
+   //  objc_classheader_t clsOffsets[capacity];
+   //  uint32_t duplicateCount;
+   //  objc_classheader_t duplicateOffsets[duplicateCount];
+};
+
 struct objc_opt_t {
     uint32_t version;
     int32_t selopt_offset;
@@ -220,6 +317,20 @@
     int32_t clsopt_offset;
 };
 
+struct objc_opt_v16_t {
+    uint32_t version;
+    uint32_t flags;
+    int32_t selopt_offset;
+    int32_t headeropt_ro_offset;
+    int32_t unused_clsopt_offset;
+    int32_t unused_protocolopt_offset;
+    int32_t headeropt_rw_offset;
+    int32_t unused_protocolopt2_offset;
+    int32_t largeSharedCachesClassOffset;
+    int32_t largeSharedCachesProtocolOffset;
+    uint64_t relativeMethodSelectorBaseAddressCacheOffset;
+};
+
 struct ClassInfo
 {
     Class isa;
@@ -228,20 +339,33 @@
 
 uint32_t
 __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
+                                                  void *shared_cache_base_ptr,
                                                   void *class_infos_ptr,
+                                                  uint64_t *relative_selector_offset,
                                                   uint32_t class_infos_byte_size,
                                                   uint32_t should_log)
 {
+    *relative_selector_offset = 0;
     uint32_t idx = 0;
     DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
+    DEBUG_PRINTF ("shared_cache_base_ptr = %p\n", shared_cache_base_ptr);
     DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
     DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
     if (objc_opt_ro_ptr)
     {
         const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
         const objc_opt_v14_t* objc_opt_v14 = (objc_opt_v14_t*)objc_opt_ro_ptr;
-        const bool is_v14_format = objc_opt->version >= 14;
-        if (is_v14_format)
+        const objc_opt_v16_t* objc_opt_v16 = (objc_opt_v16_t*)objc_opt_ro_ptr;
+        if (objc_opt->version >= 16)
+        {
+            *relative_selector_offset = objc_opt_v16->relativeMethodSelectorBaseAddressCacheOffset;
+            DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v16->version);
+            DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v16->flags);
+            DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt_v16->selopt_offset);
+            DEBUG_PRINTF ("objc_opt->headeropt_ro_offset = %d\n", objc_opt_v16->headeropt_ro_offset);
+            DEBUG_PRINTF ("objc_opt->relativeMethodSelectorBaseAddressCacheOffset = %d\n", *relative_selector_offset);
+        }
+        else if (objc_opt->version >= 14)
         {
             DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt_v14->version);
             DEBUG_PRINTF ("objc_opt->flags = %u\n", objc_opt_v14->flags);
@@ -256,10 +380,126 @@
             DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
             DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
         }
-        if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15)
+
+        if (objc_opt->version == 16)
+        {
+            const objc_clsopt_v16_t* clsopt = (const objc_clsopt_v16_t*)((uint8_t *)objc_opt + objc_opt_v16->largeSharedCachesClassOffset);
+            const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+
+            DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
+
+            ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+
+            const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
+            const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
+            const objc_classheader_v16_t *classOffsets = (const objc_classheader_v16_t *)(offsets + clsopt->capacity);
+
+            DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
+            DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
+            DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+
+            for (uint32_t i=0; i<clsopt->capacity; ++i)
+            {
+                const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
+                DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
+
+                if (classOffsets[i].isDuplicate) {
+                    DEBUG_PRINTF("isDuplicate = true\n");
+                    continue; // duplicate
+                }
+
+                if (objectCacheOffset == 0) {
+                    DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
+                    continue; // invalid offset
+                }
+
+                if (class_infos && idx < max_class_infos)
+                {
+                    class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
+
+                    // Lookup the class name.
+                    const char *name = class_name_lookup_func(class_infos[idx].isa);
+                    DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+
+                    // Hash the class name so we don't have to read it.
+                    const char *s = name;
+                    uint32_t h = 5381;
+                    for (unsigned char c = *s; c; c = *++s)
+                    {
+                        // class_getName demangles swift names and the hash must
+                        // be calculated on the mangled name.  hash==0 means lldb
+                        // will fetch the mangled name and compute the hash in
+                        // ParseClassInfoArray.
+                        if (c == '.')
+                        {
+                            h = 0;
+                            break;
+                        }
+                        h = ((h << 5) + h) + c;
+                    }
+                    class_infos[idx].hash = h;
+                }
+                else
+                {
+                    DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
+                }
+                ++idx;
+            }
+
+            const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
+            const uint32_t duplicate_count = *duplicate_count_ptr;
+            const objc_classheader_v16_t *duplicateClassOffsets = (const objc_classheader_v16_t *)(&duplicate_count_ptr[1]);
+
+            DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
+            DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
+
+            for (uint32_t i=0; i<duplicate_count; ++i)
+            {
+                const uint64_t objectCacheOffset = classOffsets[i].objectCacheOffset;
+                DEBUG_PRINTF("objectCacheOffset[%u] = %u\n", i, objectCacheOffset);
+
+                if (classOffsets[i].isDuplicate) {
+                    DEBUG_PRINTF("isDuplicate = true\n");
+                    continue; // duplicate
+                }
+
+                if (objectCacheOffset == 0) {
+                    DEBUG_PRINTF("objectCacheOffset == invalidEntryOffset\n");
+                    continue; // invalid offset
+                }
+
+                if (class_infos && idx < max_class_infos)
+                {
+                    class_infos[idx].isa = (Class)((uint8_t *)shared_cache_base_ptr + objectCacheOffset);
+
+                    // Lookup the class name.
+                    const char *name = class_name_lookup_func(class_infos[idx].isa);
+                    DEBUG_PRINTF("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+
+                    // Hash the class name so we don't have to read it.
+                    const char *s = name;
+                    uint32_t h = 5381;
+                    for (unsigned char c = *s; c; c = *++s)
+                    {
+                        // class_getName demangles swift names and the hash must
+                        // be calculated on the mangled name.  hash==0 means lldb
+                        // will fetch the mangled name and compute the hash in
+                        // ParseClassInfoArray.
+                        if (c == '.')
+                        {
+                            h = 0;
+                            break;
+                        }
+                        h = ((h << 5) + h) + c;
+                    }
+                    class_infos[idx].hash = h;
+                }
+            }
+        }
+        else if (objc_opt->version >= 12 && objc_opt->version <= 15)
         {
             const objc_clsopt_t* clsopt = NULL;
-            if (is_v14_format)
+            if (objc_opt->version >= 14)
                 clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt_v14 + objc_opt_v14->clsopt_offset);
             else
                 clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
@@ -291,7 +531,7 @@
                     DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
                     continue; // invalid offset
                 }
-                
+
                 if (class_infos && idx < max_class_infos)
                 {
                     class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
@@ -321,7 +561,7 @@
                 }
                 ++idx;
             }
-            
+
             const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
             const uint32_t duplicate_count = *duplicate_count_ptr;
             const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
@@ -334,7 +574,7 @@
                     continue; // duplicate
                 else if (clsOffset == invalidEntryOffset)
                     continue; // invalid offset
-                
+
                 if (class_infos && idx < max_class_infos)
                 {
                     class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
@@ -353,7 +593,7 @@
                         {
                             h = 0;
                             break;
-                        } 
+                        }
                         h = ((h << 5) + h) + c;
                     }
                     class_infos[idx].hash = h;
@@ -380,55 +620,57 @@
     error.SetErrorString("no process");
     return default_value;
   }
+
   if (!module_sp) {
     error.SetErrorString("no module");
     return default_value;
   }
+
   if (!byte_size)
     byte_size = process->GetAddressByteSize();
   const Symbol *symbol =
       module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
-  if (symbol && symbol->ValueIsAddress()) {
-    lldb::addr_t symbol_load_addr =
-        symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
-    if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
-      if (read_value)
-        return process->ReadUnsignedIntegerFromMemory(
-            symbol_load_addr, byte_size, default_value, error);
-      else
-        return symbol_load_addr;
-    } else {
-      error.SetErrorString("symbol address invalid");
-      return default_value;
-    }
-  } else {
+
+  if (!symbol || !symbol->ValueIsAddress()) {
     error.SetErrorString("no symbol");
     return default_value;
   }
+
+  lldb::addr_t symbol_load_addr =
+      symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
+  if (symbol_load_addr == LLDB_INVALID_ADDRESS) {
+    error.SetErrorString("symbol address invalid");
+    return default_value;
+  }
+
+  if (read_value)
+    return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size,
+                                                  default_value, error);
+  return symbol_load_addr;
 }
 
 static void RegisterObjCExceptionRecognizer(Process *process);
 
 AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
                                        const ModuleSP &objc_module_sp)
-    : AppleObjCRuntime(process), m_get_class_info_code(),
-      m_get_class_info_args(LLDB_INVALID_ADDRESS),
-      m_get_class_info_args_mutex(), m_get_shared_cache_class_info_code(),
-      m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
-      m_get_shared_cache_class_info_args_mutex(), m_decl_vendor_up(),
+    : AppleObjCRuntime(process), m_objc_module_sp(objc_module_sp),
+      m_dynamic_class_info_extractor(*this),
+      m_shared_cache_class_info_extractor(*this), m_decl_vendor_up(),
       m_tagged_pointer_obfuscator(LLDB_INVALID_ADDRESS),
-      m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS), m_hash_signature(),
-      m_has_object_getClass(false), m_loaded_objc_opt(false),
-      m_non_pointer_isa_cache_up(
-          NonPointerISACache::CreateInstance(*this, objc_module_sp)),
+      m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
+      m_relative_selector_base(LLDB_INVALID_ADDRESS), m_hash_signature(),
+      m_has_object_getClass(false), m_has_objc_copyRealizedClassList(false),
+      m_loaded_objc_opt(false), m_non_pointer_isa_cache_up(),
       m_tagged_pointer_vendor_up(
           TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
       m_encoding_to_type_sp(), m_noclasses_warning_emitted(false),
-      m_CFBoolean_values() {
+      m_CFBoolean_values(), m_realized_class_generation_count(0) {
   static const ConstString g_gdb_object_getClass("gdb_object_getClass");
-  m_has_object_getClass =
-      (objc_module_sp->FindFirstSymbolWithNameAndType(
-           g_gdb_object_getClass, eSymbolTypeCode) != nullptr);
+  m_has_object_getClass = HasSymbol(g_gdb_object_getClass);
+  static const ConstString g_objc_copyRealizedClassList(
+      "_ZL33objc_copyRealizedClassList_nolockPj");
+  m_has_objc_copyRealizedClassList = HasSymbol(g_objc_copyRealizedClassList);
+
   RegisterObjCExceptionRecognizer(process);
 }
 
@@ -451,7 +693,7 @@
     assert(in_value.GetTargetSP().get() == m_process->CalculateTarget().get());
 
   class_type_or_name.Clear();
-  value_type = Value::ValueType::eValueTypeScalar;
+  value_type = Value::ValueType::Scalar;
 
   // Make sure we can have a dynamic value before starting...
   if (CouldHaveDynamicValue(in_value)) {
@@ -498,15 +740,21 @@
     if (AppleObjCRuntime::GetObjCVersion(process, objc_module_sp) ==
         ObjCRuntimeVersions::eAppleObjC_V2)
       return new AppleObjCRuntimeV2(process, objc_module_sp);
-    else
-      return nullptr;
-  } else
     return nullptr;
+  }
+  return nullptr;
 }
 
 static constexpr OptionDefinition g_objc_classtable_dump_options[] = {
-    {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument,
-     nullptr, {}, 0, eArgTypeNone,
+    {LLDB_OPT_SET_ALL,
+     false,
+     "verbose",
+     'v',
+     OptionParser::eNoArgument,
+     nullptr,
+     {},
+     0,
+     eArgTypeNone,
      "Print ivar and method information in detail"}};
 
 class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed {
@@ -548,12 +796,13 @@
   };
 
   CommandObjectObjC_ClassTable_Dump(CommandInterpreter &interpreter)
-      : CommandObjectParsed(
-            interpreter, "dump", "Dump information on Objective-C classes "
-                                 "known to the current process.",
-            "language objc class-table dump",
-            eCommandRequiresProcess | eCommandProcessMustBeLaunched |
-                eCommandProcessMustBePaused),
+      : CommandObjectParsed(interpreter, "dump",
+                            "Dump information on Objective-C classes "
+                            "known to the current process.",
+                            "language objc class-table dump",
+                            eCommandRequiresProcess |
+                                eCommandProcessMustBeLaunched |
+                                eCommandProcessMustBePaused),
         m_options() {
     CommandArgumentEntry arg;
     CommandArgumentData index_arg;
@@ -581,8 +830,8 @@
     case 0:
       break;
     case 1: {
-      regex_up = std::make_unique<RegularExpression>(
-          llvm::StringRef::withNullAsEmpty(command.GetArgumentAtIndex(0)));
+      regex_up =
+          std::make_unique<RegularExpression>(command.GetArgumentAtIndex(0));
       if (!regex_up->IsValid()) {
         result.AppendError(
             "invalid argument - please provide a valid regular expression");
@@ -632,6 +881,7 @@
                   ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
                   ivar.m_size, ivar.m_offset);
             }
+
             iterator->second->Describe(
                 nullptr,
                 [&std_out](const char *name, const char *type) -> bool {
@@ -655,11 +905,10 @@
       }
       result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
       return true;
-    } else {
-      result.AppendError("current process has no Objective-C runtime loaded");
-      result.SetStatus(lldb::eReturnStatusFailed);
-      return false;
     }
+    result.AppendError("current process has no Objective-C runtime loaded");
+    result.SetStatus(lldb::eReturnStatusFailed);
+    return false;
   }
 
   CommandOptions m_options;
@@ -741,11 +990,10 @@
       }
       result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
       return true;
-    } else {
-      result.AppendError("current process has no Objective-C runtime loaded");
-      result.SetStatus(lldb::eReturnStatusFailed);
-      return false;
     }
+    result.AppendError("current process has no Objective-C runtime loaded");
+    result.SetStatus(lldb::eReturnStatusFailed);
+    return false;
   }
 };
 
@@ -951,11 +1199,7 @@
 
 class RemoteNXMapTable {
 public:
-  RemoteNXMapTable()
-      : m_count(0), m_num_buckets_minus_one(0),
-        m_buckets_ptr(LLDB_INVALID_ADDRESS), m_process(nullptr),
-        m_end_iterator(*this, -1), m_load_addr(LLDB_INVALID_ADDRESS),
-        m_map_pair_size(0), m_invalid_key(0) {}
+  RemoteNXMapTable() : m_end_iterator(*this, -1) {}
 
   void Dump() {
     printf("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
@@ -1129,18 +1373,17 @@
 
 private:
   // contents of _NXMapTable struct
-  uint32_t m_count;
-  uint32_t m_num_buckets_minus_one;
-  lldb::addr_t m_buckets_ptr;
-  lldb_private::Process *m_process;
+  uint32_t m_count = 0;
+  uint32_t m_num_buckets_minus_one = 0;
+  lldb::addr_t m_buckets_ptr = LLDB_INVALID_ADDRESS;
+  lldb_private::Process *m_process = nullptr;
   const_iterator m_end_iterator;
-  lldb::addr_t m_load_addr;
-  size_t m_map_pair_size;
-  lldb::addr_t m_invalid_key;
+  lldb::addr_t m_load_addr = LLDB_INVALID_ADDRESS;
+  size_t m_map_pair_size = 0;
+  lldb::addr_t m_invalid_key = 0;
 };
 
-AppleObjCRuntimeV2::HashTableSignature::HashTableSignature()
-    : m_count(0), m_num_buckets(0), m_buckets_ptr(0) {}
+AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() = default;
 
 void AppleObjCRuntimeV2::HashTableSignature::UpdateSignature(
     const RemoteNXMapTable &hash_table) {
@@ -1171,8 +1414,8 @@
 ObjCLanguageRuntime::ClassDescriptorSP
 AppleObjCRuntimeV2::GetClassDescriptorFromISA(ObjCISA isa) {
   ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
-  if (m_non_pointer_isa_cache_up)
-    class_descriptor_sp = m_non_pointer_isa_cache_up->GetClassDescriptor(isa);
+  if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
+    class_descriptor_sp = non_pointer_isa_cache->GetClassDescriptor(isa);
   if (!class_descriptor_sp)
     class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
   return class_descriptor_sp;
@@ -1214,11 +1457,9 @@
 
   objc_class_sp = GetClassDescriptorFromISA(isa);
   if (isa && !objc_class_sp) {
-    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS |
-                                      LIBLLDB_LOG_TYPES));
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
     LLDB_LOGF(log,
-              "0x%" PRIx64
-              ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
+              "0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was "
               "not in class descriptor cache 0x%" PRIx64,
               isa_pointer, isa);
   }
@@ -1229,28 +1470,29 @@
   if (m_tagged_pointer_obfuscator != LLDB_INVALID_ADDRESS)
     return m_tagged_pointer_obfuscator;
 
-
   Process *process = GetProcess();
   ModuleSP objc_module_sp(GetObjCModule());
 
   if (!objc_module_sp)
     return LLDB_INVALID_ADDRESS;
 
-  static ConstString g_gdb_objc_obfuscator("objc_debug_taggedpointer_obfuscator");
+  static ConstString g_gdb_objc_obfuscator(
+      "objc_debug_taggedpointer_obfuscator");
 
   const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(
-  g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
+      g_gdb_objc_obfuscator, lldb::eSymbolTypeAny);
   if (symbol) {
     lldb::addr_t g_gdb_obj_obfuscator_ptr =
-      symbol->GetLoadAddress(&process->GetTarget());
+        symbol->GetLoadAddress(&process->GetTarget());
 
     if (g_gdb_obj_obfuscator_ptr != LLDB_INVALID_ADDRESS) {
       Status error;
-      m_tagged_pointer_obfuscator = process->ReadPointerFromMemory(
-        g_gdb_obj_obfuscator_ptr, error);
+      m_tagged_pointer_obfuscator =
+          process->ReadPointerFromMemory(g_gdb_obj_obfuscator_ptr, error);
     }
   }
-  // If we don't have a correct value at this point, there must be no obfuscation.
+  // If we don't have a correct value at this point, there must be no
+  // obfuscation.
   if (m_tagged_pointer_obfuscator == LLDB_INVALID_ADDRESS)
     m_tagged_pointer_obfuscator = 0;
 
@@ -1284,11 +1526,212 @@
   return m_isa_hash_table_ptr;
 }
 
-AppleObjCRuntimeV2::DescriptorMapUpdateResult
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
-    RemoteNXMapTable &hash_table) {
-  Process *process = GetProcess();
+std::unique_ptr<UtilityFunction>
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl(
+    ExecutionContext &exe_ctx, std::string code, std::string name) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
 
+  LLDB_LOG(log, "Creating utility function {0}", name);
+
+  TypeSystemClang *ast =
+      ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef());
+  if (!ast)
+    return {};
+
+  auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+      std::move(code), std::move(name), eLanguageTypeC, exe_ctx);
+  if (!utility_fn_or_error) {
+    LLDB_LOG_ERROR(
+        log, utility_fn_or_error.takeError(),
+        "Failed to get utility function for implementation lookup: {0}");
+    return {};
+  }
+
+  // Make some types for our arguments.
+  CompilerType clang_uint32_t_type =
+      ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+  CompilerType clang_void_pointer_type =
+      ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+  // Make the runner function for our implementation utility function.
+  ValueList arguments;
+  Value value;
+  value.SetValueType(Value::ValueType::Scalar);
+  value.SetCompilerType(clang_void_pointer_type);
+  arguments.PushValue(value);
+  arguments.PushValue(value);
+  value.SetValueType(Value::ValueType::Scalar);
+  value.SetCompilerType(clang_uint32_t_type);
+  arguments.PushValue(value);
+  arguments.PushValue(value);
+
+  std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
+
+  Status error;
+  utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
+                                 exe_ctx.GetThreadSP(), error);
+
+  if (error.Fail()) {
+    LLDB_LOG(log,
+             "Failed to make function caller for implementation lookup: {0}.",
+             error.AsCString());
+    return {};
+  }
+
+  return utility_fn;
+}
+
+UtilityFunction *
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunction(
+    ExecutionContext &exe_ctx, Helper helper) {
+  switch (helper) {
+  case gdb_objc_realized_classes: {
+    if (!m_gdb_objc_realized_classes_helper.utility_function)
+      m_gdb_objc_realized_classes_helper.utility_function =
+          GetClassInfoUtilityFunctionImpl(exe_ctx,
+                                          g_get_dynamic_class_info_body,
+                                          g_get_dynamic_class_info_name);
+    return m_gdb_objc_realized_classes_helper.utility_function.get();
+  }
+  case objc_copyRealizedClassList: {
+    if (!m_objc_copyRealizedClassList_helper.utility_function)
+      m_objc_copyRealizedClassList_helper.utility_function =
+          GetClassInfoUtilityFunctionImpl(exe_ctx,
+                                          g_get_dynamic_class_info2_body,
+                                          g_get_dynamic_class_info2_name);
+    return m_objc_copyRealizedClassList_helper.utility_function.get();
+  }
+  }
+  llvm_unreachable("Unexpected helper");
+}
+
+lldb::addr_t &
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoArgs(Helper helper) {
+  switch (helper) {
+  case gdb_objc_realized_classes:
+    return m_gdb_objc_realized_classes_helper.args;
+  case objc_copyRealizedClassList:
+    return m_objc_copyRealizedClassList_helper.args;
+  }
+  llvm_unreachable("Unexpected helper");
+}
+
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::Helper
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::ComputeHelper() const {
+  if (!m_runtime.m_has_objc_copyRealizedClassList)
+    return DynamicClassInfoExtractor::gdb_objc_realized_classes;
+
+  if (Process *process = m_runtime.GetProcess()) {
+    if (DynamicLoader *loader = process->GetDynamicLoader()) {
+      if (loader->IsFullyInitialized())
+        return DynamicClassInfoExtractor::objc_copyRealizedClassList;
+    }
+  }
+
+  return DynamicClassInfoExtractor::gdb_objc_realized_classes;
+}
+
+std::unique_ptr<UtilityFunction>
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::
+    GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+
+  LLDB_LOG(log, "Creating utility function {0}",
+           g_get_shared_cache_class_info_name);
+
+  TypeSystemClang *ast =
+      ScratchTypeSystemClang::GetForTarget(exe_ctx.GetTargetRef());
+  if (!ast)
+    return {};
+
+  // If the inferior objc.dylib has the class_getNameRaw function, use that in
+  // our jitted expression.  Else fall back to the old class_getName.
+  static ConstString g_class_getName_symbol_name("class_getName");
+  static ConstString g_class_getNameRaw_symbol_name(
+      "objc_debug_class_getNameRaw");
+
+  ConstString class_name_getter_function_name =
+      m_runtime.HasSymbol(g_class_getNameRaw_symbol_name)
+          ? g_class_getNameRaw_symbol_name
+          : g_class_getName_symbol_name;
+
+  // Substitute in the correct class_getName / class_getNameRaw function name,
+  // concatenate the two parts of our expression text.  The format string has
+  // two %s's, so provide the name twice.
+  std::string shared_class_expression;
+  llvm::raw_string_ostream(shared_class_expression)
+      << llvm::format(g_shared_cache_class_name_funcptr,
+                      class_name_getter_function_name.AsCString(),
+                      class_name_getter_function_name.AsCString());
+
+  shared_class_expression += g_get_shared_cache_class_info_body;
+
+  auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
+      std::move(shared_class_expression), g_get_shared_cache_class_info_name,
+      eLanguageTypeC, exe_ctx);
+
+  if (!utility_fn_or_error) {
+    LLDB_LOG_ERROR(
+        log, utility_fn_or_error.takeError(),
+        "Failed to get utility function for implementation lookup: {0}");
+    return nullptr;
+  }
+
+  // Make some types for our arguments.
+  CompilerType clang_uint32_t_type =
+      ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+  CompilerType clang_void_pointer_type =
+      ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+  CompilerType clang_uint64_t_pointer_type =
+      ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 64)
+          .GetPointerType();
+
+  // Next make the function caller for our implementation utility function.
+  ValueList arguments;
+  Value value;
+  value.SetValueType(Value::ValueType::Scalar);
+  value.SetCompilerType(clang_void_pointer_type);
+  arguments.PushValue(value);
+  arguments.PushValue(value);
+  arguments.PushValue(value);
+
+  value.SetValueType(Value::ValueType::Scalar);
+  value.SetCompilerType(clang_uint64_t_pointer_type);
+  arguments.PushValue(value);
+
+  value.SetValueType(Value::ValueType::Scalar);
+  value.SetCompilerType(clang_uint32_t_type);
+  arguments.PushValue(value);
+  arguments.PushValue(value);
+
+  std::unique_ptr<UtilityFunction> utility_fn = std::move(*utility_fn_or_error);
+
+  Status error;
+  utility_fn->MakeFunctionCaller(clang_uint32_t_type, arguments,
+                                 exe_ctx.GetThreadSP(), error);
+
+  if (error.Fail()) {
+    LLDB_LOG(log,
+             "Failed to make function caller for implementation lookup: {0}.",
+             error.AsCString());
+    return {};
+  }
+
+  return utility_fn;
+}
+
+UtilityFunction *
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::GetClassInfoUtilityFunction(
+    ExecutionContext &exe_ctx) {
+  if (!m_utility_function)
+    m_utility_function = GetClassInfoUtilityFunctionImpl(exe_ctx);
+  return m_utility_function.get();
+}
+
+AppleObjCRuntimeV2::DescriptorMapUpdateResult
+AppleObjCRuntimeV2::DynamicClassInfoExtractor::UpdateISAToDescriptorMap(
+    RemoteNXMapTable &hash_table) {
+  Process *process = m_runtime.GetProcess();
   if (process == nullptr)
     return DescriptorMapUpdateResult::Fail();
 
@@ -1316,65 +1759,36 @@
 
   Status err;
 
+  // Compute which helper we're going to use for this update.
+  const DynamicClassInfoExtractor::Helper helper = ComputeHelper();
+
   // Read the total number of classes from the hash table
-  const uint32_t num_classes = hash_table.GetCount();
+  const uint32_t num_classes =
+      helper == DynamicClassInfoExtractor::gdb_objc_realized_classes
+          ? hash_table.GetCount()
+          : m_runtime.m_realized_class_generation_count;
   if (num_classes == 0) {
-    LLDB_LOGF(log, "No dynamic classes found in gdb_objc_realized_classes.");
+    LLDB_LOGF(log, "No dynamic classes found.");
     return DescriptorMapUpdateResult::Success(0);
   }
 
-  // Make some types for our arguments
-  CompilerType clang_uint32_t_type =
-      ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-  CompilerType clang_void_pointer_type =
-      ast->GetBasicType(eBasicTypeVoid).GetPointerType();
-
-  ValueList arguments;
-  FunctionCaller *get_class_info_function = nullptr;
-
-  if (!m_get_class_info_code) {
-    auto utility_fn_or_error = GetTargetRef().CreateUtilityFunction(
-        g_get_dynamic_class_info_body, g_get_dynamic_class_info_name,
-        eLanguageTypeC, exe_ctx);
-    if (!utility_fn_or_error) {
-      LLDB_LOG_ERROR(
-          log, utility_fn_or_error.takeError(),
-          "Failed to get utility function for implementation lookup: {0}");
-      return DescriptorMapUpdateResult::Fail();
-    }
-    m_get_class_info_code = std::move(*utility_fn_or_error);
-
-    // Next make the runner function for our implementation utility function.
-    Value value;
-    value.SetValueType(Value::eValueTypeScalar);
-    value.SetCompilerType(clang_void_pointer_type);
-    arguments.PushValue(value);
-    arguments.PushValue(value);
-
-    value.SetValueType(Value::eValueTypeScalar);
-    value.SetCompilerType(clang_uint32_t_type);
-    arguments.PushValue(value);
-    arguments.PushValue(value);
-
-    Status error;
-    get_class_info_function = m_get_class_info_code->MakeFunctionCaller(
-        clang_uint32_t_type, arguments, thread_sp, error);
-
-    if (error.Fail()) {
-      LLDB_LOGF(log,
-                "Failed to make function caller for implementation lookup: %s.",
-                error.AsCString());
-      return DescriptorMapUpdateResult::Fail();
-    }
-  } else {
-    get_class_info_function = m_get_class_info_code->GetFunctionCaller();
-    if (!get_class_info_function) {
-      LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
-      return DescriptorMapUpdateResult::Fail();
-    }
-    arguments = get_class_info_function->GetArgumentValues();
+  UtilityFunction *get_class_info_code =
+      GetClassInfoUtilityFunction(exe_ctx, helper);
+  if (!get_class_info_code) {
+    // The callee will have already logged a useful error message.
+    return DescriptorMapUpdateResult::Fail();
   }
 
+  FunctionCaller *get_class_info_function =
+      get_class_info_code->GetFunctionCaller();
+
+  if (!get_class_info_function) {
+    LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
+    return DescriptorMapUpdateResult::Fail();
+  }
+
+  ValueList arguments = get_class_info_function->GetArgumentValues();
+
   DiagnosticManager diagnostics;
 
   const uint32_t class_info_byte_size = addr_size + 4;
@@ -1390,18 +1804,18 @@
     return DescriptorMapUpdateResult::Fail();
   }
 
-  std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+  std::lock_guard<std::mutex> guard(m_mutex);
 
   // Fill in our function argument values
   arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
   arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
   arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
-  
+
   // Only dump the runtime classes from the expression evaluation if the log is
   // verbose:
   Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
   bool dump_log = type_log && type_log->GetVerbose();
-  
+
   arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0;
 
   bool success = false;
@@ -1410,7 +1824,7 @@
 
   // Write our function arguments into the process so we can run our function
   if (get_class_info_function->WriteFunctionArguments(
-          exe_ctx, m_get_class_info_args, arguments, diagnostics)) {
+          exe_ctx, GetClassInfoArgs(helper), arguments, diagnostics)) {
     EvaluateExpressionOptions options;
     options.SetUnwindOnError(true);
     options.SetTryAllThreads(false);
@@ -1419,8 +1833,11 @@
     options.SetTimeout(process->GetUtilityExpressionTimeout());
     options.SetIsForUtilityExpr(true);
 
+    CompilerType clang_uint32_t_type =
+        ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
     Value return_value;
-    return_value.SetValueType(Value::eValueTypeScalar);
+    return_value.SetValueType(Value::ValueType::Scalar);
     return_value.SetCompilerType(clang_uint32_t_type);
     return_value.GetScalar() = 0;
 
@@ -1428,12 +1845,12 @@
 
     // Run the function
     ExpressionResults results = get_class_info_function->ExecuteFunction(
-        exe_ctx, &m_get_class_info_args, options, diagnostics, return_value);
+        exe_ctx, &GetClassInfoArgs(helper), options, diagnostics, return_value);
 
     if (results == eExpressionCompleted) {
       // The result is the number of ClassInfo structures that were filled in
       num_class_infos = return_value.GetScalar().ULong();
-      LLDB_LOGF(log, "Discovered %u ObjC classes\n", num_class_infos);
+      LLDB_LOG(log, "Discovered {0} Objective-C classes", num_class_infos);
       if (num_class_infos > 0) {
         // Read the ClassInfo structures
         DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
@@ -1443,7 +1860,7 @@
           DataExtractor class_infos_data(buffer.GetBytes(),
                                          buffer.GetByteSize(),
                                          process->GetByteOrder(), addr_size);
-          ParseClassInfoArray(class_infos_data, num_class_infos);
+          m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
         }
       }
       success = true;
@@ -1507,15 +1924,16 @@
       ClassDescriptorSP descriptor_sp(
           new ClassDescriptorV2(*this, isa, nullptr));
 
-      // The code in g_get_shared_cache_class_info_body sets the value of the hash
-      // to 0 to signal a demangled symbol. We use class_getName() in that code to
-      // find the class name, but this returns a demangled name for Swift symbols.
-      // For those symbols, recompute the hash here by reading their name from the
-      // runtime.
+      // The code in g_get_shared_cache_class_info_body sets the value of the
+      // hash to 0 to signal a demangled symbol. We use class_getName() in that
+      // code to find the class name, but this returns a demangled name for
+      // Swift symbols. For those symbols, recompute the hash here by reading
+      // their name from the runtime.
       if (name_hash)
         AddClass(isa, descriptor_sp, name_hash);
       else
-        AddClass(isa, descriptor_sp, descriptor_sp->GetClassName().AsCString(nullptr));
+        AddClass(isa, descriptor_sp,
+                 descriptor_sp->GetClassName().AsCString(nullptr));
       num_parsed++;
       if (should_log)
         LLDB_LOGF(log,
@@ -1531,10 +1949,20 @@
   return num_parsed;
 }
 
-AppleObjCRuntimeV2::DescriptorMapUpdateResult
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
-  Process *process = GetProcess();
+bool AppleObjCRuntimeV2::HasSymbol(ConstString Name) {
+  if (!m_objc_module_sp)
+    return false;
+  if (const Symbol *symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType(
+          Name, lldb::eSymbolTypeCode)) {
+    if (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())
+      return true;
+  }
+  return false;
+}
 
+AppleObjCRuntimeV2::DescriptorMapUpdateResult
+AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() {
+  Process *process = m_runtime.GetProcess();
   if (process == nullptr)
     return DescriptorMapUpdateResult::Fail();
 
@@ -1562,103 +1990,38 @@
 
   uint32_t num_class_infos = 0;
 
-  const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+  const lldb::addr_t objc_opt_ptr = m_runtime.GetSharedCacheReadOnlyAddress();
+  const lldb::addr_t shared_cache_base_addr =
+      m_runtime.GetSharedCacheBaseAddress();
 
-  if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+  if (objc_opt_ptr == LLDB_INVALID_ADDRESS ||
+      shared_cache_base_addr == LLDB_INVALID_ADDRESS)
     return DescriptorMapUpdateResult::Fail();
 
   const uint32_t num_classes = 128 * 1024;
 
-  // Make some types for our arguments
-  CompilerType clang_uint32_t_type =
-      ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
-  CompilerType clang_void_pointer_type =
-      ast->GetBasicType(eBasicTypeVoid).GetPointerType();
+  UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx);
+  FunctionCaller *get_shared_cache_class_info_function =
+      get_class_info_code->GetFunctionCaller();
 
-  ValueList arguments;
-  FunctionCaller *get_shared_cache_class_info_function = nullptr;
-
-  if (!m_get_shared_cache_class_info_code) {
-    Status error;
-
-    // If the inferior objc.dylib has the class_getNameRaw function,
-    // use that in our jitted expression.  Else fall back to the old
-    // class_getName.
-    static ConstString g_class_getName_symbol_name("class_getName");
-    static ConstString g_class_getNameRaw_symbol_name("objc_debug_class_getNameRaw");
-    ConstString class_name_getter_function_name = g_class_getName_symbol_name;
-
-    ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process);
-    if (objc_runtime) {
-      for (lldb::ModuleSP mod_sp : process->GetTarget().GetImages().Modules()) {
-        if (objc_runtime->IsModuleObjCLibrary(mod_sp)) {
-          const Symbol *symbol =
-              mod_sp->FindFirstSymbolWithNameAndType(g_class_getNameRaw_symbol_name, 
-                                                lldb::eSymbolTypeCode);
-          if (symbol && 
-              (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
-            class_name_getter_function_name = g_class_getNameRaw_symbol_name;
-          }
-        }
-      }
-    }
-
-    // Substitute in the correct class_getName / class_getNameRaw function name,
-    // concatenate the two parts of our expression text.  The format string
-    // has two %s's, so provide the name twice.
-    std::string shared_class_expression;
-    llvm::raw_string_ostream(shared_class_expression) << llvm::format(
-                               g_shared_cache_class_name_funcptr,
-                               class_name_getter_function_name.AsCString(),
-                               class_name_getter_function_name.AsCString());
-
-    shared_class_expression += g_get_shared_cache_class_info_body;
-
-    auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction(
-        std::move(shared_class_expression), g_get_shared_cache_class_info_name,
-        eLanguageTypeC, exe_ctx);
-    if (!utility_fn_or_error) {
-      LLDB_LOG_ERROR(
-          log, utility_fn_or_error.takeError(),
-          "Failed to get utility function for implementation lookup: {0}");
-      return DescriptorMapUpdateResult::Fail();
-    }
-
-    m_get_shared_cache_class_info_code = std::move(*utility_fn_or_error);
-
-    // Next make the function caller for our implementation utility function.
-    Value value;
-    value.SetValueType(Value::eValueTypeScalar);
-    value.SetCompilerType(clang_void_pointer_type);
-    arguments.PushValue(value);
-    arguments.PushValue(value);
-
-    value.SetValueType(Value::eValueTypeScalar);
-    value.SetCompilerType(clang_uint32_t_type);
-    arguments.PushValue(value);
-    arguments.PushValue(value);
-
-    get_shared_cache_class_info_function =
-        m_get_shared_cache_class_info_code->MakeFunctionCaller(
-            clang_uint32_t_type, arguments, thread_sp, error);
-
-    if (get_shared_cache_class_info_function == nullptr)
-      return DescriptorMapUpdateResult::Fail();
-
-  } else {
-    get_shared_cache_class_info_function =
-        m_get_shared_cache_class_info_code->GetFunctionCaller();
-    if (get_shared_cache_class_info_function == nullptr)
-      return DescriptorMapUpdateResult::Fail();
-    arguments = get_shared_cache_class_info_function->GetArgumentValues();
+  if (!get_shared_cache_class_info_function) {
+    LLDB_LOGF(log, "Failed to get implementation lookup function caller.");
+    return DescriptorMapUpdateResult::Fail();
   }
 
+  ValueList arguments =
+      get_shared_cache_class_info_function->GetArgumentValues();
+
   DiagnosticManager diagnostics;
 
   const uint32_t class_info_byte_size = addr_size + 4;
   const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
   lldb::addr_t class_infos_addr = process->AllocateMemory(
       class_infos_byte_size, ePermissionsReadable | ePermissionsWritable, err);
+  const uint32_t relative_selector_offset_addr_size = 64;
+  lldb::addr_t relative_selector_offset_addr =
+      process->AllocateMemory(relative_selector_offset_addr_size,
+                              ePermissionsReadable | ePermissionsWritable, err);
 
   if (class_infos_addr == LLDB_INVALID_ADDRESS) {
     LLDB_LOGF(log,
@@ -1668,18 +2031,20 @@
     return DescriptorMapUpdateResult::Fail();
   }
 
-  std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+  std::lock_guard<std::mutex> guard(m_mutex);
 
   // Fill in our function argument values
   arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
-  arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
-  arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+  arguments.GetValueAtIndex(1)->GetScalar() = shared_cache_base_addr;
+  arguments.GetValueAtIndex(2)->GetScalar() = class_infos_addr;
+  arguments.GetValueAtIndex(3)->GetScalar() = relative_selector_offset_addr;
+  arguments.GetValueAtIndex(4)->GetScalar() = class_infos_byte_size;
   // Only dump the runtime classes from the expression evaluation if the log is
   // verbose:
   Log *type_log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES);
   bool dump_log = type_log && type_log->GetVerbose();
-  
-  arguments.GetValueAtIndex(3)->GetScalar() = dump_log ? 1 : 0;
+
+  arguments.GetValueAtIndex(5)->GetScalar() = dump_log ? 1 : 0;
 
   bool success = false;
 
@@ -1687,8 +2052,7 @@
 
   // Write our function arguments into the process so we can run our function
   if (get_shared_cache_class_info_function->WriteFunctionArguments(
-          exe_ctx, m_get_shared_cache_class_info_args, arguments,
-          diagnostics)) {
+          exe_ctx, m_args, arguments, diagnostics)) {
     EvaluateExpressionOptions options;
     options.SetUnwindOnError(true);
     options.SetTryAllThreads(false);
@@ -1697,8 +2061,11 @@
     options.SetTimeout(process->GetUtilityExpressionTimeout());
     options.SetIsForUtilityExpr(true);
 
+    CompilerType clang_uint32_t_type =
+        ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+
     Value return_value;
-    return_value.SetValueType(Value::eValueTypeScalar);
+    return_value.SetValueType(Value::ValueType::Scalar);
     return_value.SetCompilerType(clang_uint32_t_type);
     return_value.GetScalar() = 0;
 
@@ -1707,14 +2074,13 @@
     // Run the function
     ExpressionResults results =
         get_shared_cache_class_info_function->ExecuteFunction(
-            exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics,
-            return_value);
+            exe_ctx, &m_args, options, diagnostics, return_value);
 
     if (results == eExpressionCompleted) {
       // The result is the number of ClassInfo structures that were filled in
       num_class_infos = return_value.GetScalar().ULong();
-      LLDB_LOGF(log, "Discovered %u ObjC classes in shared cache\n",
-                num_class_infos);
+      LLDB_LOG(log, "Discovered {0} Objective-C classes in the shared cache",
+               num_class_infos);
       assert(num_class_infos <= num_classes);
       if (num_class_infos > 0) {
         if (num_class_infos > num_classes) {
@@ -1725,16 +2091,38 @@
           success = true;
         }
 
+        // Read the relative selector offset.
+        DataBufferHeap relative_selector_offset_buffer(64, 0);
+        if (process->ReadMemory(relative_selector_offset_addr,
+                                relative_selector_offset_buffer.GetBytes(),
+                                relative_selector_offset_buffer.GetByteSize(),
+                                err) ==
+            relative_selector_offset_buffer.GetByteSize()) {
+          DataExtractor relative_selector_offset_data(
+              relative_selector_offset_buffer.GetBytes(),
+              relative_selector_offset_buffer.GetByteSize(),
+              process->GetByteOrder(), addr_size);
+          lldb::offset_t offset = 0;
+          uint64_t relative_selector_offset =
+              relative_selector_offset_data.GetU64(&offset);
+          if (relative_selector_offset > 0) {
+            // The offset is relative to the objc_opt struct.
+            m_runtime.SetRelativeSelectorBaseAddr(objc_opt_ptr +
+                                                  relative_selector_offset);
+          }
+        }
+
         // Read the ClassInfo structures
-        DataBufferHeap buffer(num_class_infos * class_info_byte_size, 0);
-        if (process->ReadMemory(class_infos_addr, buffer.GetBytes(),
-                                buffer.GetByteSize(),
-                                err) == buffer.GetByteSize()) {
-          DataExtractor class_infos_data(buffer.GetBytes(),
-                                         buffer.GetByteSize(),
+        DataBufferHeap class_infos_buffer(
+            num_class_infos * class_info_byte_size, 0);
+        if (process->ReadMemory(class_infos_addr, class_infos_buffer.GetBytes(),
+                                class_infos_buffer.GetByteSize(),
+                                err) == class_infos_buffer.GetByteSize()) {
+          DataExtractor class_infos_data(class_infos_buffer.GetBytes(),
+                                         class_infos_buffer.GetByteSize(),
                                          process->GetByteOrder(), addr_size);
 
-          ParseClassInfoArray(class_infos_data, num_class_infos);
+          m_runtime.ParseClassInfoArray(class_infos_data, num_class_infos);
         }
       } else {
         success = true;
@@ -1758,42 +2146,6 @@
   return DescriptorMapUpdateResult(success, num_class_infos);
 }
 
-bool AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory(
-    RemoteNXMapTable &hash_table) {
-  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
-
-  Process *process = GetProcess();
-
-  if (process == nullptr)
-    return false;
-
-  uint32_t num_map_table_isas = 0;
-
-  ModuleSP objc_module_sp(GetObjCModule());
-
-  if (objc_module_sp) {
-    for (RemoteNXMapTable::element elt : hash_table) {
-      ++num_map_table_isas;
-
-      if (ISAIsCached(elt.second))
-        continue;
-
-      ClassDescriptorSP descriptor_sp = ClassDescriptorSP(
-          new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
-
-      if (log && log->GetVerbose())
-        LLDB_LOGF(log,
-                  "AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64
-                  " (%s) from dynamic table to isa->descriptor cache",
-                  elt.second, elt.first.AsCString());
-
-      AddClass(elt.second, descriptor_sp, elt.first.AsCString());
-    }
-  }
-
-  return num_map_table_isas > 0;
-}
-
 lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress() {
   Process *process = GetProcess();
 
@@ -1827,6 +2179,19 @@
   return LLDB_INVALID_ADDRESS;
 }
 
+lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() {
+  StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
+  if (!info)
+    return LLDB_INVALID_ADDRESS;
+
+  StructuredData::Dictionary *info_dict = info->GetAsDictionary();
+  if (!info_dict)
+    return LLDB_INVALID_ADDRESS;
+
+  return info_dict->GetValueForKey("shared_cache_base_address")
+      ->GetIntegerValue(LLDB_INVALID_ADDRESS);
+}
+
 void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
   LLDB_SCOPED_TIMER();
 
@@ -1842,14 +2207,19 @@
     // map, whether it was successful or not.
     m_isa_to_descriptor_stop_id = process->GetStopID();
 
-    if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+    // Ask the runtime is the realized class generation count changed. Unlike
+    // the hash table, this accounts for lazily named classes.
+    const bool class_count_changed = RealizedClassGenerationCountChanged();
+
+    if (!m_hash_signature.NeedsUpdate(process, this, hash_table) &&
+        !class_count_changed)
       return;
 
     m_hash_signature.UpdateSignature(hash_table);
 
-    // Grab the dynamically loaded objc classes from the hash table in memory
+    // Grab the dynamically loaded Objective-C classes from memory.
     DescriptorMapUpdateResult dynamic_update_result =
-        UpdateISAToDescriptorMapDynamic(hash_table);
+        m_dynamic_class_info_extractor.UpdateISAToDescriptorMap(hash_table);
 
     // Now get the objc classes that are baked into the Objective-C runtime in
     // the shared cache, but only once per process as this data never changes
@@ -1865,7 +2235,7 @@
       const uint32_t num_classes_to_warn_at = 500;
 
       DescriptorMapUpdateResult shared_cache_update_result =
-          UpdateISAToDescriptorMapSharedCache();
+          m_shared_cache_class_info_extractor.UpdateISAToDescriptorMap();
 
       LLDB_LOGF(log,
                 "attempted to read objc class data - results: "
@@ -1895,6 +2265,35 @@
   }
 }
 
+bool AppleObjCRuntimeV2::RealizedClassGenerationCountChanged() {
+  Process *process = GetProcess();
+  if (!process)
+    return false;
+
+  Status error;
+  uint64_t objc_debug_realized_class_generation_count =
+      ExtractRuntimeGlobalSymbol(
+          process, ConstString("objc_debug_realized_class_generation_count"),
+          GetObjCModule(), error);
+  if (error.Fail())
+    return false;
+
+  if (m_realized_class_generation_count ==
+      objc_debug_realized_class_generation_count)
+    return false;
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+  LLDB_LOG(log,
+           "objc_debug_realized_class_generation_count changed from {0} to {1}",
+           m_realized_class_generation_count,
+           objc_debug_realized_class_generation_count);
+
+  m_realized_class_generation_count =
+      objc_debug_realized_class_generation_count;
+
+  return true;
+}
+
 static bool DoesProcessHaveSharedCache(Process &process) {
   PlatformSP platform_sp = process.GetTarget().GetPlatform();
   if (!platform_sp)
@@ -1975,9 +2374,10 @@
           const ConstString ivar_name_cs(class_and_ivar.second);
           const char *ivar_name_cstr = ivar_name_cs.AsCString();
 
-          auto ivar_func = [&ret, ivar_name_cstr](
-              const char *name, const char *type, lldb::addr_t offset_addr,
-              uint64_t size) -> lldb::addr_t {
+          auto ivar_func = [&ret,
+                            ivar_name_cstr](const char *name, const char *type,
+                                            lldb::addr_t offset_addr,
+                                            uint64_t size) -> lldb::addr_t {
             if (!strcmp(name, ivar_name_cstr)) {
               ret = offset_addr;
               return true;
@@ -2279,7 +2679,6 @@
 AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(
     lldb::addr_t ptr) {
   ClassDescriptorSP actual_class_descriptor_sp;
-  uint64_t data_payload;
   uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
 
   if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2307,12 +2706,15 @@
     m_cache[slot] = actual_class_descriptor_sp;
   }
 
-  data_payload =
+  uint64_t data_payload =
       (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_payload_lshift) >>
        m_objc_debug_taggedpointer_payload_rshift);
-
-  return ClassDescriptorSP(
-      new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
+  int64_t data_payload_signed =
+      ((int64_t)((int64_t)unobfuscated
+                 << m_objc_debug_taggedpointer_payload_lshift) >>
+       m_objc_debug_taggedpointer_payload_rshift);
+  return ClassDescriptorSP(new ClassDescriptorV2Tagged(
+      actual_class_descriptor_sp, data_payload, data_payload_signed));
 }
 
 AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended(
@@ -2364,7 +2766,6 @@
 AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor(
     lldb::addr_t ptr) {
   ClassDescriptorSP actual_class_descriptor_sp;
-  uint64_t data_payload;
   uint64_t unobfuscated = (ptr) ^ m_runtime.GetTaggedPointerObfuscator();
 
   if (!IsPossibleTaggedPointer(unobfuscated))
@@ -2395,12 +2796,16 @@
     m_ext_cache[slot] = actual_class_descriptor_sp;
   }
 
-  data_payload =
-      (((uint64_t)unobfuscated << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+  uint64_t data_payload = (((uint64_t)unobfuscated
+                            << m_objc_debug_taggedpointer_ext_payload_lshift) >>
+                           m_objc_debug_taggedpointer_ext_payload_rshift);
+  int64_t data_payload_signed =
+      ((int64_t)((int64_t)unobfuscated
+                 << m_objc_debug_taggedpointer_ext_payload_lshift) >>
        m_objc_debug_taggedpointer_ext_payload_rshift);
 
-  return ClassDescriptorSP(
-      new ClassDescriptorV2Tagged(actual_class_descriptor_sp, data_payload));
+  return ClassDescriptorSP(new ClassDescriptorV2Tagged(
+      actual_class_descriptor_sp, data_payload, data_payload_signed));
 }
 
 AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(
@@ -2552,8 +2957,8 @@
 AppleObjCRuntimeV2::GetPointerISA(ObjCISA isa) {
   ObjCISA ret = isa;
 
-  if (m_non_pointer_isa_cache_up)
-    m_non_pointer_isa_cache_up->EvaluateNonPointerISA(isa, ret);
+  if (auto *non_pointer_isa_cache = GetNonPointerIsaCache())
+    non_pointer_isa_cache->EvaluateNonPointerISA(isa, ret);
 
   return ret;
 }
@@ -2598,13 +3003,14 @@
 #pragma mark Frame recognizers
 
 class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
- public:
+public:
   ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) {
     ThreadSP thread_sp = frame_sp->GetThread();
     ProcessSP process_sp = thread_sp->GetProcess();
 
     const lldb::ABISP &abi = process_sp->GetABI();
-    if (!abi) return;
+    if (!abi)
+      return;
 
     TypeSystemClang *clang_ast_context =
         ScratchTypeSystemClang::GetForTarget(process_sp->GetTarget());
@@ -2618,7 +3024,8 @@
     input_value.SetCompilerType(voidstar);
     args.PushValue(input_value);
 
-    if (!abi->GetArgumentValues(*thread_sp, args)) return;
+    if (!abi->GetArgumentValues(*thread_sp, args))
+      return;
 
     addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong();
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index c6fb6ea..d0caa29 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -26,7 +26,6 @@
 public:
   ~AppleObjCRuntimeV2() override = default;
 
-  // Static Functions
   static void Initialize();
 
   static void Terminate();
@@ -46,7 +45,6 @@
     return runtime->isA(&ID);
   }
 
-  // These are generic runtime functions:
   bool GetDynamicTypeAndAddress(ValueObject &in_value,
                                 lldb::DynamicValueType use_dynamic,
                                 TypeAndOrName &class_type_or_name,
@@ -56,7 +54,6 @@
   llvm::Expected<std::unique_ptr<UtilityFunction>>
   CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override;
 
-  // PluginInterface protocol
   ConstString GetPluginName() override;
 
   uint32_t GetPluginVersion() override;
@@ -88,6 +85,15 @@
 
   lldb::addr_t GetTaggedPointerObfuscator();
 
+  /// Returns the base address for relative method list selector strings.
+  lldb::addr_t GetRelativeSelectorBaseAddr() {
+    return m_relative_selector_base;
+  }
+
+  void SetRelativeSelectorBaseAddr(lldb::addr_t relative_selector_base) {
+    m_relative_selector_base = relative_selector_base;
+  }
+
   void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
                                     lldb::addr_t &cf_false) override;
 
@@ -105,8 +111,8 @@
 
 protected:
   lldb::BreakpointResolverSP
-  CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
-                          bool catch_bp, bool throw_bp) override;
+  CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp,
+                          bool throw_bp) override;
 
 private:
   class HashTableSignature {
@@ -119,9 +125,9 @@
     void UpdateSignature(const RemoteNXMapTable &hash_table);
 
   protected:
-    uint32_t m_count;
-    uint32_t m_num_buckets;
-    lldb::addr_t m_buckets_ptr;
+    uint32_t m_count = 0;
+    uint32_t m_num_buckets = 0;
+    lldb::addr_t m_buckets_ptr = 0;
   };
 
   class NonPointerISACache {
@@ -296,22 +302,99 @@
     }
   };
 
+  /// Abstraction to read the Objective-C class info.
+  class ClassInfoExtractor {
+  public:
+    ClassInfoExtractor(AppleObjCRuntimeV2 &runtime) : m_runtime(runtime) {}
+    std::mutex &GetMutex() { return m_mutex; }
+
+  protected:
+    /// The lifetime of this object is tied to that of the runtime.
+    AppleObjCRuntimeV2 &m_runtime;
+    std::mutex m_mutex;
+  };
+
+  /// We can read the class info from the Objective-C runtime using
+  /// gdb_objc_realized_classes or objc_copyRealizedClassList. The latter is
+  /// preferred because it includes lazily named classes, but it's not always
+  /// available or safe to call.
+  ///
+  /// We potentially need both for the same process, because we may need to use
+  /// gdb_objc_realized_classes until dyld is initialized and then switch over
+  /// to objc_copyRealizedClassList for lazily named classes.
+  class DynamicClassInfoExtractor : public ClassInfoExtractor {
+  public:
+    DynamicClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
+        : ClassInfoExtractor(runtime) {}
+
+    DescriptorMapUpdateResult
+    UpdateISAToDescriptorMap(RemoteNXMapTable &hash_table);
+
+  private:
+    enum Helper { gdb_objc_realized_classes, objc_copyRealizedClassList };
+
+    /// Compute which helper to use. Prefer objc_copyRealizedClassList if it's
+    /// available and it's safe to call (i.e. dyld is fully initialized). Use
+    /// gdb_objc_realized_classes otherwise.
+    Helper ComputeHelper() const;
+
+    UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx,
+                                                 Helper helper);
+    lldb::addr_t &GetClassInfoArgs(Helper helper);
+
+    std::unique_ptr<UtilityFunction>
+    GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx, std::string code,
+                                    std::string name);
+
+    /// Helper to read class info using the gdb_objc_realized_classes.
+    struct gdb_objc_realized_classes_helper {
+      std::unique_ptr<UtilityFunction> utility_function;
+      lldb::addr_t args = LLDB_INVALID_ADDRESS;
+    };
+
+    /// Helper to read class info using objc_copyRealizedClassList.
+    struct objc_copyRealizedClassList_helper {
+      std::unique_ptr<UtilityFunction> utility_function;
+      lldb::addr_t args = LLDB_INVALID_ADDRESS;
+    };
+
+    gdb_objc_realized_classes_helper m_gdb_objc_realized_classes_helper;
+    objc_copyRealizedClassList_helper m_objc_copyRealizedClassList_helper;
+  };
+
+  /// Abstraction to read the Objective-C class info from the shared cache.
+  class SharedCacheClassInfoExtractor : public ClassInfoExtractor {
+  public:
+    SharedCacheClassInfoExtractor(AppleObjCRuntimeV2 &runtime)
+        : ClassInfoExtractor(runtime) {}
+
+    DescriptorMapUpdateResult UpdateISAToDescriptorMap();
+
+  private:
+    UtilityFunction *GetClassInfoUtilityFunction(ExecutionContext &exe_ctx);
+
+    std::unique_ptr<UtilityFunction>
+    GetClassInfoUtilityFunctionImpl(ExecutionContext &exe_ctx);
+
+    std::unique_ptr<UtilityFunction> m_utility_function;
+    lldb::addr_t m_args = LLDB_INVALID_ADDRESS;
+  };
+
   AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp);
 
   ObjCISA GetPointerISA(ObjCISA isa);
 
   lldb::addr_t GetISAHashTablePointer();
 
-  bool UpdateISAToDescriptorMapFromMemory(RemoteNXMapTable &hash_table);
-
-  DescriptorMapUpdateResult
-  UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
+  /// Update the generation count of realized classes. This is not an exact
+  /// count but rather a value that is incremented when new classes are realized
+  /// or destroyed. Unlike the count in gdb_objc_realized_classes, it will
+  /// change when lazily named classes get realized.
+  bool RealizedClassGenerationCountChanged();
 
   uint32_t ParseClassInfoArray(const lldb_private::DataExtractor &data,
                                uint32_t num_class_infos);
 
-  DescriptorMapUpdateResult UpdateISAToDescriptorMapSharedCache();
-
   enum class SharedCacheWarningReason {
     eExpressionExecutionFailure,
     eNotEnoughClassesRead
@@ -320,30 +403,40 @@
   void WarnIfNoClassesCached(SharedCacheWarningReason reason);
 
   lldb::addr_t GetSharedCacheReadOnlyAddress();
+  lldb::addr_t GetSharedCacheBaseAddress();
 
   bool GetCFBooleanValuesIfNeeded();
 
+  bool HasSymbol(ConstString Name);
+
+  NonPointerISACache *GetNonPointerIsaCache() {
+    if (!m_non_pointer_isa_cache_up)
+      m_non_pointer_isa_cache_up.reset(
+          NonPointerISACache::CreateInstance(*this, m_objc_module_sp));
+    return m_non_pointer_isa_cache_up.get();
+  }
+
   friend class ClassDescriptorV2;
 
-  std::unique_ptr<UtilityFunction> m_get_class_info_code;
-  lldb::addr_t m_get_class_info_args;
-  std::mutex m_get_class_info_args_mutex;
+  lldb::ModuleSP m_objc_module_sp;
 
-  std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
-  lldb::addr_t m_get_shared_cache_class_info_args;
-  std::mutex m_get_shared_cache_class_info_args_mutex;
+  DynamicClassInfoExtractor m_dynamic_class_info_extractor;
+  SharedCacheClassInfoExtractor m_shared_cache_class_info_extractor;
 
   std::unique_ptr<DeclVendor> m_decl_vendor_up;
   lldb::addr_t m_tagged_pointer_obfuscator;
   lldb::addr_t m_isa_hash_table_ptr;
+  lldb::addr_t m_relative_selector_base;
   HashTableSignature m_hash_signature;
   bool m_has_object_getClass;
+  bool m_has_objc_copyRealizedClassList;
   bool m_loaded_objc_opt;
   std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_up;
   std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_up;
   EncodingToTypeSP m_encoding_to_type_sp;
   bool m_noclasses_warning_emitted;
   llvm::Optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values;
+  uint64_t m_realized_class_generation_count;
 };
 
 } // namespace lldb_private
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index bcc1f6f..aa6306b 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -285,7 +285,7 @@
   SetUpRegion();
 }
 
-AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() {}
+AppleObjCTrampolineHandler::~AppleObjCTrampolineHandler() = default;
 
 void AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::SetUpRegion() {
   // The header looks like:
@@ -526,7 +526,7 @@
     CompilerType clang_void_ptr_type =
         clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
 
-    input_value.SetValueType(Value::eValueTypeScalar);
+    input_value.SetValueType(Value::ValueType::Scalar);
     // input_value.SetContext (Value::eContextTypeClangType,
     // clang_void_ptr_type);
     input_value.SetCompilerType(clang_void_ptr_type);
@@ -936,7 +936,7 @@
     Value void_ptr_value;
     CompilerType clang_void_ptr_type =
         clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-    void_ptr_value.SetValueType(Value::eValueTypeScalar);
+    void_ptr_value.SetValueType(Value::ValueType::Scalar);
     // void_ptr_value.SetContext (Value::eContextTypeClangType,
     // clang_void_ptr_type);
     void_ptr_value.SetCompilerType(clang_void_ptr_type);
@@ -1048,7 +1048,7 @@
 
       Value isa_value(*(argument_values.GetValueAtIndex(obj_index)));
 
-      isa_value.SetValueType(Value::eValueTypeLoadAddress);
+      isa_value.SetValueType(Value::ValueType::LoadAddress);
       isa_value.ResolveValue(&exe_ctx);
       if (isa_value.GetScalar().IsValid()) {
         isa_addr = isa_value.GetScalar().ULongLong();
@@ -1110,7 +1110,7 @@
       CompilerType clang_int_type =
           clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
               lldb::eEncodingSint, 32);
-      flag_value.SetValueType(Value::eValueTypeScalar);
+      flag_value.SetValueType(Value::ValueType::Scalar);
       // flag_value.SetContext (Value::eContextTypeClangType, clang_int_type);
       flag_value.SetCompilerType(clang_int_type);
 
@@ -1157,13 +1157,8 @@
         flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
       dispatch_values.PushValue(flag_value);
 
-      // The step through code might have to fill in the cache, so it
-      // is not safe to run only one thread.  So we override the
-      // stop_others value passed in to us here:
-      const bool trampoline_stop_others = false;
       ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughObjCTrampoline>(
-          thread, *this, dispatch_values, isa_addr, sel_addr,
-          trampoline_stop_others);
+          thread, *this, dispatch_values, isa_addr, sel_addr);
       if (log) {
         StreamString s;
         ret_plan_sp->GetDescription(&s, eDescriptionLevelFull);
@@ -1182,13 +1177,9 @@
     MsgsendMap::iterator pos;
     pos = m_opt_dispatch_map.find(curr_pc);
     if (pos != m_opt_dispatch_map.end()) {
-
       const char *opt_name = g_opt_dispatch_names[(*pos).second];
-
-      bool trampoline_stop_others = false;
-      LazyBool step_in_should_stop = eLazyBoolCalculate;
-      ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch> (
-          thread, *this, opt_name, trampoline_stop_others, step_in_should_stop);
+      ret_plan_sp = std::make_shared<AppleThreadPlanStepThroughDirectDispatch>(
+          thread, *this, opt_name);
     }
   }
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index 27aebd8..546b500 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -76,10 +76,7 @@
 
     class VTableRegion {
     public:
-      VTableRegion()
-          : m_valid(false), m_owner(nullptr),
-            m_header_addr(LLDB_INVALID_ADDRESS), m_code_start_addr(0),
-            m_code_end_addr(0), m_next_region(0) {}
+      VTableRegion() = default;
 
       VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr);
 
@@ -99,13 +96,13 @@
 
       void Dump(Stream &s);
 
-      bool m_valid;
-      AppleObjCVTables *m_owner;
-      lldb::addr_t m_header_addr;
-      lldb::addr_t m_code_start_addr;
-      lldb::addr_t m_code_end_addr;
+      bool m_valid = false;
+      AppleObjCVTables *m_owner = nullptr;
+      lldb::addr_t m_header_addr = LLDB_INVALID_ADDRESS;
+      lldb::addr_t m_code_start_addr = 0;
+      lldb::addr_t m_code_end_addr = 0;
       std::vector<VTableDescriptor> m_descriptors;
-      lldb::addr_t m_next_region;
+      lldb::addr_t m_next_region = 0;
     };
 
   public:
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index b19d3d9..7b01215 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -59,7 +59,7 @@
 // "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
 
 AppleObjCTypeEncodingParser::StructElement::StructElement()
-    : name(""), type(clang::QualType()), bitfield(0) {}
+    : name(""), type(clang::QualType()) {}
 
 AppleObjCTypeEncodingParser::StructElement
 AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index 9a10896..6e533b5 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -29,7 +29,7 @@
   struct StructElement {
     std::string name;
     clang::QualType type;
-    uint32_t bitfield;
+    uint32_t bitfield = 0;
 
     StructElement();
     ~StructElement() = default;
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 653e007..1dc8034 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -30,19 +30,17 @@
 AppleThreadPlanStepThroughObjCTrampoline::
     AppleThreadPlanStepThroughObjCTrampoline(
         Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
-        ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
-        bool stop_others)
+        ValueList &input_values, lldb::addr_t isa_addr, lldb::addr_t sel_addr)
     : ThreadPlan(ThreadPlan::eKindGeneric,
                  "MacOSX Step through ObjC Trampoline", thread, eVoteNoOpinion,
                  eVoteNoOpinion),
       m_trampoline_handler(trampoline_handler),
       m_args_addr(LLDB_INVALID_ADDRESS), m_input_values(input_values),
-      m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr),
-      m_stop_others(stop_others) {}
+      m_isa_addr(isa_addr), m_sel_addr(sel_addr), m_impl_function(nullptr) {}
 
 // Destructor
 AppleThreadPlanStepThroughObjCTrampoline::
-    ~AppleThreadPlanStepThroughObjCTrampoline() {}
+    ~AppleThreadPlanStepThroughObjCTrampoline() = default;
 
 void AppleThreadPlanStepThroughObjCTrampoline::DidPush() {
   // Setting up the memory space for the called function text might require
@@ -66,7 +64,7 @@
     EvaluateExpressionOptions options;
     options.SetUnwindOnError(true);
     options.SetIgnoreBreakpoints(true);
-    options.SetStopOthers(m_stop_others);
+    options.SetStopOthers(false);
     GetThread().CalculateExecutionContext(exc_ctx);
     m_func_sp = m_impl_function->GetThreadPlanToCallFunction(
         exc_ctx, m_args_addr, options, diagnostics);
@@ -157,7 +155,7 @@
       const bool first_insn = true;
       const uint32_t frame_idx = 0;
       m_run_to_sp = GetThread().QueueThreadPlanForStepOutNoShouldStop(
-          abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion,
+          abort_other_plans, &sc, first_insn, false, eVoteNoOpinion,
           eVoteNoOpinion, frame_idx, status);
       if (m_run_to_sp && status.Success())
         m_run_to_sp->SetPrivate(true);
@@ -179,7 +177,7 @@
     // Extract the target address from the value:
 
     m_run_to_sp = std::make_shared<ThreadPlanRunToAddress>(
-        GetThread(), target_so_addr, m_stop_others);
+        GetThread(), target_so_addr, false);
     PushPlan(m_run_to_sp);
     return false;
   } else if (GetThread().IsThreadPlanDone(m_run_to_sp.get())) {
@@ -222,10 +220,9 @@
 AppleThreadPlanStepThroughDirectDispatch ::
     AppleThreadPlanStepThroughDirectDispatch(
         Thread &thread, AppleObjCTrampolineHandler &handler,
-        llvm::StringRef dispatch_func_name, bool stop_others,
-        LazyBool step_in_avoids_code_without_debug_info)
-    : ThreadPlanStepOut(thread, nullptr, true /* first instruction */,
-                        stop_others, eVoteNoOpinion, eVoteNoOpinion,
+        llvm::StringRef dispatch_func_name)
+    : ThreadPlanStepOut(thread, nullptr, true /* first instruction */, false,
+                        eVoteNoOpinion, eVoteNoOpinion,
                         0 /* Step out of zeroth frame */,
                         eLazyBoolNo /* Our parent plan will decide this
                                when we are done */
@@ -234,7 +231,7 @@
                         false /* Don't gather the return value */),
       m_trampoline_handler(handler),
       m_dispatch_func_name(std::string(dispatch_func_name)),
-      m_at_msg_send(false), m_stop_others(stop_others) {
+      m_at_msg_send(false) {
   // Set breakpoints on the dispatch functions:
   auto bkpt_callback = [&] (lldb::addr_t addr, 
                             const AppleObjCTrampolineHandler
@@ -249,20 +246,7 @@
   // We'll set the step-out plan in the DidPush so it gets queued in the right
   // order.
 
-  bool avoid_nodebug = true;
-
-  switch (step_in_avoids_code_without_debug_info) {
-  case eLazyBoolYes:
-    avoid_nodebug = true;
-    break;
-  case eLazyBoolNo:
-    avoid_nodebug = false;
-    break;
-  case eLazyBoolCalculate:
-    avoid_nodebug = GetThread().GetStepInAvoidsNoDebug();
-    break;
-  }
-  if (avoid_nodebug)
+  if (GetThread().GetStepInAvoidsNoDebug())
     GetFlags().Set(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
   else
     GetFlags().Clear(ThreadPlanShouldStopHere::eStepInAvoidNoDebug);
@@ -398,8 +382,8 @@
     // There's no way we could have gotten here without an ObjC language 
     // runtime.
     assert(objc_runtime);
-    m_objc_step_through_sp 
-      = objc_runtime->GetStepThroughTrampolinePlan(GetThread(), m_stop_others);
+    m_objc_step_through_sp =
+        objc_runtime->GetStepThroughTrampolinePlan(GetThread(), false);
     // If we failed to find the target for this dispatch, just keep going and
     // let the step out complete.
     if (!m_objc_step_through_sp) {
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 89aed89..b5b4507 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -24,8 +24,7 @@
 public:
   AppleThreadPlanStepThroughObjCTrampoline(
       Thread &thread, AppleObjCTrampolineHandler &trampoline_handler,
-      ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr,
-      bool stop_others);
+      ValueList &values, lldb::addr_t isa_addr, lldb::addr_t sel_addr);
 
   ~AppleThreadPlanStepThroughObjCTrampoline() override;
 
@@ -39,7 +38,9 @@
 
   bool ShouldStop(Event *event_ptr) override;
 
-  bool StopOthers() override { return m_stop_others; }
+  // The step through code might have to fill in the cache, so it is not safe
+  // to run only one thread.
+  bool StopOthers() override { return false; }
 
   // The base class MischiefManaged does some cleanup - so you have to call it
   // in your MischiefManaged derived class.
@@ -69,15 +70,13 @@
   FunctionCaller *m_impl_function; /// This is a pointer to a impl function that
                                    /// is owned by the client that pushes this
                                    /// plan.
-  bool m_stop_others;  /// Whether we should stop other threads.
 };
 
 class AppleThreadPlanStepThroughDirectDispatch: public ThreadPlanStepOut {
 public:
-  AppleThreadPlanStepThroughDirectDispatch(
-      Thread &thread, AppleObjCTrampolineHandler &handler,
-      llvm::StringRef dispatch_func_name, bool stop_others,
-      LazyBool step_in_avoids_code_without_debug_info);
+  AppleThreadPlanStepThroughDirectDispatch(Thread &thread,
+                                           AppleObjCTrampolineHandler &handler,
+                                           llvm::StringRef dispatch_func_name);
 
   ~AppleThreadPlanStepThroughDirectDispatch() override;
 
@@ -85,7 +84,7 @@
 
   bool ShouldStop(Event *event_ptr) override;
 
-  bool StopOthers() override { return m_stop_others; }
+  bool StopOthers() override { return false; }
 
   bool MischiefManaged() override;
 
@@ -107,7 +106,6 @@
   std::vector<lldb::BreakpointSP> m_msgSend_bkpts; /// Breakpoints on the objc
                                                    /// dispatch functions.
   bool m_at_msg_send;  /// Are we currently handling an msg_send
-  bool m_stop_others;  /// Whether we should stop other threads.
 
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 2ccf9b3..65bf3e6 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -32,7 +32,7 @@
 char ObjCLanguageRuntime::ID = 0;
 
 // Destructor
-ObjCLanguageRuntime::~ObjCLanguageRuntime() {}
+ObjCLanguageRuntime::~ObjCLanguageRuntime() = default;
 
 ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process)
     : LanguageRuntime(process), m_impl_cache(),
@@ -305,7 +305,7 @@
   return CompilerType();
 }
 
-ObjCLanguageRuntime::EncodingToType::~EncodingToType() {}
+ObjCLanguageRuntime::EncodingToType::~EncodingToType() = default;
 
 ObjCLanguageRuntime::EncodingToTypeSP ObjCLanguageRuntime::GetEncodingToType() {
   return nullptr;
@@ -363,7 +363,8 @@
   m_class_names.insert(class_name);
 }
 
-ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() {}
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition() =
+    default;
 
 bool ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition(
     StoppointCallbackContext &context) {
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 683eff7..15fce04 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -49,9 +49,7 @@
   // implementations of the runtime, and more might come
   class ClassDescriptor {
   public:
-    ClassDescriptor()
-        : m_is_kvo(eLazyBoolCalculate), m_is_cf(eLazyBoolCalculate),
-          m_type_wp() {}
+    ClassDescriptor() : m_type_wp() {}
 
     virtual ~ClassDescriptor() = default;
 
@@ -87,10 +85,20 @@
 
     virtual bool IsValid() = 0;
 
+    /// There are two routines in the ObjC runtime that tagged pointer clients
+    /// can call to get the value from their tagged pointer, one that retrieves
+    /// it as an unsigned value and one a signed value.  These two
+    /// GetTaggedPointerInfo methods mirror those two ObjC runtime calls.
+    /// @{
     virtual bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
                                       uint64_t *value_bits = nullptr,
                                       uint64_t *payload = nullptr) = 0;
 
+    virtual bool GetTaggedPointerInfoSigned(uint64_t *info_bits = nullptr,
+                                            int64_t *value_bits = nullptr,
+                                            uint64_t *payload = nullptr) = 0;
+    /// @}
+ 
     virtual uint64_t GetInstanceSize() = 0;
 
     // use to implement version-specific additional constraints on pointers
@@ -135,8 +143,8 @@
                         bool check_version_specific = false) const;
 
   private:
-    LazyBool m_is_kvo;
-    LazyBool m_is_cf;
+    LazyBool m_is_kvo = eLazyBoolCalculate;
+    LazyBool m_is_cf = eLazyBoolCalculate;
     lldb::TypeWP m_type_wp;
   };
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index 6858c71..08a752e 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -185,7 +185,7 @@
   EarlyPasses->add(new RenderScriptRuntimeModulePass(process));
 }
 
-RSIRPasses::~RSIRPasses() {}
+RSIRPasses::~RSIRPasses() = default;
 
 } // namespace lldb_renderscript
 } // namespace lldb_private
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index dd93122..10ff5aa 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -61,7 +61,7 @@
 template <typename type_t> class empirical_type {
 public:
   // Ctor. Contents is invalid when constructed.
-  empirical_type() : valid(false) {}
+  empirical_type() = default;
 
   // Return true and copy contents to out if valid, else return false.
   bool get(type_t &out) const {
@@ -99,7 +99,7 @@
   }
 
 protected:
-  bool valid;
+  bool valid = false;
   type_t data;
 };
 
@@ -2228,7 +2228,7 @@
   return JITAllocationSize(alloc, frame_ptr);
 }
 
-// Function attempts to set the type_name member of the paramaterised Element
+// Function attempts to set the type_name member of the parameterised Element
 // object. This string should be the name of the struct type the Element
 // represents. We need this string for pretty printing the Element to users.
 void RenderScriptRuntime::FindStructTypeName(Element &elem,
@@ -4087,9 +4087,7 @@
 
   class CommandOptions : public Options {
   public:
-    CommandOptions()
-        : Options(),
-          m_kernel_types(RSReduceBreakpointResolver::eKernelTypeAll) {}
+    CommandOptions() : Options() {}
 
     ~CommandOptions() override = default;
 
@@ -4175,7 +4173,7 @@
       return true;
     }
 
-    int m_kernel_types;
+    int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll;
     llvm::StringRef m_reduce_name;
     RSCoordinate m_coord;
     bool m_have_coord;
@@ -4189,7 +4187,6 @@
       result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, "
                                    "and an optional kernel type list",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4203,7 +4200,6 @@
     auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
     if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord,
                                              m_options.m_kernel_types)) {
-      result.SetStatus(eReturnStatusFailed);
       result.AppendError("Error: unable to place breakpoint on reduction");
       return false;
     }
@@ -4291,7 +4287,6 @@
       result.AppendErrorWithFormat(
           "'%s' takes 1 argument of kernel name, and an optional coordinate.",
           m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4304,7 +4299,6 @@
     auto name = command.GetArgumentAtIndex(0);
     auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
     if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) {
-      result.SetStatus(eReturnStatusFailed);
       result.AppendErrorWithFormat(
           "Error: unable to set breakpoint on kernel '%s'", name);
       return false;
@@ -4342,7 +4336,6 @@
     if (argc != 1) {
       result.AppendErrorWithFormat(
           "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4361,7 +4354,6 @@
     } else {
       result.AppendErrorWithFormat(
           "Argument must be either 'enable' or 'disable'");
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4568,7 +4560,6 @@
       result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. "
                                    "As well as an optional -f argument",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4583,7 +4574,6 @@
     if (!success) {
       result.AppendErrorWithFormat("invalid allocation id argument '%s'",
                                    id_cstr);
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4608,7 +4598,6 @@
         std::string error = llvm::toString(file.takeError());
         result.AppendErrorWithFormat("Couldn't open file '%s': %s",
                                      path.c_str(), error.c_str());
-        result.SetStatus(eReturnStatusFailed);
         return false;
       }
     } else
@@ -4653,7 +4642,7 @@
 
   class CommandOptions : public Options {
   public:
-    CommandOptions() : Options(), m_id(0) {}
+    CommandOptions() : Options() {}
 
     ~CommandOptions() override = default;
 
@@ -4681,7 +4670,7 @@
       return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options);
     }
 
-    uint32_t m_id;
+    uint32_t m_id = 0;
   };
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -4717,7 +4706,6 @@
       result.AppendErrorWithFormat(
           "'%s' takes 2 arguments, an allocation ID and filename to read from.",
           m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4732,7 +4720,6 @@
     if (!success) {
       result.AppendErrorWithFormat("invalid allocation id argument '%s'",
                                    id_cstr);
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4768,7 +4755,6 @@
       result.AppendErrorWithFormat(
           "'%s' takes 2 arguments, an allocation ID and filename to read from.",
           m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -4783,7 +4769,6 @@
     if (!success) {
       result.AppendErrorWithFormat("invalid allocation id argument '%s'",
                                    id_cstr);
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
diff --git a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 5e37265..2785c3b 100644
--- a/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/src/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -44,9 +44,9 @@
 typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;
 
 struct RSCoordinate {
-  uint32_t x, y, z;
+  uint32_t x = 0, y = 0, z = 0;
 
-  RSCoordinate() : x(), y(), z(){};
+  RSCoordinate() = default;
 
   bool operator==(const lldb_renderscript::RSCoordinate &rhs) {
     return x == rhs.x && y == rhs.y && z == rhs.z;
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 211eb9c..7ff9175 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -42,9 +42,7 @@
 
 LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive)
 
-ObjectContainerBSDArchive::Object::Object()
-    : ar_name(), modification_time(0), uid(0), gid(0), mode(0), size(0),
-      file_offset(0), file_size(0) {}
+ObjectContainerBSDArchive::Object::Object() : ar_name() {}
 
 void ObjectContainerBSDArchive::Object::Clear() {
   ar_name.Clear();
@@ -142,7 +140,7 @@
     : m_arch(arch), m_modification_time(time), m_file_offset(file_offset),
       m_objects(), m_data(data) {}
 
-ObjectContainerBSDArchive::Archive::~Archive() {}
+ObjectContainerBSDArchive::Archive::~Archive() = default;
 
 size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
   DataExtractor &data = m_data;
@@ -375,7 +373,7 @@
   m_archive_sp = archive_sp;
 }
 
-ObjectContainerBSDArchive::~ObjectContainerBSDArchive() {}
+ObjectContainerBSDArchive::~ObjectContainerBSDArchive() = default;
 
 bool ObjectContainerBSDArchive::ParseHeader() {
   if (m_archive_sp.get() == nullptr) {
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index f6862af..9830e9b 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/src/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -84,25 +84,25 @@
     lldb_private::ConstString ar_name;
 
     /// Object modification time in the archive.
-    uint32_t modification_time;
+    uint32_t modification_time = 0;
 
     /// Object user id in the archive.
-    uint16_t uid;
+    uint16_t uid = 0;
 
     /// Object group id in the archive.
-    uint16_t gid;
+    uint16_t gid = 0;
 
     /// Object octal file permissions in the archive.
-    uint16_t mode;
+    uint16_t mode = 0;
 
     /// Object size in bytes in the archive.
-    uint32_t size;
+    uint32_t size = 0;
 
     /// File offset in bytes from the beginning of the file of the object data.
-    lldb::offset_t file_offset;
+    lldb::offset_t file_offset = 0;
 
     /// Length of the object data.
-    lldb::offset_t file_size;
+    lldb::offset_t file_size = 0;
   };
 
   class Archive {
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/src/llvm-project/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
index bb56379..d0a493d 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
@@ -79,7 +79,7 @@
   memset(&m_header, 0, sizeof(m_header));
 }
 
-ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() {}
+ObjectContainerUniversalMachO::~ObjectContainerUniversalMachO() = default;
 
 bool ObjectContainerUniversalMachO::ParseHeader() {
   bool success = ParseHeader(m_data, m_header, m_fat_archs);
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index cad9ce2..a5e86f0 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/LZMA.h"
@@ -37,6 +38,7 @@
 #include "llvm/Object/Decompressor.h"
 #include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/CRC.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/MipsABIFlags.h"
@@ -857,8 +859,7 @@
       if (symbol.d_tag == DT_MIPS_RLD_MAP) {
         // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
         Address addr;
-        if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
-                                          addr))
+        if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true))
           return addr;
       }
       if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
@@ -866,7 +867,7 @@
         // relative to the address of the tag.
         uint64_t rel_offset;
         rel_offset = target->ReadUnsignedIntegerFromMemory(
-            dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
+            dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true);
         if (error.Success() && rel_offset != UINT64_MAX) {
           Address addr;
           addr_t debug_ptr_address =
@@ -1861,7 +1862,7 @@
   // unified section list.
   if (GetType() != eTypeDebugInfo)
     unified_section_list = *m_sections_up;
-  
+
   // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
   // embedded in there and replace the one in the original object file (if any).
   // If there's none in the orignal object file, we add it to it.
@@ -1879,7 +1880,7 @@
           unified_section_list.AddSection(symtab_section_sp);
       }
     }
-  }  
+  }
 }
 
 std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
@@ -1923,7 +1924,7 @@
   ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
   if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
     return m_gnu_debug_data_object_file;
-  
+
   return nullptr;
 }
 
@@ -2707,6 +2708,9 @@
   if (!module_sp)
     return nullptr;
 
+  Progress progress(llvm::formatv("Parsing symbol table for {0}",
+                                  m_file.GetFilename().AsCString("<Unknown>")));
+
   // We always want to use the main object file so we (hopefully) only have one
   // cached copy of our symtab, dynamic sections, etc.
   ObjectFile *module_obj_file = module_sp->GetObjectFile();
@@ -2770,14 +2774,14 @@
         user_id_t reloc_id = reloc_section->GetID();
         const ELFSectionHeaderInfo *reloc_header =
             GetSectionHeaderByIndex(reloc_id);
-        assert(reloc_header);
+        if (reloc_header) {
+          if (m_symtab_up == nullptr)
+            m_symtab_up =
+                std::make_unique<Symtab>(reloc_section->GetObjectFile());
 
-        if (m_symtab_up == nullptr)
-          m_symtab_up =
-              std::make_unique<Symtab>(reloc_section->GetObjectFile());
-
-        ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
-                               reloc_id);
+          ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
+                                 reloc_id);
+        }
       }
     }
 
@@ -2809,31 +2813,37 @@
       if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
                                       entry_point_file_addr)) {
         uint64_t symbol_id = m_symtab_up->GetNumSymbols();
-        Symbol symbol(symbol_id,
-                      GetNextSyntheticSymbolName().GetCString(), // Symbol name.
-                      eSymbolTypeCode, // Type of this symbol.
-                      true,            // Is this globally visible?
-                      false,           // Is this symbol debug info?
-                      false,           // Is this symbol a trampoline?
-                      true,            // Is this symbol artificial?
-                      entry_point_addr.GetSection(), // Section where this
-                                                     // symbol is defined.
-                      0,     // Offset in section or symbol value.
-                      0,     // Size.
-                      false, // Size is valid.
-                      false, // Contains linker annotations?
-                      0);    // Symbol flags.
-        m_symtab_up->AddSymbol(symbol);
+        // Don't set the name for any synthetic symbols, the Symbol
+        // object will generate one if needed when the name is accessed
+        // via accessors.
+        SectionSP section_sp = entry_point_addr.GetSection();
+        Symbol symbol(
+            /*symID=*/symbol_id,
+            /*name=*/llvm::StringRef(), // Name will be auto generated.
+            /*type=*/eSymbolTypeCode,
+            /*external=*/true,
+            /*is_debug=*/false,
+            /*is_trampoline=*/false,
+            /*is_artificial=*/true,
+            /*section_sp=*/section_sp,
+            /*offset=*/0,
+            /*size=*/0, // FDE can span multiple symbols so don't use its size.
+            /*size_is_valid=*/false,
+            /*contains_linker_annotations=*/false,
+            /*flags=*/0);
         // When the entry point is arm thumb we need to explicitly set its
         // class address to reflect that. This is important because expression
         // evaluation relies on correctly setting a breakpoint at this
         // address.
         if (arch.GetMachine() == llvm::Triple::arm &&
-            (entry_point_file_addr & 1))
+            (entry_point_file_addr & 1)) {
+          symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
           m_address_class_map[entry_point_file_addr ^ 1] =
               AddressClass::eCodeAlternateISA;
-        else
+        } else {
           m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
+        }
+        m_symtab_up->AddSymbol(symbol);
       }
     }
 
@@ -2897,8 +2907,11 @@
   // recalculate the index first.
   std::vector<Symbol> new_symbols;
 
-  eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
-      lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
+  size_t num_symbols = symbol_table->GetNumSymbols();
+  uint64_t last_symbol_id =
+      num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0;
+  eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size,
+                                  dw_offset_t) {
     Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
     if (symbol) {
       if (!symbol->GetByteSizeIsValid()) {
@@ -2910,22 +2923,24 @@
           section_list->FindSectionContainingFileAddress(file_addr);
       if (section_sp) {
         addr_t offset = file_addr - section_sp->GetFileAddress();
-        const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
-        uint64_t symbol_id = symbol_table->GetNumSymbols();
+        uint64_t symbol_id = ++last_symbol_id;
+        // Don't set the name for any synthetic symbols, the Symbol
+        // object will generate one if needed when the name is accessed
+        // via accessors.
         Symbol eh_symbol(
-            symbol_id,       // Symbol table index.
-            symbol_name,     // Symbol name.
-            eSymbolTypeCode, // Type of this symbol.
-            true,            // Is this globally visible?
-            false,           // Is this symbol debug info?
-            false,           // Is this symbol a trampoline?
-            true,            // Is this symbol artificial?
-            section_sp,      // Section in which this symbol is defined or null.
-            offset,          // Offset in section or symbol value.
-            0,     // Size:          Don't specify the size as an FDE can
-            false, // Size is valid: cover multiple symbols.
-            false, // Contains linker annotations?
-            0);    // Symbol flags.
+            /*symID=*/symbol_id,
+            /*name=*/llvm::StringRef(), // Name will be auto generated.
+            /*type=*/eSymbolTypeCode,
+            /*external=*/true,
+            /*is_debug=*/false,
+            /*is_trampoline=*/false,
+            /*is_artificial=*/true,
+            /*section_sp=*/section_sp,
+            /*offset=*/offset,
+            /*size=*/0, // FDE can span multiple symbols so don't use its size.
+            /*size_is_valid=*/false,
+            /*contains_linker_annotations=*/false,
+            /*flags=*/0);
         new_symbols.push_back(eh_symbol);
       }
     }
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 062271f..e678c2f 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -9,7 +9,7 @@
 #ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
 #define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include <vector>
 
@@ -22,13 +22,13 @@
 #include "ELFHeader.h"
 
 struct ELFNote {
-  elf::elf_word n_namesz;
-  elf::elf_word n_descsz;
-  elf::elf_word n_type;
+  elf::elf_word n_namesz = 0;
+  elf::elf_word n_descsz = 0;
+  elf::elf_word n_type = 0;
 
   std::string n_name;
 
-  ELFNote() : n_namesz(0), n_descsz(0), n_type(0) {}
+  ELFNote() = default;
 
   /// Parse an ELFNote entry from the given DataExtractor starting at position
   /// \p offset.
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index 93c2c9f..f93ac92 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -100,7 +100,7 @@
   }
 }
 
-ObjectFileJIT::~ObjectFileJIT() {}
+ObjectFileJIT::~ObjectFileJIT() = default;
 
 bool ObjectFileJIT::ParseHeader() {
   // JIT code is never in a file, nor is it required to have any header
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 463a2a5..fd1a23d 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -17,10 +17,13 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Host/SafeMachO.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -41,8 +44,8 @@
 #include "lldb/Utility/Timer.h"
 #include "lldb/Utility/UUID.h"
 
-#include "lldb/Host/SafeMachO.h"
-
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 #include "ObjectFileMachO.h"
@@ -59,8 +62,54 @@
 #include <uuid/uuid.h>
 #endif
 
+#include <bitset>
 #include <memory>
 
+#if LLVM_SUPPORT_XCODE_SIGNPOSTS
+// Unfortunately the signpost header pulls in the system MachO header, too.
+#undef CPU_TYPE_ARM
+#undef CPU_TYPE_ARM64
+#undef CPU_TYPE_ARM64_32
+#undef CPU_TYPE_I386
+#undef CPU_TYPE_X86_64
+#undef MH_BINDATLOAD
+#undef MH_BUNDLE
+#undef MH_CIGAM
+#undef MH_CIGAM_64
+#undef MH_CORE
+#undef MH_DSYM
+#undef MH_DYLDLINK
+#undef MH_DYLIB
+#undef MH_DYLIB_STUB
+#undef MH_DYLINKER
+#undef MH_DYLINKER
+#undef MH_EXECUTE
+#undef MH_FVMLIB
+#undef MH_INCRLINK
+#undef MH_KEXT_BUNDLE
+#undef MH_MAGIC
+#undef MH_MAGIC_64
+#undef MH_NOUNDEFS
+#undef MH_OBJECT
+#undef MH_OBJECT
+#undef MH_PRELOAD
+
+#undef LC_BUILD_VERSION
+#undef LC_VERSION_MIN_MACOSX
+#undef LC_VERSION_MIN_IPHONEOS
+#undef LC_VERSION_MIN_TVOS
+#undef LC_VERSION_MIN_WATCHOS
+
+#undef PLATFORM_MACOS
+#undef PLATFORM_MACCATALYST
+#undef PLATFORM_IOS
+#undef PLATFORM_IOSSIMULATOR
+#undef PLATFORM_TVOS
+#undef PLATFORM_TVOSSIMULATOR
+#undef PLATFORM_WATCHOS
+#undef PLATFORM_WATCHOSSIMULATOR
+#endif
+
 #define THUMB_ADDRESS_BIT_MASK 0xfffffffffffffffeull
 using namespace lldb;
 using namespace lldb_private;
@@ -738,11 +787,11 @@
   switch (magic) {
   case MH_MAGIC:
   case MH_CIGAM:
-    return sizeof(struct mach_header);
+    return sizeof(struct llvm::MachO::mach_header);
 
   case MH_MAGIC_64:
   case MH_CIGAM_64:
-    return sizeof(struct mach_header_64);
+    return sizeof(struct llvm::MachO::mach_header_64);
     break;
 
   default:
@@ -1061,7 +1110,7 @@
     // None found.
     return false;
   } else {
-    memset(&m_header, 0, sizeof(struct mach_header));
+    memset(&m_header, 0, sizeof(struct llvm::MachO::mach_header));
   }
   return false;
 }
@@ -1271,7 +1320,7 @@
       for (uint32_t i = 0; i < m_header.ncmds; ++i) {
         const lldb::offset_t load_cmd_offset = offset;
 
-        load_command lc;
+        llvm::MachO::load_command lc;
         if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
           break;
         if (lc.cmd == LC_DYSYMTAB) {
@@ -1298,7 +1347,7 @@
   EncryptedFileRanges result;
   lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
 
-  encryption_info_command encryption_cmd;
+  llvm::MachO::encryption_info_command encryption_cmd;
   for (uint32_t i = 0; i < m_header.ncmds; ++i) {
     const lldb::offset_t load_cmd_offset = offset;
     if (m_data.GetU32(&offset, &encryption_cmd, 2) == nullptr)
@@ -1323,14 +1372,14 @@
   return result;
 }
 
-void ObjectFileMachO::SanitizeSegmentCommand(segment_command_64 &seg_cmd,
-                                             uint32_t cmd_idx) {
+void ObjectFileMachO::SanitizeSegmentCommand(
+    llvm::MachO::segment_command_64 &seg_cmd, uint32_t cmd_idx) {
   if (m_length == 0 || seg_cmd.filesize == 0)
     return;
 
   if ((m_header.flags & MH_DYLIB_IN_CACHE) && !IsInMemory()) {
     // In shared cache images, the load commands are relative to the
-    // shared cache file, and not the the specific image we are
+    // shared cache file, and not the specific image we are
     // examining. Let's fix this up so that it looks like a normal
     // image.
     if (strncmp(seg_cmd.segname, "__TEXT", sizeof(seg_cmd.segname)) == 0)
@@ -1380,7 +1429,8 @@
   }
 }
 
-static uint32_t GetSegmentPermissions(const segment_command_64 &seg_cmd) {
+static uint32_t
+GetSegmentPermissions(const llvm::MachO::segment_command_64 &seg_cmd) {
   uint32_t result = 0;
   if (seg_cmd.initprot & VM_PROT_READ)
     result |= ePermissionsReadable;
@@ -1548,11 +1598,10 @@
       : EncryptedRanges(std::move(EncryptedRanges)), UnifiedList(UnifiedList) {}
 };
 
-void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
-                                            lldb::offset_t offset,
-                                            uint32_t cmd_idx,
-                                            SegmentParsingContext &context) {
-  segment_command_64 load_cmd;
+void ObjectFileMachO::ProcessSegmentCommand(
+    const llvm::MachO::load_command &load_cmd_, lldb::offset_t offset,
+    uint32_t cmd_idx, SegmentParsingContext &context) {
+  llvm::MachO::segment_command_64 load_cmd;
   memcpy(&load_cmd, &load_cmd_, sizeof(load_cmd_));
 
   if (!m_data.GetU8(&offset, (uint8_t *)load_cmd.segname, 16))
@@ -1653,7 +1702,7 @@
     m_sections_up->AddSection(unified_section_sp);
   }
 
-  struct section_64 sect64;
+  llvm::MachO::section_64 sect64;
   ::memset(&sect64, 0, sizeof(sect64));
   // Push a section into our mach sections for the section at index zero
   // (NO_SECT) if we don't have any mach sections yet...
@@ -1825,8 +1874,8 @@
   }
 }
 
-void ObjectFileMachO::ProcessDysymtabCommand(const load_command &load_cmd,
-                                             lldb::offset_t offset) {
+void ObjectFileMachO::ProcessDysymtabCommand(
+    const llvm::MachO::load_command &load_cmd, lldb::offset_t offset) {
   m_dysymtab.cmd = load_cmd.cmd;
   m_dysymtab.cmdsize = load_cmd.cmdsize;
   m_data.GetU32(&offset, &m_dysymtab.ilocalsym,
@@ -1846,7 +1895,7 @@
   offset = MachHeaderSizeFromMagic(m_header.magic);
 
   SegmentParsingContext context(GetEncryptedFileRanges(), unified_section_list);
-  struct load_command load_cmd;
+  llvm::MachO::load_command load_cmd;
   for (uint32_t i = 0; i < m_header.ncmds; ++i) {
     const lldb::offset_t load_cmd_offset = offset;
     if (m_data.GetU32(&offset, &load_cmd, 2) == nullptr)
@@ -1893,9 +1942,9 @@
             filename = first_section_sp->GetObjectFile()->GetFileSpec().GetPath();
 
           Host::SystemLog(Host::eSystemLogError,
-                          "error: unable to find section %d for a symbol in %s, corrupt file?\n",
-                          n_sect, 
-                          filename.c_str());
+                          "error: unable to find section %d for a symbol in "
+                          "%s, corrupt file?\n",
+                          n_sect, filename.c_str());
         }
       }
       if (m_section_infos[n_sect].vm_range.Contains(file_addr)) {
@@ -2167,9 +2216,12 @@
   if (!module_sp)
     return 0;
 
-  struct symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
-  struct linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
-  struct dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+  Progress progress(llvm::formatv("Parsing symbol table for {0}",
+                                  m_file.GetFilename().AsCString("<Unknown>")));
+
+  llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
+  llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
+  llvm::MachO::dyld_info_command dyld_info = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
   // The data element of type bool indicates that this entry is thumb
   // code.
   typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
@@ -2178,7 +2230,16 @@
   // We add symbols to the table in the order of most information (nlist
   // records) to least (function starts), and avoid duplicating symbols
   // via this set.
-  std::set<addr_t> symbols_added;
+  llvm::DenseSet<addr_t> symbols_added;
+
+  // We are using a llvm::DenseSet for "symbols_added" so we must be sure we
+  // do not add the tombstone or empty keys to the set.
+  auto add_symbol_addr = [&symbols_added](lldb::addr_t file_addr) {
+    // Don't add the tombstone or empty keys.
+    if (file_addr == UINT64_MAX || file_addr == UINT64_MAX - 1)
+      return;
+    symbols_added.insert(file_addr);
+  };
   FunctionStarts function_starts;
   lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
   uint32_t i;
@@ -2191,7 +2252,7 @@
   for (i = 0; i < m_header.ncmds; ++i) {
     const lldb::offset_t cmd_offset = offset;
     // Read in the load command and load command size
-    struct load_command lc;
+    llvm::MachO::load_command lc;
     if (m_data.GetU32(&offset, &lc, 2) == nullptr)
       break;
     // Watch for the symbol table load command
@@ -2578,7 +2639,7 @@
   typedef std::set<ConstString> IndirectSymbols;
   IndirectSymbols indirect_symbol_names;
 
-#if defined(__APPLE__) && TARGET_OS_EMBEDDED
+#if TARGET_OS_IPHONE
 
   // Some recent builds of the dyld_shared_cache (hereafter: DSC) have been
   // optimized by moving LOCAL symbols out of the memory mapped portion of
@@ -3635,9 +3696,9 @@
                                     symbol_section);
                                 sym[GSYM_sym_idx].GetAddressRef().SetOffset(
                                     symbol_value);
-                                symbols_added.insert(sym[GSYM_sym_idx]
-                                                         .GetAddress()
-                                                         .GetFileAddress());
+                                add_symbol_addr(sym[GSYM_sym_idx]
+                                                    .GetAddress()
+                                                    .GetFileAddress());
                                 // We just need the flags from the linker
                                 // symbol, so put these flags
                                 // into the N_GSYM flags to avoid duplicate
@@ -3657,7 +3718,7 @@
                       if (set_value) {
                         sym[sym_idx].GetAddressRef().SetSection(symbol_section);
                         sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
-                        symbols_added.insert(
+                        add_symbol_addr(
                             sym[sym_idx].GetAddress().GetFileAddress());
                       }
                       sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
@@ -4470,7 +4531,7 @@
                 // invalid address of zero when the global is a common symbol.
                 sym[GSYM_sym_idx].GetAddressRef().SetSection(symbol_section);
                 sym[GSYM_sym_idx].GetAddressRef().SetOffset(symbol_value);
-                symbols_added.insert(
+                add_symbol_addr(
                     sym[GSYM_sym_idx].GetAddress().GetFileAddress());
                 // We just need the flags from the linker symbol, so put these
                 // flags into the N_GSYM flags to avoid duplicate symbols in
@@ -4489,7 +4550,8 @@
       if (set_value) {
         sym[sym_idx].GetAddressRef().SetSection(symbol_section);
         sym[sym_idx].GetAddressRef().SetOffset(symbol_value);
-        symbols_added.insert(sym[sym_idx].GetAddress().GetFileAddress());
+        if (symbol_section)
+          add_symbol_addr(sym[sym_idx].GetAddress().GetFileAddress());
       }
       sym[sym_idx].SetFlags(nlist.n_type << 16 | nlist.n_desc);
       if (nlist.n_desc & N_WEAK_REF)
@@ -4585,7 +4647,7 @@
         sym[sym_idx].SetIsSynthetic(true);
         sym[sym_idx].SetExternal(true);
         sym[sym_idx].GetAddressRef() = symbol_addr;
-        symbols_added.insert(symbol_addr.GetFileAddress());
+        add_symbol_addr(symbol_addr.GetFileAddress());
         if (e.entry.flags & TRIE_SYMBOL_IS_THUMB)
           sym[sym_idx].SetFlags(MACHO_NLIST_ARM_SYMBOL_IS_THUMB);
         ++sym_idx;
@@ -4635,12 +4697,14 @@
                 symbol_byte_size = section_end_file_addr - symbol_file_addr;
               }
               sym[sym_idx].SetID(synthetic_sym_id++);
-              sym[sym_idx].GetMangled().SetDemangledName(
-                  GetNextSyntheticSymbolName());
+              // Don't set the name for any synthetic symbols, the Symbol
+              // object will generate one if needed when the name is accessed
+              // via accessors.
+              sym[sym_idx].GetMangled().SetDemangledName(ConstString());
               sym[sym_idx].SetType(eSymbolTypeCode);
               sym[sym_idx].SetIsSynthetic(true);
               sym[sym_idx].GetAddressRef() = symbol_addr;
-              symbols_added.insert(symbol_addr.GetFileAddress());
+              add_symbol_addr(symbol_addr.GetFileAddress());
               if (symbol_flags)
                 sym[sym_idx].SetFlags(symbol_flags);
               if (symbol_byte_size)
@@ -4741,7 +4805,7 @@
                     sym[sym_idx].SetType(eSymbolTypeResolver);
                   sym[sym_idx].SetIsSynthetic(true);
                   sym[sym_idx].GetAddressRef() = so_addr;
-                  symbols_added.insert(so_addr.GetFileAddress());
+                  add_symbol_addr(so_addr.GetFileAddress());
                   sym[sym_idx].SetByteSize(symbol_stub_byte_size);
                   ++sym_idx;
                 }
@@ -4838,7 +4902,7 @@
                               const lldb_private::DataExtractor &data,
                               lldb::offset_t lc_offset) {
   uint32_t i;
-  struct uuid_command load_cmd;
+  llvm::MachO::uuid_command load_cmd;
 
   lldb::offset_t offset = lc_offset;
   for (i = 0; i < header.ncmds; ++i) {
@@ -4986,7 +5050,7 @@
     return add_triple(base_triple);
   }
 
-  struct load_command load_cmd;
+  llvm::MachO::load_command load_cmd;
 
   // See if there is an LC_VERSION_MIN_* load command that can give
   // us the OS type.
@@ -4996,7 +5060,7 @@
     if (data.GetU32(&offset, &load_cmd, 2) == NULL)
       break;
 
-    struct version_min_command version_min;
+    llvm::MachO::version_min_command version_min;
     switch (load_cmd.cmd) {
     case llvm::MachO::LC_VERSION_MIN_MACOSX:
     case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
@@ -5048,7 +5112,7 @@
 
     do {
       if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
-        struct build_version_command build_version;
+        llvm::MachO::build_version_command build_version;
         if (load_cmd.cmdsize < sizeof(build_version)) {
           // Malformed load command.
           break;
@@ -5129,7 +5193,7 @@
   ModuleSP module_sp(GetModule());
   if (module_sp) {
     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-    struct load_command load_cmd;
+    llvm::MachO::load_command load_cmd;
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     std::vector<std::string> rpath_paths;
     std::vector<std::string> rpath_relative_paths;
@@ -5265,7 +5329,7 @@
   ModuleSP module_sp(GetModule());
   if (module_sp) {
     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-    struct load_command load_cmd;
+    llvm::MachO::load_command load_cmd;
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     uint32_t i;
     lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
@@ -5422,7 +5486,7 @@
       m_thread_context_offsets_valid = true;
       lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
       FileRangeArray::Entry file_range;
-      thread_command thread_cmd;
+      llvm::MachO::thread_command thread_cmd;
       for (uint32_t i = 0; i < m_header.ncmds; ++i) {
         const uint32_t cmd_offset = offset;
         if (m_data.GetU32(&offset, &thread_cmd, 2) == nullptr)
@@ -5451,7 +5515,7 @@
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     for (uint32_t i = 0; i < m_header.ncmds; ++i) {
       const uint32_t cmd_offset = offset;
-      load_command lc;
+      llvm::MachO::load_command lc;
       if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
         break;
       if (lc.cmd == LC_NOTE) {
@@ -5491,7 +5555,7 @@
     offset = MachHeaderSizeFromMagic(m_header.magic);
     for (uint32_t i = 0; i < m_header.ncmds; ++i) {
       const uint32_t cmd_offset = offset;
-      struct ident_command ident_command;
+      llvm::MachO::ident_command ident_command;
       if (m_data.GetU32(&offset, &ident_command, 2) == nullptr)
         break;
       if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
@@ -5510,6 +5574,46 @@
   return result;
 }
 
+addr_t ObjectFileMachO::GetAddressMask() {
+  addr_t mask = 0;
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+      const uint32_t cmd_offset = offset;
+      llvm::MachO::load_command lc;
+      if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
+        break;
+      if (lc.cmd == LC_NOTE) {
+        char data_owner[17];
+        m_data.CopyData(offset, 16, data_owner);
+        data_owner[16] = '\0';
+        offset += 16;
+        uint64_t fileoff = m_data.GetU64_unchecked(&offset);
+
+        // "addrable bits" has a uint32_t version and a uint32_t
+        // number of bits used in addressing.
+        if (strcmp("addrable bits", data_owner) == 0) {
+          offset = fileoff;
+          uint32_t version;
+          if (m_data.GetU32(&offset, &version, 1) != nullptr) {
+            if (version == 3) {
+              uint32_t num_addr_bits = m_data.GetU32_unchecked(&offset);
+              if (num_addr_bits != 0) {
+                mask = ~((1ULL << num_addr_bits) - 1);
+              }
+              break;
+            }
+          }
+        }
+      }
+      offset = cmd_offset + lc.cmdsize;
+    }
+  }
+  return mask;
+}
+
 bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid,
                                                 ObjectFile::BinaryType &type) {
   address = LLDB_INVALID_ADDRESS;
@@ -5520,7 +5624,7 @@
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     for (uint32_t i = 0; i < m_header.ncmds; ++i) {
       const uint32_t cmd_offset = offset;
-      load_command lc;
+      llvm::MachO::load_command lc;
       if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
         break;
       if (lc.cmd == LC_NOTE) {
@@ -5730,7 +5834,7 @@
   ModuleSP module_sp(GetModule());
   if (module_sp) {
     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-    struct dylib_command load_cmd;
+    llvm::MachO::dylib_command load_cmd;
     lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
     uint32_t version_cmd = 0;
     uint64_t version = 0;
@@ -5897,7 +6001,7 @@
     for (uint32_t i = 0; i < m_header.ncmds; ++i) {
       const lldb::offset_t load_cmd_offset = offset;
 
-      version_min_command lc;
+      llvm::MachO::version_min_command lc;
       if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
         break;
       if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
@@ -5958,7 +6062,7 @@
     for (uint32_t i = 0; i < m_header.ncmds; ++i) {
       const lldb::offset_t load_cmd_offset = offset;
 
-      version_min_command lc;
+      llvm::MachO::version_min_command lc;
       if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
         break;
       if (lc.cmd == llvm::MachO::LC_VERSION_MIN_MACOSX ||
@@ -5987,7 +6091,7 @@
       for (uint32_t i = 0; i < m_header.ncmds; ++i) {
         const lldb::offset_t load_cmd_offset = offset;
 
-        version_min_command lc;
+        llvm::MachO::version_min_command lc;
         if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
           break;
         if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
@@ -6144,11 +6248,257 @@
   return num_loaded_sections > 0;
 }
 
+struct all_image_infos_header {
+  uint32_t version;         // currently 1
+  uint32_t imgcount;        // number of binary images
+  uint64_t entries_fileoff; // file offset in the corefile of where the array of
+                            // struct entry's begin.
+  uint32_t entries_size;    // size of 'struct entry'.
+  uint32_t unused;
+};
+
+struct image_entry {
+  uint64_t filepath_offset;  // offset in corefile to c-string of the file path,
+                             // UINT64_MAX if unavailable.
+  uuid_t uuid;               // uint8_t[16].  should be set to all zeroes if
+                             // uuid is unknown.
+  uint64_t load_address;     // UINT64_MAX if unknown.
+  uint64_t seg_addrs_offset; // offset to the array of struct segment_vmaddr's.
+  uint32_t segment_count;    // The number of segments for this binary.
+  uint32_t unused;
+
+  image_entry() {
+    filepath_offset = UINT64_MAX;
+    memset(&uuid, 0, sizeof(uuid_t));
+    segment_count = 0;
+    load_address = UINT64_MAX;
+    seg_addrs_offset = UINT64_MAX;
+    unused = 0;
+  }
+  image_entry(const image_entry &rhs) {
+    filepath_offset = rhs.filepath_offset;
+    memcpy(&uuid, &rhs.uuid, sizeof(uuid_t));
+    segment_count = rhs.segment_count;
+    seg_addrs_offset = rhs.seg_addrs_offset;
+    load_address = rhs.load_address;
+    unused = rhs.unused;
+  }
+};
+
+struct segment_vmaddr {
+  char segname[16];
+  uint64_t vmaddr;
+  uint64_t unused;
+
+  segment_vmaddr() {
+    memset(&segname, 0, 16);
+    vmaddr = UINT64_MAX;
+    unused = 0;
+  }
+  segment_vmaddr(const segment_vmaddr &rhs) {
+    memcpy(&segname, &rhs.segname, 16);
+    vmaddr = rhs.vmaddr;
+    unused = rhs.unused;
+  }
+};
+
+// Write the payload for the "all image infos" LC_NOTE into
+// the supplied all_image_infos_payload, assuming that this
+// will be written into the corefile starting at
+// initial_file_offset.
+//
+// The placement of this payload is a little tricky.  We're
+// laying this out as
+//
+// 1. header (struct all_image_info_header)
+// 2. Array of fixed-size (struct image_entry)'s, one
+//    per binary image present in the process.
+// 3. Arrays of (struct segment_vmaddr)'s, a varying number
+//    for each binary image.
+// 4. Variable length c-strings of binary image filepaths,
+//    one per binary.
+//
+// To compute where everything will be laid out in the
+// payload, we need to iterate over the images and calculate
+// how many segment_vmaddr structures each image will need,
+// and how long each image's filepath c-string is. There
+// are some multiple passes over the image list while calculating
+// everything.
+
+static offset_t
+CreateAllImageInfosPayload(const lldb::ProcessSP &process_sp,
+                           offset_t initial_file_offset,
+                           StreamString &all_image_infos_payload) {
+  Target &target = process_sp->GetTarget();
+  const ModuleList &modules = target.GetImages();
+  size_t modules_count = modules.GetSize();
+
+  std::set<std::string> executing_uuids;
+  ThreadList &thread_list(process_sp->GetThreadList());
+  for (uint32_t i = 0; i < thread_list.GetSize(); i++) {
+    ThreadSP thread_sp = thread_list.GetThreadAtIndex(i);
+    uint32_t stack_frame_count = thread_sp->GetStackFrameCount();
+    for (uint32_t j = 0; j < stack_frame_count; j++) {
+      StackFrameSP stack_frame_sp = thread_sp->GetStackFrameAtIndex(j);
+      Address pc = stack_frame_sp->GetFrameCodeAddress();
+      ModuleSP module_sp = pc.GetModule();
+      if (module_sp) {
+        UUID uuid = module_sp->GetUUID();
+        if (uuid.IsValid()) {
+          executing_uuids.insert(uuid.GetAsString());
+        }
+      }
+    }
+  }
+
+  struct all_image_infos_header infos;
+  infos.version = 1;
+  infos.imgcount = modules_count;
+  infos.entries_size = sizeof(image_entry);
+  infos.entries_fileoff = initial_file_offset + sizeof(all_image_infos_header);
+  infos.unused = 0;
+
+  all_image_infos_payload.PutHex32(infos.version);
+  all_image_infos_payload.PutHex32(infos.imgcount);
+  all_image_infos_payload.PutHex64(infos.entries_fileoff);
+  all_image_infos_payload.PutHex32(infos.entries_size);
+  all_image_infos_payload.PutHex32(infos.unused);
+
+  // First create the structures for all of the segment name+vmaddr vectors
+  // for each module, so we will know the size of them as we add the
+  // module entries.
+  std::vector<std::vector<segment_vmaddr>> modules_segment_vmaddrs;
+  for (size_t i = 0; i < modules_count; i++) {
+    ModuleSP module = modules.GetModuleAtIndex(i);
+
+    SectionList *sections = module->GetSectionList();
+    size_t sections_count = sections->GetSize();
+    std::vector<segment_vmaddr> segment_vmaddrs;
+    for (size_t j = 0; j < sections_count; j++) {
+      SectionSP section = sections->GetSectionAtIndex(j);
+      if (!section->GetParent().get()) {
+        addr_t vmaddr = section->GetLoadBaseAddress(&target);
+        if (vmaddr == LLDB_INVALID_ADDRESS)
+          continue;
+        ConstString name = section->GetName();
+        segment_vmaddr seg_vmaddr;
+        strncpy(seg_vmaddr.segname, name.AsCString(),
+                sizeof(seg_vmaddr.segname));
+        seg_vmaddr.vmaddr = vmaddr;
+        seg_vmaddr.unused = 0;
+        segment_vmaddrs.push_back(seg_vmaddr);
+      }
+    }
+    modules_segment_vmaddrs.push_back(segment_vmaddrs);
+  }
+
+  offset_t size_of_vmaddr_structs = 0;
+  for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
+    size_of_vmaddr_structs +=
+        modules_segment_vmaddrs[i].size() * sizeof(segment_vmaddr);
+  }
+
+  offset_t size_of_filepath_cstrings = 0;
+  for (size_t i = 0; i < modules_count; i++) {
+    ModuleSP module_sp = modules.GetModuleAtIndex(i);
+    size_of_filepath_cstrings += module_sp->GetFileSpec().GetPath().size() + 1;
+  }
+
+  // Calculate the file offsets of our "all image infos" payload in the
+  // corefile. initial_file_offset the original value passed in to this method.
+
+  offset_t start_of_entries =
+      initial_file_offset + sizeof(all_image_infos_header);
+  offset_t start_of_seg_vmaddrs =
+      start_of_entries + sizeof(image_entry) * modules_count;
+  offset_t start_of_filenames = start_of_seg_vmaddrs + size_of_vmaddr_structs;
+
+  offset_t final_file_offset = start_of_filenames + size_of_filepath_cstrings;
+
+  // Now write the one-per-module 'struct image_entry' into the
+  // StringStream; keep track of where the struct segment_vmaddr
+  // entries for each module will end up in the corefile.
+
+  offset_t current_string_offset = start_of_filenames;
+  offset_t current_segaddrs_offset = start_of_seg_vmaddrs;
+  std::vector<struct image_entry> image_entries;
+  for (size_t i = 0; i < modules_count; i++) {
+    ModuleSP module_sp = modules.GetModuleAtIndex(i);
+
+    struct image_entry ent;
+    memcpy(&ent.uuid, module_sp->GetUUID().GetBytes().data(), sizeof(ent.uuid));
+    if (modules_segment_vmaddrs[i].size() > 0) {
+      ent.segment_count = modules_segment_vmaddrs[i].size();
+      ent.seg_addrs_offset = current_segaddrs_offset;
+    }
+    ent.filepath_offset = current_string_offset;
+    ObjectFile *objfile = module_sp->GetObjectFile();
+    if (objfile) {
+      Address base_addr(objfile->GetBaseAddress());
+      if (base_addr.IsValid()) {
+        ent.load_address = base_addr.GetLoadAddress(&target);
+      }
+    }
+
+    all_image_infos_payload.PutHex64(ent.filepath_offset);
+    all_image_infos_payload.PutRawBytes(ent.uuid, sizeof(ent.uuid));
+    all_image_infos_payload.PutHex64(ent.load_address);
+    all_image_infos_payload.PutHex64(ent.seg_addrs_offset);
+    all_image_infos_payload.PutHex32(ent.segment_count);
+
+    if (executing_uuids.find(module_sp->GetUUID().GetAsString()) !=
+        executing_uuids.end())
+      all_image_infos_payload.PutHex32(1);
+    else
+      all_image_infos_payload.PutHex32(0);
+
+    current_segaddrs_offset += ent.segment_count * sizeof(segment_vmaddr);
+    current_string_offset += module_sp->GetFileSpec().GetPath().size() + 1;
+  }
+
+  // Now write the struct segment_vmaddr entries into the StringStream.
+
+  for (size_t i = 0; i < modules_segment_vmaddrs.size(); i++) {
+    if (modules_segment_vmaddrs[i].size() == 0)
+      continue;
+    for (struct segment_vmaddr segvm : modules_segment_vmaddrs[i]) {
+      all_image_infos_payload.PutRawBytes(segvm.segname, sizeof(segvm.segname));
+      all_image_infos_payload.PutHex64(segvm.vmaddr);
+      all_image_infos_payload.PutHex64(segvm.unused);
+    }
+  }
+
+  for (size_t i = 0; i < modules_count; i++) {
+    ModuleSP module_sp = modules.GetModuleAtIndex(i);
+    std::string filepath = module_sp->GetFileSpec().GetPath();
+    all_image_infos_payload.PutRawBytes(filepath.data(), filepath.size() + 1);
+  }
+
+  return final_file_offset;
+}
+
+// Temp struct used to combine contiguous memory regions with
+// identical permissions.
+struct page_object {
+  addr_t addr;
+  addr_t size;
+  uint32_t prot;
+};
+
 bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
-                               const FileSpec &outfile, Status &error) {
+                               const FileSpec &outfile,
+                               lldb::SaveCoreStyle &core_style, Status &error) {
   if (!process_sp)
     return false;
 
+  // For Mach-O, we can only create full corefiles or dirty-page-only
+  // corefiles.  The default is dirty-page-only.
+  if (core_style != SaveCoreStyle::eSaveCoreFull) {
+    core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
+  } else {
+    core_style = SaveCoreStyle::eSaveCoreFull;
+  }
+
   Target &target = process_sp->GetTarget();
   const ArchSpec target_arch = target.GetArchitecture();
   const llvm::Triple &target_triple = target_arch.GetTriple();
@@ -6176,20 +6526,16 @@
     }
 
     if (make_core) {
-      std::vector<segment_command_64> segment_load_commands;
+      std::vector<llvm::MachO::segment_command_64> segment_load_commands;
       //                uint32_t range_info_idx = 0;
       MemoryRegionInfo range_info;
       Status range_error = process_sp->GetMemoryRegionInfo(0, range_info);
       const uint32_t addr_byte_size = target_arch.GetAddressByteSize();
       const ByteOrder byte_order = target_arch.GetByteOrder();
+      std::vector<page_object> pages_to_copy;
+
       if (range_error.Success()) {
         while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) {
-          const addr_t addr = range_info.GetRange().GetRangeBase();
-          const addr_t size = range_info.GetRange().GetByteSize();
-
-          if (size == 0)
-            break;
-
           // Calculate correct protections
           uint32_t prot = 0;
           if (range_info.GetReadable() == MemoryRegionInfo::eYes)
@@ -6199,32 +6545,33 @@
           if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
             prot |= VM_PROT_EXECUTE;
 
+          const addr_t addr = range_info.GetRange().GetRangeBase();
+          const addr_t size = range_info.GetRange().GetByteSize();
+
+          if (size == 0)
+            break;
+
           if (prot != 0) {
-            uint32_t cmd_type = LC_SEGMENT_64;
-            uint32_t segment_size = sizeof(segment_command_64);
-            if (addr_byte_size == 4) {
-              cmd_type = LC_SEGMENT;
-              segment_size = sizeof(segment_command);
+            addr_t pagesize = range_info.GetPageSize();
+            const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
+                range_info.GetDirtyPageList();
+            if (core_style == SaveCoreStyle::eSaveCoreDirtyOnly &&
+                dirty_page_list.hasValue()) {
+              core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
+              for (addr_t dirtypage : dirty_page_list.getValue()) {
+                page_object obj;
+                obj.addr = dirtypage;
+                obj.size = pagesize;
+                obj.prot = prot;
+                pages_to_copy.push_back(obj);
+              }
+            } else {
+              page_object obj;
+              obj.addr = addr;
+              obj.size = size;
+              obj.prot = prot;
+              pages_to_copy.push_back(obj);
             }
-            segment_command_64 segment = {
-                cmd_type,     // uint32_t cmd;
-                segment_size, // uint32_t cmdsize;
-                {0},          // char segname[16];
-                addr, // uint64_t vmaddr;    // uint32_t for 32-bit Mach-O
-                size, // uint64_t vmsize;    // uint32_t for 32-bit Mach-O
-                0,    // uint64_t fileoff;   // uint32_t for 32-bit Mach-O
-                size, // uint64_t filesize;  // uint32_t for 32-bit Mach-O
-                prot, // uint32_t maxprot;
-                prot, // uint32_t initprot;
-                0,    // uint32_t nsects;
-                0};   // uint32_t flags;
-            segment_load_commands.push_back(segment);
-          } else {
-            // No protections and a size of 1 used to be returned from old
-            // debugservers when we asked about a region that was past the
-            // last memory region and it indicates the end...
-            if (size == 1)
-              break;
           }
 
           range_error = process_sp->GetMemoryRegionInfo(
@@ -6233,9 +6580,54 @@
             break;
         }
 
+        // Combine contiguous entries that have the same
+        // protections so we don't have an excess of
+        // load commands.
+        std::vector<page_object> combined_page_objects;
+        page_object last_obj;
+        last_obj.addr = LLDB_INVALID_ADDRESS;
+        for (page_object obj : pages_to_copy) {
+          if (last_obj.addr == LLDB_INVALID_ADDRESS) {
+            last_obj = obj;
+            continue;
+          }
+          if (last_obj.addr + last_obj.size == obj.addr &&
+              last_obj.prot == obj.prot) {
+            last_obj.size += obj.size;
+            continue;
+          }
+          combined_page_objects.push_back(last_obj);
+          last_obj = obj;
+        }
+
+        for (page_object obj : combined_page_objects) {
+          uint32_t cmd_type = LC_SEGMENT_64;
+          uint32_t segment_size = sizeof(llvm::MachO::segment_command_64);
+          if (addr_byte_size == 4) {
+            cmd_type = LC_SEGMENT;
+            segment_size = sizeof(llvm::MachO::segment_command);
+          }
+          llvm::MachO::segment_command_64 segment = {
+              cmd_type,     // uint32_t cmd;
+              segment_size, // uint32_t cmdsize;
+              {0},          // char segname[16];
+              obj.addr,     // uint64_t vmaddr;    // uint32_t for 32-bit
+                            // Mach-O
+              obj.size,     // uint64_t vmsize;    // uint32_t for 32-bit
+                            // Mach-O
+              0,            // uint64_t fileoff;   // uint32_t for 32-bit Mach-O
+              obj.size,     // uint64_t filesize;  // uint32_t for 32-bit
+                            // Mach-O
+              obj.prot,     // uint32_t maxprot;
+              obj.prot,     // uint32_t initprot;
+              0,            // uint32_t nsects;
+              0};           // uint32_t flags;
+          segment_load_commands.push_back(segment);
+        }
+
         StreamString buffer(Stream::eBinary, addr_byte_size, byte_order);
 
-        mach_header_64 mach_header;
+        llvm::MachO::mach_header_64 mach_header;
         if (addr_byte_size == 8) {
           mach_header.magic = MH_MAGIC_64;
         } else {
@@ -6290,11 +6682,11 @@
 
         // The size of the load command is the size of the segments...
         if (addr_byte_size == 8) {
-          mach_header.sizeofcmds =
-              segment_load_commands.size() * sizeof(struct segment_command_64);
+          mach_header.sizeofcmds = segment_load_commands.size() *
+                                   sizeof(llvm::MachO::segment_command_64);
         } else {
-          mach_header.sizeofcmds =
-              segment_load_commands.size() * sizeof(struct segment_command);
+          mach_header.sizeofcmds = segment_load_commands.size() *
+                                   sizeof(llvm::MachO::segment_command);
         }
 
         // and the size of all LC_THREAD load command
@@ -6303,6 +6695,19 @@
           mach_header.sizeofcmds += 8 + LC_THREAD_data.GetSize();
         }
 
+        // Bits will be set to indicate which bits are NOT used in
+        // addressing in this process or 0 for unknown.
+        uint64_t address_mask = process_sp->GetCodeAddressMask();
+        if (address_mask != 0) {
+          // LC_NOTE "addrable bits"
+          mach_header.ncmds++;
+          mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
+        }
+
+        // LC_NOTE "all image infos"
+        mach_header.ncmds++;
+        mach_header.sizeofcmds += sizeof(llvm::MachO::note_command);
+
         // Write the mach header
         buffer.PutHex32(mach_header.magic);
         buffer.PutHex32(mach_header.cputype);
@@ -6318,11 +6723,54 @@
         // Skip the mach header and all load commands and align to the next
         // 0x1000 byte boundary
         addr_t file_offset = buffer.GetSize() + mach_header.sizeofcmds;
-        if (file_offset & 0x00000fff) {
-          file_offset += 0x00001000ull;
-          file_offset &= (~0x00001000ull + 1);
+
+        file_offset = llvm::alignTo(file_offset, 16);
+        std::vector<std::unique_ptr<LCNoteEntry>> lc_notes;
+
+        // Add "addrable bits" LC_NOTE when an address mask is available
+        if (address_mask != 0) {
+          std::unique_ptr<LCNoteEntry> addrable_bits_lcnote_up(
+              new LCNoteEntry(addr_byte_size, byte_order));
+          addrable_bits_lcnote_up->name = "addrable bits";
+          addrable_bits_lcnote_up->payload_file_offset = file_offset;
+          int bits = std::bitset<64>(~address_mask).count();
+          addrable_bits_lcnote_up->payload.PutHex32(3); // version
+          addrable_bits_lcnote_up->payload.PutHex32(
+              bits); // # of bits used for addressing
+          addrable_bits_lcnote_up->payload.PutHex64(0); // unused
+
+          file_offset += addrable_bits_lcnote_up->payload.GetSize();
+
+          lc_notes.push_back(std::move(addrable_bits_lcnote_up));
         }
 
+        // Add "all image infos" LC_NOTE
+        std::unique_ptr<LCNoteEntry> all_image_infos_lcnote_up(
+            new LCNoteEntry(addr_byte_size, byte_order));
+        all_image_infos_lcnote_up->name = "all image infos";
+        all_image_infos_lcnote_up->payload_file_offset = file_offset;
+        file_offset = CreateAllImageInfosPayload(
+            process_sp, file_offset, all_image_infos_lcnote_up->payload);
+        lc_notes.push_back(std::move(all_image_infos_lcnote_up));
+
+        // Add LC_NOTE load commands
+        for (auto &lcnote : lc_notes) {
+          // Add the LC_NOTE load command to the file.
+          buffer.PutHex32(LC_NOTE);
+          buffer.PutHex32(sizeof(llvm::MachO::note_command));
+          char namebuf[16];
+          memset(namebuf, 0, sizeof(namebuf));
+          // this is the uncommon case where strncpy is exactly
+          // the right one, doesn't need to be nul terminated.
+          strncpy(namebuf, lcnote->name.c_str(), sizeof(namebuf));
+          buffer.PutRawBytes(namebuf, sizeof(namebuf));
+          buffer.PutHex64(lcnote->payload_file_offset);
+          buffer.PutHex64(lcnote->payload.GetSize());
+        }
+
+        // Align to 4096-byte page boundary for the LC_SEGMENTs.
+        file_offset = llvm::alignTo(file_offset, 4096);
+
         for (auto &segment : segment_load_commands) {
           segment.fileoff = file_offset;
           file_offset += segment.filesize;
@@ -6338,14 +6786,6 @@
 
         // Write out all of the segment load commands
         for (const auto &segment : segment_load_commands) {
-          printf("0x%8.8x 0x%8.8x [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
-                 ") [0x%16.16" PRIx64 " 0x%16.16" PRIx64
-                 ") 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x]\n",
-                 segment.cmd, segment.cmdsize, segment.vmaddr,
-                 segment.vmaddr + segment.vmsize, segment.fileoff,
-                 segment.filesize, segment.maxprot, segment.initprot,
-                 segment.nsects, segment.flags);
-
           buffer.PutHex32(segment.cmd);
           buffer.PutHex32(segment.cmdsize);
           buffer.PutRawBytes(segment.segname, sizeof(segment.segname));
@@ -6380,6 +6820,22 @@
           error =
               core_file.get()->Write(buffer.GetString().data(), bytes_written);
           if (error.Success()) {
+
+            for (auto &lcnote : lc_notes) {
+              if (core_file.get()->SeekFromStart(lcnote->payload_file_offset) ==
+                  -1) {
+                error.SetErrorStringWithFormat("Unable to seek to corefile pos "
+                                               "to write '%s' LC_NOTE payload",
+                                               lcnote->name.c_str());
+                return false;
+              }
+              bytes_written = lcnote->payload.GetSize();
+              error = core_file.get()->Write(lcnote->payload.GetData(),
+                                             bytes_written);
+              if (!error.Success())
+                return false;
+            }
+
             // Now write the file data for all memory segments in the process
             for (const auto &segment : segment_load_commands) {
               if (core_file.get()->SeekFromStart(segment.fileoff) == -1) {
@@ -6389,9 +6845,10 @@
                 break;
               }
 
-              printf("Saving %" PRId64
-                     " bytes of data for memory region at 0x%" PRIx64 "\n",
-                     segment.vmsize, segment.vmaddr);
+              target.GetDebugger().GetAsyncOutputStream()->Printf(
+                  "Saving %" PRId64
+                  " bytes of data for memory region at 0x%" PRIx64 "\n",
+                  segment.vmsize, segment.vmaddr);
               addr_t bytes_left = segment.vmsize;
               addr_t addr = segment.vmaddr;
               Status memory_read_error;
@@ -6433,3 +6890,121 @@
   }
   return false;
 }
+
+ObjectFileMachO::MachOCorefileAllImageInfos
+ObjectFileMachO::GetCorefileAllImageInfos() {
+  MachOCorefileAllImageInfos image_infos;
+
+  // Look for an "all image infos" LC_NOTE.
+  lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+  for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+    const uint32_t cmd_offset = offset;
+    llvm::MachO::load_command lc;
+    if (m_data.GetU32(&offset, &lc.cmd, 2) == nullptr)
+      break;
+    if (lc.cmd == LC_NOTE) {
+      char data_owner[17];
+      m_data.CopyData(offset, 16, data_owner);
+      data_owner[16] = '\0';
+      offset += 16;
+      uint64_t fileoff = m_data.GetU64_unchecked(&offset);
+      offset += 4; /* size unused */
+
+      if (strcmp("all image infos", data_owner) == 0) {
+        offset = fileoff;
+        // Read the struct all_image_infos_header.
+        uint32_t version = m_data.GetU32(&offset);
+        if (version != 1) {
+          return image_infos;
+        }
+        uint32_t imgcount = m_data.GetU32(&offset);
+        uint64_t entries_fileoff = m_data.GetU64(&offset);
+        offset += 4; // uint32_t entries_size;
+        offset += 4; // uint32_t unused;
+
+        offset = entries_fileoff;
+        for (uint32_t i = 0; i < imgcount; i++) {
+          // Read the struct image_entry.
+          offset_t filepath_offset = m_data.GetU64(&offset);
+          uuid_t uuid;
+          memcpy(&uuid, m_data.GetData(&offset, sizeof(uuid_t)),
+                 sizeof(uuid_t));
+          uint64_t load_address = m_data.GetU64(&offset);
+          offset_t seg_addrs_offset = m_data.GetU64(&offset);
+          uint32_t segment_count = m_data.GetU32(&offset);
+          uint32_t currently_executing = m_data.GetU32(&offset);
+
+          MachOCorefileImageEntry image_entry;
+          image_entry.filename = (const char *)m_data.GetCStr(&filepath_offset);
+          image_entry.uuid = UUID::fromData(uuid, sizeof(uuid_t));
+          image_entry.load_address = load_address;
+          image_entry.currently_executing = currently_executing;
+
+          offset_t seg_vmaddrs_offset = seg_addrs_offset;
+          for (uint32_t j = 0; j < segment_count; j++) {
+            char segname[17];
+            m_data.CopyData(seg_vmaddrs_offset, 16, segname);
+            segname[16] = '\0';
+            seg_vmaddrs_offset += 16;
+            uint64_t vmaddr = m_data.GetU64(&seg_vmaddrs_offset);
+            seg_vmaddrs_offset += 8; /* unused */
+
+            std::tuple<ConstString, addr_t> new_seg{ConstString(segname),
+                                                    vmaddr};
+            image_entry.segment_load_addresses.push_back(new_seg);
+          }
+          image_infos.all_image_infos.push_back(image_entry);
+        }
+      }
+    }
+    offset = cmd_offset + lc.cmdsize;
+  }
+
+  return image_infos;
+}
+
+bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
+  MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos();
+  bool added_images = false;
+  if (image_infos.IsValid()) {
+    for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) {
+      ModuleSpec module_spec;
+      module_spec.GetUUID() = image.uuid;
+      module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
+      if (image.currently_executing) {
+        Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+        if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+          process.GetTarget().GetOrCreateModule(module_spec, false);
+        }
+      }
+      Status error;
+      ModuleSP module_sp =
+          process.GetTarget().GetOrCreateModule(module_spec, false, &error);
+      if (!module_sp.get() || !module_sp->GetObjectFile()) {
+        if (image.load_address != LLDB_INVALID_ADDRESS) {
+          module_sp = process.ReadModuleFromMemory(module_spec.GetFileSpec(),
+                                                   image.load_address);
+        }
+      }
+      if (module_sp.get() && module_sp->GetObjectFile()) {
+        added_images = true;
+        if (module_sp->GetObjectFile()->GetType() ==
+            ObjectFile::eTypeExecutable) {
+          process.GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo);
+        }
+        for (auto name_vmaddr_tuple : image.segment_load_addresses) {
+          SectionList *sectlist = module_sp->GetObjectFile()->GetSectionList();
+          if (sectlist) {
+            SectionSP sect_sp =
+                sectlist->FindSectionByName(std::get<0>(name_vmaddr_tuple));
+            if (sect_sp) {
+              process.GetTarget().SetSectionLoadAddress(
+                  sect_sp, std::get<1>(name_vmaddr_tuple));
+            }
+          }
+        }
+      }
+    }
+  }
+  return added_images;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index 2308c49..3e8c84f 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -15,6 +15,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/RangeMap.h"
+#include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/UUID.h"
 
 // This class needs to be hidden as eventually belongs in a plugin that
@@ -58,6 +59,7 @@
 
   static bool SaveCore(const lldb::ProcessSP &process_sp,
                        const lldb_private::FileSpec &outfile,
+                       lldb::SaveCoreStyle &core_style,
                        lldb_private::Status &error);
 
   static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
@@ -112,10 +114,14 @@
 
   std::string GetIdentifierString() override;
 
+  lldb::addr_t GetAddressMask() override;
+
   bool GetCorefileMainBinaryInfo(lldb::addr_t &address,
                                  lldb_private::UUID &uuid,
                                  ObjectFile::BinaryType &type) override;
 
+  bool LoadCoreFileImages(lldb_private::Process &process) override;
+
   lldb::RegisterContextSP
   GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override;
 
@@ -209,6 +215,40 @@
 
   bool SectionIsLoadable(const lldb_private::Section *section);
 
+  /// A corefile may include metadata about all of the binaries that were
+  /// present in the process when the corefile was taken.  This is only
+  /// implemented for Mach-O files for now; we'll generalize it when we
+  /// have other systems that can include the same.
+  struct MachOCorefileImageEntry {
+    std::string filename;
+    lldb_private::UUID uuid;
+    lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
+    bool currently_executing;
+    std::vector<std::tuple<lldb_private::ConstString, lldb::addr_t>>
+        segment_load_addresses;
+  };
+
+  struct LCNoteEntry {
+    LCNoteEntry(uint32_t addr_byte_size, lldb::ByteOrder byte_order)
+        : payload(lldb_private::Stream::eBinary, addr_byte_size, byte_order) {}
+
+    std::string name;
+    lldb::addr_t payload_file_offset = 0;
+    lldb_private::StreamString payload;
+  };
+
+  struct MachOCorefileAllImageInfos {
+    std::vector<MachOCorefileImageEntry> all_image_infos;
+    bool IsValid() { return all_image_infos.size() > 0; }
+  };
+
+  /// Get the list of binary images that were present in the process
+  /// when the corefile was produced.
+  /// \return
+  ///     The MachOCorefileAllImageInfos object returned will have
+  ///     IsValid() == false if the information is unavailable.
+  MachOCorefileAllImageInfos GetCorefileAllImageInfos();
+
   llvm::MachO::mach_header m_header;
   static lldb_private::ConstString GetSegmentNameTEXT();
   static lldb_private::ConstString GetSegmentNameDATA();
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
index 35a823e..cb7bbee 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp
@@ -173,7 +173,7 @@
   if (ec || magic != llvm::file_magic::pdb)
     return nullptr;
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
-      llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
+      llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false,
                                   /*RequiresNullTerminator=*/false);
   if (!ErrorOrBuffer)
     return nullptr;
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 4e2598c..9eb1c25 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -189,7 +189,9 @@
 
 bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
                                 const lldb_private::FileSpec &outfile,
+                                lldb::SaveCoreStyle &core_style,
                                 lldb_private::Status &error) {
+  core_style = eSaveCoreFull;
   return SaveMiniDump(process_sp, outfile, error);
 }
 
@@ -261,7 +263,7 @@
   ::memset(&m_coff_header, 0, sizeof(m_coff_header));
 }
 
-ObjectFilePECOFF::~ObjectFilePECOFF() {}
+ObjectFilePECOFF::~ObjectFilePECOFF() = default;
 
 bool ObjectFilePECOFF::ParseHeader() {
   ModuleSP module_sp(GetModule());
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index fdcacbe..9fe4a13 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -79,6 +79,7 @@
 
   static bool SaveCore(const lldb::ProcessSP &process_sp,
                        const lldb_private::FileSpec &outfile,
+                       lldb::SaveCoreStyle &core_style,
                        lldb_private::Status &error);
 
   static bool MagicBytesMatch(lldb::DataBufferSP &data_sp);
diff --git a/src/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/src/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
index 6c29c23..5272da9 100644
--- a/src/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp
@@ -196,7 +196,7 @@
     m_sect_infos.push_back(section_info{*offset_ptr + c.tell(), section_length,
                                         section_id, *sect_name});
     *offset_ptr += (c.tell() + section_length);
-  } else if (section_id <= llvm::wasm::WASM_SEC_EVENT) {
+  } else if (section_id <= llvm::wasm::WASM_SEC_TAG) {
     m_sect_infos.push_back(section_info{*offset_ptr + c.tell(),
                                         static_cast<uint32_t>(payload_len),
                                         section_id, ConstString()});
diff --git a/src/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/src/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index 4350010..730c88f 100644
--- a/src/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/src/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -91,13 +91,13 @@
     std::string os_plugin_class_name(
         python_module_path.GetFilename().AsCString(""));
     if (!os_plugin_class_name.empty()) {
-      const bool init_session = false;
+      LoadScriptOptions options;
       char python_module_path_cstr[PATH_MAX];
       python_module_path.GetPath(python_module_path_cstr,
                                  sizeof(python_module_path_cstr));
       Status error;
-      if (m_interpreter->LoadScriptingModule(python_module_path_cstr,
-                                             init_session, error)) {
+      if (m_interpreter->LoadScriptingModule(python_module_path_cstr, options,
+                                             error)) {
         // Strip the ".py" extension if there is one
         size_t py_extension_pos = os_plugin_class_name.rfind(".py");
         if (py_extension_pos != std::string::npos)
@@ -115,7 +115,7 @@
   }
 }
 
-OperatingSystemPython::~OperatingSystemPython() {}
+OperatingSystemPython::~OperatingSystemPython() = default;
 
 DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() {
   if (m_register_info_up == nullptr) {
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/Android/AdbClient.cpp b/src/llvm-project/lldb/source/Plugins/Platform/Android/AdbClient.cpp
index ffccd6d..ed2d56f 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/Android/AdbClient.cpp
@@ -24,7 +24,7 @@
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timeout.h"
 
-#include <limits.h>
+#include <climits>
 
 #include <algorithm>
 #include <cstdlib>
@@ -118,11 +118,11 @@
   return error;
 }
 
-AdbClient::AdbClient() {}
+AdbClient::AdbClient() = default;
 
 AdbClient::AdbClient(const std::string &device_id) : m_device_id(device_id) {}
 
-AdbClient::~AdbClient() {}
+AdbClient::~AdbClient() = default;
 
 void AdbClient::SetDeviceID(const std::string &device_id) {
   m_device_id = device_id;
@@ -583,7 +583,7 @@
   return error;
 }
 
-AdbClient::SyncService::~SyncService() {}
+AdbClient::SyncService::~SyncService() = default;
 
 Status AdbClient::SyncService::SendSyncRequest(const char *request_id,
                                                const uint32_t data_len,
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/src/llvm-project/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 6dd5306..77690b4 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -73,7 +73,7 @@
   return error;
 }
 
-PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer() {}
+PlatformAndroidRemoteGDBServer::PlatformAndroidRemoteGDBServer() = default;
 
 PlatformAndroidRemoteGDBServer::~PlatformAndroidRemoteGDBServer() {
   for (const auto &it : m_port_forwards)
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index f4d44eb..7b3d8a3 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -9,7 +9,7 @@
 #include "PlatformFreeBSD.h"
 #include "lldb/Host/Config.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if LLDB_ENABLE_POSIX
 #include <sys/utsname.h>
 #endif
@@ -214,55 +214,9 @@
 #endif
 }
 
-size_t
-PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode(Target &target,
-                                                 BreakpointSite *bp_site) {
-  switch (target.GetArchitecture().GetMachine()) {
-  case llvm::Triple::arm: {
-    lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
-    AddressClass addr_class = AddressClass::eUnknown;
-
-    if (bp_loc_sp) {
-      addr_class = bp_loc_sp->GetAddress().GetAddressClass();
-      if (addr_class == AddressClass::eUnknown &&
-          (bp_loc_sp->GetAddress().GetFileAddress() & 1))
-        addr_class = AddressClass::eCodeAlternateISA;
-    }
-
-    if (addr_class == AddressClass::eCodeAlternateISA) {
-      // TODO: Enable when FreeBSD supports thumb breakpoints.
-      // FreeBSD kernel as of 10.x, does not support thumb breakpoints
-      return 0;
-    }
-
-    static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};
-    size_t trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
-    assert(bp_site);
-    if (bp_site->SetTrapOpcode(g_arm_breakpoint_opcode, trap_opcode_size))
-      return trap_opcode_size;
-  }
-    LLVM_FALLTHROUGH;
-  default:
-    return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);
-  }
-}
-
 bool PlatformFreeBSD::CanDebugProcess() {
   if (IsHost()) {
-    llvm::Triple host_triple{llvm::sys::getProcessTriple()};
-    bool use_legacy_plugin;
-
-    switch (host_triple.getArch()) {
-      case llvm::Triple::x86:
-      case llvm::Triple::x86_64:
-        // FreeBSDRemote plugin supports x86 only at the moment
-        use_legacy_plugin = !!getenv("FREEBSD_LEGACY_PLUGIN");
-        break;
-      default:
-        use_legacy_plugin = true;
-    }
-
-    return !use_legacy_plugin;
+    return true;
   } else {
     // If we're connected, we can debug.
     return IsConnected();
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index c198ea1..4fd10fb 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/src/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -44,9 +44,6 @@
 
   bool CanDebugProcess() override;
 
-  size_t GetSoftwareBreakpointTrapOpcode(Target &target,
-                                         BreakpointSite *bp_site) override;
-
   void CalculateTrapHandlerSymbolNames() override;
 
   MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/src/llvm-project/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 2cb671f..314730c 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -9,7 +9,7 @@
 #include "PlatformLinux.h"
 #include "lldb/Host/Config.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if LLDB_ENABLE_POSIX
 #include <sys/utsname.h>
 #endif
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index 342f7c2..925a3d1 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -50,7 +50,7 @@
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformAppleSimulator::~PlatformAppleSimulator() {}
+PlatformAppleSimulator::~PlatformAppleSimulator() = default;
 
 lldb_private::Status PlatformAppleSimulator::LaunchProcess(
     lldb_private::ProcessLaunchInfo &launch_info) {
@@ -505,6 +505,16 @@
   return process_infos.size();
 }
 
+/// Whether to skip creating a simulator platform.
+static bool shouldSkipSimulatorPlatform(bool force, const ArchSpec *arch) {
+  // If the arch is known not to specify a simulator environment, skip creating
+  // the simulator platform (we can create it later if there's a matching arch).
+  // This avoids very slow xcrun queries for non-simulator archs (the slowness
+  // is due to xcrun not caching negative queries (rdar://74882205)).
+  return !force && arch && arch->IsValid() &&
+         !arch->TripleEnvironmentWasSpecified();
+}
+
 static llvm::StringRef GetXcodeSDKDir(std::string preferred,
                                       std::string secondary) {
   llvm::StringRef sdk;
@@ -530,6 +540,8 @@
   }
 
   static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+    if (shouldSkipSimulatorPlatform(force, arch))
+      return nullptr;
     llvm::StringRef sdk;
     sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("iPhoneSimulator.Internal.sdk"));
     if (sdk.empty())
@@ -578,6 +590,8 @@
   }
 
   static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+    if (shouldSkipSimulatorPlatform(force, arch))
+      return nullptr;
     return PlatformAppleSimulator::CreateInstance(
         "PlatformAppleTVSimulator", g_tvos_description,
         ConstString(g_tvos_plugin_name),
@@ -619,6 +633,8 @@
   }
 
   static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+    if (shouldSkipSimulatorPlatform(force, arch))
+      return nullptr;
     return PlatformAppleSimulator::CreateInstance(
         "PlatformAppleWatchSimulator", g_watchos_description,
         ConstString(g_watchos_plugin_name),
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index f1ca859..51ff2a6 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -8,7 +8,7 @@
 
 #include "PlatformDarwin.h"
 
-#include <string.h>
+#include <cstring>
 
 #include <algorithm>
 #include <memory>
@@ -54,7 +54,7 @@
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformDarwin::~PlatformDarwin() {}
+PlatformDarwin::~PlatformDarwin() = default;
 
 lldb_private::Status
 PlatformDarwin::PutFile(const lldb_private::FileSpec &source,
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 76ce500..ee8850f 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -197,7 +197,7 @@
     m_collection_sp->Initialize(g_platformdarwinkernel_properties);
   }
 
-  virtual ~PlatformDarwinKernelProperties() {}
+  virtual ~PlatformDarwinKernelProperties() = default;
 
   FileSpecList GetKextDirectories() const {
     const uint32_t idx = ePropertyKextDirectories;
@@ -250,7 +250,7 @@
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformDarwinKernel::~PlatformDarwinKernel() {}
+PlatformDarwinKernel::~PlatformDarwinKernel() = default;
 
 void PlatformDarwinKernel::GetStatus(Stream &strm) {
   Platform::GetStatus(strm);
@@ -791,21 +791,6 @@
     return error;
   }
 
-  // Lastly, look through the kext binarys without dSYMs
-  if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle) > 0) {
-    for (BundleIDToKextIterator it =
-             m_name_to_kext_path_map_without_dsyms.begin();
-         it != m_name_to_kext_path_map_without_dsyms.end(); ++it) {
-      if (it->first == kext_bundle) {
-        error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
-                                           module_spec.GetArchitecture(),
-                                           module_sp);
-        if (module_sp.get()) {
-          return error;
-        }
-      }
-    }
-  }
   return error;
 }
 
@@ -884,33 +869,6 @@
     return error;
   }
 
-  // Lastly, try all kernel binaries that don't have a dSYM
-  for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
-    if (FileSystem::Instance().Exists(possible_kernel)) {
-      ModuleSpec kern_spec(possible_kernel);
-      kern_spec.GetUUID() = module_spec.GetUUID();
-      module_sp.reset(new Module(kern_spec));
-      if (module_sp && module_sp->GetObjectFile() &&
-          module_sp->MatchesModuleSpec(kern_spec)) {
-        // module_sp is an actual kernel binary we want to add.
-        if (process) {
-          process->GetTarget().GetImages().AppendIfNeeded(module_sp);
-          error.Clear();
-          return error;
-        } else {
-          error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr,
-                                              nullptr, nullptr);
-          if (module_sp && module_sp->GetObjectFile() &&
-              module_sp->GetObjectFile()->GetType() !=
-                  ObjectFile::Type::eTypeCoreFile) {
-            return error;
-          }
-          module_sp.reset();
-        }
-      }
-    }
-  }
-
   return error;
 }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
index 8a11f40..79cbd1c 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -39,15 +39,13 @@
 PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
     : PlatformDarwin(false), // This is a remote platform
       m_sdk_directory_infos(), m_device_support_directory(),
-      m_device_support_directory_for_os_version(), m_build_update(),
-      m_last_module_sdk_idx(UINT32_MAX),
-      m_connected_module_sdk_idx(UINT32_MAX) {}
+      m_device_support_directory_for_os_version(), m_build_update() {}
 
 /// Destructor.
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
+PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() = default;
 
 void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
   Platform::GetStatus(strm);
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
index 6f6ede7..3b578a3 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
@@ -64,8 +64,8 @@
   std::string m_device_support_directory;
   std::string m_device_support_directory_for_os_version;
   std::string m_build_update;
-  uint32_t m_last_module_sdk_idx;
-  uint32_t m_connected_module_sdk_idx;
+  uint32_t m_last_module_sdk_idx = UINT32_MAX;
+  uint32_t m_connected_module_sdk_idx = UINT32_MAX;
 
   bool UpdateSDKDirectoryInfosIfNeeded();
 
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
index 5104e48..a35efd5 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
@@ -93,7 +93,7 @@
   ProductFamilyID GetProductFamilyID();
 
 private:
-  id m_dev;
+  id m_dev = nullptr;
   llvm::Optional<ModelIdentifier> m_model_identifier;
 };
 
@@ -129,7 +129,7 @@
   bool IsAvailable();
 
 private:
-  id m_dev;
+  id m_dev = nullptr;
   llvm::Optional<OSVersion> m_os_version;
 };
 
@@ -169,7 +169,7 @@
   Process Spawn(lldb_private::ProcessLaunchInfo &launch_info);
 
 private:
-  id m_dev;
+  id m_dev = nullptr;
   llvm::Optional<DeviceType> m_dev_type;
   llvm::Optional<DeviceRuntime> m_dev_runtime;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 66fe569..91d6252 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/src/llvm-project/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -66,8 +66,7 @@
 CoreSimulatorSupport::Process::Process(lldb::pid_t p, Status error)
     : m_pid(p), m_error(error) {}
 
-CoreSimulatorSupport::DeviceType::DeviceType()
-    : m_dev(nil), m_model_identifier() {}
+CoreSimulatorSupport::DeviceType::DeviceType() : m_model_identifier() {}
 
 CoreSimulatorSupport::DeviceType::DeviceType(id d)
     : m_dev(d), m_model_identifier() {}
@@ -87,8 +86,7 @@
   return ProductFamilyID([m_dev productFamilyID]);
 }
 
-CoreSimulatorSupport::DeviceRuntime::DeviceRuntime()
-    : m_dev(nil), m_os_version() {}
+CoreSimulatorSupport::DeviceRuntime::DeviceRuntime() : m_os_version() {}
 
 CoreSimulatorSupport::DeviceRuntime::DeviceRuntime(id d)
     : m_dev(d), m_os_version() {}
@@ -99,8 +97,7 @@
   return [m_dev available];
 }
 
-CoreSimulatorSupport::Device::Device()
-    : m_dev(nil), m_dev_type(), m_dev_runtime() {}
+CoreSimulatorSupport::Device::Device() : m_dev_type(), m_dev_runtime() {}
 
 CoreSimulatorSupport::Device::Device(id d)
     : m_dev(d), m_dev_type(), m_dev_runtime() {}
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/src/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index a5d73c9..e3682b4 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -9,7 +9,7 @@
 #include "PlatformNetBSD.h"
 #include "lldb/Host/Config.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if LLDB_ENABLE_POSIX
 #include <sys/utsname.h>
 #endif
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/src/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index 2cd024f..012b688 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -9,7 +9,7 @@
 #include "PlatformOpenBSD.h"
 #include "lldb/Host/Config.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if LLDB_ENABLE_POSIX
 #include <sys/utsname.h>
 #endif
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 3628b0a..7353132 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -46,7 +46,7 @@
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformPOSIX::~PlatformPOSIX() {}
+PlatformPOSIX::~PlatformPOSIX() = default;
 
 lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
     lldb_private::CommandInterpreter &interpreter) {
@@ -578,7 +578,19 @@
   // __lldb_dlopen_result for consistency. The wrapper returns a void * but
   // doesn't use it because UtilityFunctions don't work with void returns at
   // present.
+  //
+  // Use lazy binding so as to not make dlopen()'s success conditional on
+  // forcing every symbol in the library.
+  //
+  // In general, the debugger should allow programs to load & run with
+  // libraries as far as they can, instead of defaulting to being super-picky
+  // about unavailable symbols.
+  //
+  // The value "1" appears to imply lazy binding (RTLD_LAZY) on both Darwin
+  // and other POSIX OSes.
   static const char *dlopen_wrapper_code = R"(
+  const int RTLD_LAZY = 1;
+
   struct __lldb_dlopen_result {
     void *image_ptr;
     const char *error_str;
@@ -595,7 +607,7 @@
   {
     // This is the case where the name is the full path:
     if (!path_strings) {
-      result_ptr->image_ptr = dlopen(name, 2);
+      result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
       if (result_ptr->image_ptr)
         result_ptr->error_str = nullptr;
       return nullptr;
@@ -609,7 +621,7 @@
       buffer[path_len] = '/';
       char *target_ptr = buffer+path_len+1; 
       memcpy((void *) target_ptr, (void *) name, name_len + 1);
-      result_ptr->image_ptr = dlopen(buffer, 2);
+      result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
       if (result_ptr->image_ptr) {
         result_ptr->error_str = nullptr;
         break;
@@ -659,7 +671,7 @@
   // We are passing four arguments, the basename, the list of places to look,
   // a buffer big enough for all the path + name combos, and
   // a pointer to the storage we've made for the result:
-  value.SetValueType(Value::eValueTypeScalar);
+  value.SetValueType(Value::ValueType::Scalar);
   value.SetCompilerType(clang_void_pointer_type);
   arguments.PushValue(value);
   value.SetCompilerType(clang_char_pointer_type);
@@ -994,13 +1006,6 @@
              )";
 }
 
-size_t PlatformPOSIX::ConnectToWaitingProcesses(Debugger &debugger,
-                                                Status &error) {
-  if (m_remote_platform_sp)
-    return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
-  return Platform::ConnectToWaitingProcesses(debugger, error);
-}
-
 ConstString PlatformPOSIX::GetFullNameForDylib(ConstString basename) {
   if (basename.IsEmpty())
     return basename;
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 72c54f4..1cba4c5 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/src/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -71,9 +71,6 @@
   lldb_private::Status UnloadImage(lldb_private::Process *process,
                                    uint32_t image_token) override;
 
-  size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger,
-                                   lldb_private::Status &error) override;
-
   lldb_private::ConstString GetFullNameForDylib(lldb_private::ConstString basename) override;
 
 protected:
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/src/llvm-project/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 3527fb1..fd28eec 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -8,7 +8,7 @@
 
 #include "PlatformWindows.h"
 
-#include <stdio.h>
+#include <cstdio>
 #if defined(_WIN32)
 #include "lldb/Host/windows/windows.h"
 #include <winsock2.h>
diff --git a/src/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/src/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 6a4275d..5282086 100644
--- a/src/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -30,6 +30,7 @@
 #include "lldb/Utility/UriParser.h"
 
 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -202,13 +203,16 @@
 /// Default Constructor
 PlatformRemoteGDBServer::PlatformRemoteGDBServer()
     : Platform(false), // This is a remote platform
-      m_gdb_client() {}
+      m_gdb_client() {
+  m_gdb_client.SetPacketTimeout(
+      process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
+}
 
 /// Destructor.
 ///
 /// The destructor is virtual since this class is designed to be
 /// inherited from by the plug-in instance.
-PlatformRemoteGDBServer::~PlatformRemoteGDBServer() {}
+PlatformRemoteGDBServer::~PlatformRemoteGDBServer() = default;
 
 bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx,
                                                               ArchSpec &arch) {
@@ -736,8 +740,8 @@
   m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture());
 
   StringExtractorGDBRemote response;
-  auto result = m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo",
-                                                          response, false);
+  auto result =
+      m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
 
   if (result != decltype(result)::Success ||
       response.GetResponseType() != response.eResponse)
@@ -839,7 +843,7 @@
   GetPendingGdbServerList(connection_urls);
 
   for (size_t i = 0; i < connection_urls.size(); ++i) {
-    ConnectProcess(connection_urls[i].c_str(), "", debugger, nullptr, error);
+    ConnectProcess(connection_urls[i].c_str(), "gdb-remote", debugger, nullptr, error);
     if (error.Fail())
       return i; // We already connected to i process succsessfully
   }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/CMakeLists.txt
index 91f20ec..bea5bac 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Process/CMakeLists.txt
@@ -2,7 +2,6 @@
   add_subdirectory(Linux)
   add_subdirectory(POSIX)
 elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
-  add_subdirectory(FreeBSDRemote)
   add_subdirectory(FreeBSD)
   add_subdirectory(POSIX)
 elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
@@ -13,6 +12,7 @@
 elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
   add_subdirectory(MacOSX-Kernel)
 endif()
+add_subdirectory(scripted)
 add_subdirectory(gdb-remote)
 add_subdirectory(Utility)
 add_subdirectory(elf-core)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt
index c8301f3..598911c 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt
@@ -1,24 +1,20 @@
-add_lldb_library(lldbPluginProcessFreeBSD PLUGIN
-  ProcessFreeBSD.cpp
-  FreeBSDThread.cpp
-  ProcessMonitor.cpp
-
-  POSIXStopInfo.cpp
-  RegisterContextPOSIXProcessMonitor_arm.cpp
-  RegisterContextPOSIXProcessMonitor_arm64.cpp
-  RegisterContextPOSIXProcessMonitor_powerpc.cpp
-  RegisterContextPOSIXProcessMonitor_x86.cpp
-  RegisterContextPOSIXProcessMonitor_mips64.cpp
+add_lldb_library(lldbPluginProcessFreeBSD
+  NativeProcessFreeBSD.cpp
+  NativeRegisterContextFreeBSD.cpp
+  NativeRegisterContextFreeBSD_arm.cpp
+  NativeRegisterContextFreeBSD_arm64.cpp
+  NativeRegisterContextFreeBSD_mips64.cpp
+  NativeRegisterContextFreeBSD_powerpc.cpp
+  NativeRegisterContextFreeBSD_x86_64.cpp
+  NativeThreadFreeBSD.cpp
 
   LINK_LIBS
-    lldbBreakpoint
-    lldbCore
     lldbHost
     lldbSymbol
     lldbTarget
     lldbUtility
-    lldbPluginProcessUtility
     lldbPluginProcessPOSIX
+    lldbPluginProcessUtility
   LINK_COMPONENTS
     Support
   )
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
deleted file mode 100644
index 3accc9c..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-//===-- FreeBSDThread.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 <errno.h>
-#include <pthread.h>
-#include <pthread_np.h>
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/user.h>
-
-#include "FreeBSDThread.h"
-#include "POSIXStopInfo.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/HostNativeThread.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadSpec.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Utility/State.h"
-#include "llvm/ADT/SmallString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
-    : Thread(process, tid), m_frame_up(), m_breakpoint(),
-      m_thread_name_valid(false), m_thread_name(), m_posix_thread(nullptr) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-  LLDB_LOGV(log, "tid = {0}", tid);
-
-  // Set the current watchpoints for this thread.
-  Target &target = GetProcess()->GetTarget();
-  const WatchpointList &wp_list = target.GetWatchpointList();
-  size_t wp_size = wp_list.GetSize();
-
-  for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) {
-    lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx);
-    if (wp.get() && wp->IsEnabled()) {
-      // This watchpoint as been enabled; obviously this "new" thread has been
-      // created since that watchpoint was enabled.  Since the
-      // POSIXBreakpointProtocol has yet to be initialized, its
-      // m_watchpoints_initialized member will be FALSE.  Attempting to read
-      // the debug status register to determine if a watchpoint has been hit
-      // would result in the zeroing of that register. Since the active debug
-      // registers would have been cloned when this thread was created, simply
-      // force the m_watchpoints_initized member to TRUE and avoid resetting
-      // dr6 and dr7.
-      GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized();
-    }
-  }
-}
-
-FreeBSDThread::~FreeBSDThread() { DestroyThread(); }
-
-ProcessMonitor &FreeBSDThread::GetMonitor() {
-  ProcessSP base = GetProcess();
-  ProcessFreeBSD &process = static_cast<ProcessFreeBSD &>(*base);
-  return process.GetMonitor();
-}
-
-void FreeBSDThread::RefreshStateAfterStop() {
-  // Invalidate all registers in our register context. We don't set "force" to
-  // true because the stop reply packet might have had some register values
-  // that were expedited and these will already be copied into the register
-  // context by the time this function gets called. The KDPRegisterContext
-  // class has been made smart enough to detect when it needs to invalidate
-  // which registers are valid by putting hooks in the register read and
-  // register supply functions where they check the process stop ID and do the
-  // right thing. if (StateIsStoppedState(GetState())
-  {
-    const bool force = false;
-    GetRegisterContext()->InvalidateIfNeeded(force);
-  }
-}
-
-const char *FreeBSDThread::GetInfo() { return nullptr; }
-
-void FreeBSDThread::SetName(const char *name) {
-  m_thread_name_valid = (name && name[0]);
-  if (m_thread_name_valid)
-    m_thread_name.assign(name);
-  else
-    m_thread_name.clear();
-}
-
-const char *FreeBSDThread::GetName() {
-  if (!m_thread_name_valid) {
-    m_thread_name.clear();
-    int pid = GetProcess()->GetID();
-
-    struct kinfo_proc *kp = nullptr, *nkp;
-    size_t len = 0;
-    int error;
-    int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
-                  pid};
-
-    while (1) {
-      error = sysctl(ctl, 4, kp, &len, nullptr, 0);
-      if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
-        // Add extra space in case threads are added before next call.
-        len += sizeof(*kp) + len / 10;
-        nkp = (struct kinfo_proc *)realloc(kp, len);
-        if (nkp == nullptr) {
-          free(kp);
-          return nullptr;
-        }
-        kp = nkp;
-        continue;
-      }
-      if (error != 0)
-        len = 0;
-      break;
-    }
-
-    for (size_t i = 0; i < len / sizeof(*kp); i++) {
-      if (kp[i].ki_tid == (lwpid_t)GetID()) {
-        m_thread_name.append(kp[i].ki_tdname,
-                             kp[i].ki_tdname + strlen(kp[i].ki_tdname));
-        break;
-      }
-    }
-    free(kp);
-    m_thread_name_valid = true;
-  }
-
-  if (m_thread_name.empty())
-    return nullptr;
-  return m_thread_name.c_str();
-}
-
-lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
-  if (!m_reg_context_sp) {
-    m_posix_thread = nullptr;
-
-    RegisterInfoInterface *reg_interface = nullptr;
-    const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
-
-    assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD);
-    switch (target_arch.GetMachine()) {
-    case llvm::Triple::aarch64:
-    case llvm::Triple::arm:
-      break;
-    case llvm::Triple::ppc:
-#ifndef __powerpc64__
-      reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
-      break;
-#endif
-    case llvm::Triple::ppc64:
-      reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
-      break;
-    case llvm::Triple::mips64:
-      reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
-      break;
-    case llvm::Triple::x86:
-      reg_interface = new RegisterContextFreeBSD_i386(target_arch);
-      break;
-    case llvm::Triple::x86_64:
-      reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
-      break;
-    default:
-      llvm_unreachable("CPU not supported");
-    }
-
-    switch (target_arch.GetMachine()) {
-    case llvm::Triple::aarch64: {
-      RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
-          new RegisterContextPOSIXProcessMonitor_arm64(
-              *this, std::make_unique<RegisterInfoPOSIX_arm64>(target_arch));
-      m_posix_thread = reg_ctx;
-      m_reg_context_sp.reset(reg_ctx);
-      break;
-    }
-    case llvm::Triple::arm: {
-      RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
-          new RegisterContextPOSIXProcessMonitor_arm(
-              *this, std::make_unique<RegisterInfoPOSIX_arm>(target_arch));
-      m_posix_thread = reg_ctx;
-      m_reg_context_sp.reset(reg_ctx);
-      break;
-    }
-    case llvm::Triple::mips64: {
-      RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
-          new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
-                                                        reg_interface);
-      m_posix_thread = reg_ctx;
-      m_reg_context_sp.reset(reg_ctx);
-      break;
-    }
-    case llvm::Triple::ppc:
-    case llvm::Triple::ppc64: {
-      RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
-          new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
-                                                         reg_interface);
-      m_posix_thread = reg_ctx;
-      m_reg_context_sp.reset(reg_ctx);
-      break;
-    }
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64: {
-      RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
-          new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
-                                                        reg_interface);
-      m_posix_thread = reg_ctx;
-      m_reg_context_sp.reset(reg_ctx);
-      break;
-    }
-    default:
-      break;
-    }
-  }
-  return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
-  lldb::RegisterContextSP reg_ctx_sp;
-  uint32_t concrete_frame_idx = 0;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-  LLDB_LOGV(log, "called");
-
-  if (frame)
-    concrete_frame_idx = frame->GetConcreteFrameIndex();
-
-  if (concrete_frame_idx == 0)
-    reg_ctx_sp = GetRegisterContext();
-  else {
-    reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
-  }
-
-  return reg_ctx_sp;
-}
-
-lldb::addr_t FreeBSDThread::GetThreadPointer() {
-  ProcessMonitor &monitor = GetMonitor();
-  addr_t addr;
-  if (monitor.ReadThreadPointer(GetID(), addr))
-    return addr;
-  else
-    return LLDB_INVALID_ADDRESS;
-}
-
-bool FreeBSDThread::CalculateStopInfo() {
-  SetStopInfo(m_stop_info_sp);
-  return true;
-}
-
-void FreeBSDThread::DidStop() {
-  // Don't set the thread state to stopped unless we really stopped.
-}
-
-void FreeBSDThread::WillResume(lldb::StateType resume_state) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-  LLDB_LOGF(log, "tid %lu resume_state = %s", GetID(),
-            lldb_private::StateAsCString(resume_state));
-  ProcessSP process_sp(GetProcess());
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
-  int signo = GetResumeSignal();
-  bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
-
-  switch (resume_state) {
-  case eStateSuspended:
-  case eStateStopped:
-    process->m_suspend_tids.push_back(GetID());
-    break;
-  case eStateRunning:
-    process->m_run_tids.push_back(GetID());
-    if (signo_valid)
-      process->m_resume_signo = signo;
-    break;
-  case eStateStepping:
-    process->m_step_tids.push_back(GetID());
-    if (signo_valid)
-      process->m_resume_signo = signo;
-    break;
-  default:
-    break;
-  }
-}
-
-bool FreeBSDThread::Resume() {
-  lldb::StateType resume_state = GetResumeState();
-  ProcessMonitor &monitor = GetMonitor();
-  bool status;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-  LLDB_LOGF(log, "FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
-            StateAsCString(resume_state));
-
-  switch (resume_state) {
-  default:
-    assert(false && "Unexpected state for resume!");
-    status = false;
-    break;
-
-  case lldb::eStateRunning:
-    SetState(resume_state);
-    status = monitor.Resume(GetID(), GetResumeSignal());
-    break;
-
-  case lldb::eStateStepping:
-    SetState(resume_state);
-    status = monitor.SingleStep(GetID(), GetResumeSignal());
-    break;
-  case lldb::eStateStopped:
-  case lldb::eStateSuspended:
-    status = true;
-    break;
-  }
-
-  return status;
-}
-
-void FreeBSDThread::Notify(const ProcessMessage &message) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-  LLDB_LOGF(log, "FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
-            __FUNCTION__, message.PrintKind(), GetID());
-
-  switch (message.GetKind()) {
-  default:
-    assert(false && "Unexpected message kind!");
-    break;
-
-  case ProcessMessage::eExitMessage:
-    // Nothing to be done.
-    break;
-
-  case ProcessMessage::eLimboMessage:
-    LimboNotify(message);
-    break;
-
-  case ProcessMessage::eCrashMessage:
-  case ProcessMessage::eSignalMessage:
-    SignalNotify(message);
-    break;
-
-  case ProcessMessage::eSignalDeliveredMessage:
-    SignalDeliveredNotify(message);
-    break;
-
-  case ProcessMessage::eTraceMessage:
-    TraceNotify(message);
-    break;
-
-  case ProcessMessage::eBreakpointMessage:
-    BreakNotify(message);
-    break;
-
-  case ProcessMessage::eWatchpointMessage:
-    WatchNotify(message);
-    break;
-
-  case ProcessMessage::eExecMessage:
-    ExecNotify(message);
-    break;
-  }
-}
-
-bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
-  bool wp_set = false;
-  if (wp) {
-    addr_t wp_addr = wp->GetLoadAddress();
-    size_t wp_size = wp->GetByteSize();
-    bool wp_read = wp->WatchpointRead();
-    bool wp_write = wp->WatchpointWrite();
-    uint32_t wp_hw_index = wp->GetHardwareIndex();
-    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
-    if (reg_ctx)
-      wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
-          wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
-  }
-  return wp_set;
-}
-
-bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
-  bool result = false;
-  if (wp) {
-    lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
-    if (reg_ctx_sp.get())
-      result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
-  }
-  return result;
-}
-
-uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
-  lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
-  if (reg_ctx_sp.get())
-    return reg_ctx_sp->NumSupportedHardwareWatchpoints();
-  return 0;
-}
-
-uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
-  uint32_t hw_index = LLDB_INVALID_INDEX32;
-  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
-  uint32_t wp_idx;
-  POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
-  if (reg_ctx) {
-    for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
-      if (reg_ctx->IsWatchpointVacant(wp_idx)) {
-        hw_index = wp_idx;
-        break;
-      }
-    }
-  }
-  return hw_index;
-}
-
-void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
-  bool status;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
-  assert(GetRegisterContext());
-  status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
-  assert(status && "Breakpoint update failed!");
-
-  // With our register state restored, resolve the breakpoint object
-  // corresponding to our current PC.
-  assert(GetRegisterContext());
-  lldb::addr_t pc = GetRegisterContext()->GetPC();
-  LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
-  lldb::BreakpointSiteSP bp_site(
-      GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
-  // If the breakpoint is for this thread, then we'll report the hit, but if it
-  // is for another thread, we create a stop reason with should_stop=false.  If
-  // there is no breakpoint location, then report an invalid stop reason. We
-  // don't need to worry about stepping over the breakpoint here, that will be
-  // taken care of when the thread resumes and notices that there's a
-  // breakpoint under the pc.
-  if (bp_site) {
-    lldb::break_id_t bp_id = bp_site->GetID();
-    // If we have an operating system plug-in, we might have set a thread
-    // specific breakpoint using the operating system thread ID, so we can't
-    // make any assumptions about the thread ID so we must always report the
-    // breakpoint regardless of the thread.
-    if (bp_site->ValidForThisThread(this) ||
-        GetProcess()->GetOperatingSystem() != nullptr)
-      SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
-    else {
-      const bool should_stop = false;
-      SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
-                                                                 should_stop));
-    }
-  } else
-    SetStopInfo(StopInfoSP());
-}
-
-void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
-  lldb::addr_t halt_addr = message.GetHWAddress();
-  LLDB_LOGF(log,
-            "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
-            __FUNCTION__, halt_addr);
-
-  POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
-  if (reg_ctx) {
-    uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
-    uint32_t wp_idx;
-    for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
-      if (reg_ctx->IsWatchpointHit(wp_idx)) {
-        // Clear the watchpoint hit here
-        reg_ctx->ClearWatchpointHits();
-        break;
-      }
-    }
-
-    if (wp_idx == num_hw_wps)
-      return;
-
-    Target &target = GetProcess()->GetTarget();
-    lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
-    const WatchpointList &wp_list = target.GetWatchpointList();
-    lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
-
-    assert(wp_sp.get() && "No watchpoint found");
-    SetStopInfo(
-        StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
-  }
-}
-
-void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
-
-  // Try to resolve the breakpoint object corresponding to the current PC.
-  assert(GetRegisterContext());
-  lldb::addr_t pc = GetRegisterContext()->GetPC();
-  LLDB_LOGF(log, "FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
-  lldb::BreakpointSiteSP bp_site(
-      GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
-
-  // If the current pc is a breakpoint site then set the StopInfo to
-  // Breakpoint. Otherwise, set the StopInfo to Watchpoint or Trace. If we have
-  // an operating system plug-in, we might have set a thread specific
-  // breakpoint using the operating system thread ID, so we can't make any
-  // assumptions about the thread ID so we must always report the breakpoint
-  // regardless of the thread.
-  if (bp_site && (bp_site->ValidForThisThread(this) ||
-                  GetProcess()->GetOperatingSystem() != nullptr))
-    SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
-        *this, bp_site->GetID()));
-  else {
-    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
-    if (reg_ctx) {
-      uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
-      uint32_t wp_idx;
-      for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
-        if (reg_ctx->IsWatchpointHit(wp_idx)) {
-          WatchNotify(message);
-          return;
-        }
-      }
-    }
-    SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
-  }
-}
-
-void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
-  SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
-}
-
-void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
-  int signo = message.GetSignal();
-  if (message.GetKind() == ProcessMessage::eCrashMessage) {
-    std::string stop_description = GetCrashReasonString(
-        message.GetCrashReason(), message.GetFaultAddress());
-    SetStopInfo(StopInfo::CreateStopReasonWithSignal(
-        *this, signo, stop_description.c_str()));
-  } else {
-    SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
-  }
-}
-
-void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
-  int signo = message.GetSignal();
-  SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
-}
-
-unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
-  unsigned reg = LLDB_INVALID_REGNUM;
-  ArchSpec arch = HostInfo::GetArchitecture();
-
-  switch (arch.GetMachine()) {
-  default:
-    llvm_unreachable("CPU type not supported!");
-    break;
-
-  case llvm::Triple::aarch64:
-  case llvm::Triple::arm:
-  case llvm::Triple::mips64:
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64: {
-    POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
-    reg = reg_ctx->GetRegisterIndexFromOffset(offset);
-  } break;
-  }
-  return reg;
-}
-
-void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
-  SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
-}
-
-const char *FreeBSDThread::GetRegisterName(unsigned reg) {
-  const char *name = nullptr;
-  ArchSpec arch = HostInfo::GetArchitecture();
-
-  switch (arch.GetMachine()) {
-  default:
-    assert(false && "CPU type not supported!");
-    break;
-
-  case llvm::Triple::aarch64:
-  case llvm::Triple::arm:
-  case llvm::Triple::mips64:
-  case llvm::Triple::ppc:
-  case llvm::Triple::ppc64:
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    name = GetRegisterContext()->GetRegisterName(reg);
-    break;
-  }
-  return name;
-}
-
-const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
-  return GetRegisterName(GetRegisterIndexFromOffset(offset));
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
deleted file mode 100644
index 774ffb5..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ /dev/null
@@ -1,111 +0,0 @@
-//===-- FreeBSDThread.h -----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_FreeBSDThread_H_
-#define liblldb_FreeBSDThread_H_
-
-#include <memory>
-#include <string>
-
-#include "RegisterContextPOSIX.h"
-#include "lldb/Target/Thread.h"
-
-class ProcessMessage;
-class ProcessMonitor;
-class POSIXBreakpointProtocol;
-
-// @class FreeBSDThread
-// Abstraction of a FreeBSD thread.
-class FreeBSDThread : public lldb_private::Thread {
-public:
-  // Constructors and destructors
-  FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
-
-  virtual ~FreeBSDThread();
-
-  // POSIXThread
-  void RefreshStateAfterStop() override;
-
-  // This notifies the thread when a private stop occurs.
-  void DidStop() override;
-
-  const char *GetInfo() override;
-
-  void SetName(const char *name) override;
-
-  const char *GetName() override;
-
-  lldb::RegisterContextSP GetRegisterContext() override;
-
-  lldb::RegisterContextSP
-  CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
-  lldb::addr_t GetThreadPointer() override;
-
-  // These functions provide a mapping from the register offset
-  // back to the register index or name for use in debugging or log
-  // output.
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset);
-
-  const char *GetRegisterName(unsigned reg);
-
-  const char *GetRegisterNameFromOffset(unsigned offset);
-
-  // These methods form a specialized interface to POSIX threads.
-  //
-  bool Resume();
-
-  void Notify(const ProcessMessage &message);
-
-  // These methods provide an interface to watchpoints
-  //
-  bool EnableHardwareWatchpoint(lldb_private::Watchpoint *wp);
-
-  bool DisableHardwareWatchpoint(lldb_private::Watchpoint *wp);
-
-  uint32_t NumSupportedHardwareWatchpoints();
-
-  uint32_t FindVacantWatchpointIndex();
-
-protected:
-  POSIXBreakpointProtocol *GetPOSIXBreakpointProtocol() {
-    if (!m_reg_context_sp)
-      m_reg_context_sp = GetRegisterContext();
-    return m_posix_thread;
-  }
-
-  std::unique_ptr<lldb_private::StackFrame> m_frame_up;
-
-  lldb::BreakpointSiteSP m_breakpoint;
-
-  bool m_thread_name_valid;
-  std::string m_thread_name;
-  POSIXBreakpointProtocol *m_posix_thread;
-
-  ProcessMonitor &GetMonitor();
-
-  bool CalculateStopInfo() override;
-
-  void BreakNotify(const ProcessMessage &message);
-  void WatchNotify(const ProcessMessage &message);
-  virtual void TraceNotify(const ProcessMessage &message);
-  void LimboNotify(const ProcessMessage &message);
-  void SignalNotify(const ProcessMessage &message);
-  void SignalDeliveredNotify(const ProcessMessage &message);
-  void CrashNotify(const ProcessMessage &message);
-  void ExitNotify(const ProcessMessage &message);
-  void ExecNotify(const ProcessMessage &message);
-
-  // FreeBSDThread internal API.
-
-  // POSIXThread override
-  virtual void WillResume(lldb::StateType resume_state) override;
-};
-
-#endif // #ifndef liblldb_FreeBSDThread_H_
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
similarity index 84%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index 163093c..d6426b3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -128,13 +128,20 @@
   return std::move(process_up);
 }
 
+NativeProcessFreeBSD::Extension
+NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
+  return Extension::multiprocess | Extension::fork | Extension::vfork |
+         Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+}
+
 // Public Instance Methods
 
 NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd,
                                            NativeDelegate &delegate,
                                            const ArchSpec &arch,
                                            MainLoop &mainloop)
-    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+      m_main_loop(mainloop) {
   if (m_terminal_fd != -1) {
     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
     assert(status.Success());
@@ -213,8 +220,9 @@
       llvm::Error error = t.CopyWatchpointsFrom(
           static_cast<NativeThreadFreeBSD &>(*GetCurrentThread()));
       if (error) {
-        LLDB_LOG(log, "failed to copy watchpoints to new thread {0}: {1}",
-                 info.pl_lwpid, llvm::toString(std::move(error)));
+        LLDB_LOG_ERROR(log, std::move(error),
+                       "failed to copy watchpoints to new thread {1}: {0}",
+                       info.pl_lwpid);
         SetState(StateType::eStateInvalid);
         return;
       }
@@ -257,6 +265,26 @@
                info.pl_lwpid);
   }
 
+  if (info.pl_flags & PL_FLAG_FORKED) {
+    assert(thread);
+    MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
+    return;
+  }
+
+  if (info.pl_flags & PL_FLAG_VFORK_DONE) {
+    assert(thread);
+    if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+      thread->SetStoppedByVForkDone();
+      SetState(StateType::eStateStopped, true);
+    } else {
+      Status error =
+          PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+      if (error.Fail())
+        SetState(StateType::eStateInvalid);
+    }
+    return;
+  }
+
   if (info.pl_flags & PL_FLAG_SI) {
     assert(info.pl_siginfo.si_signo == SIGTRAP);
     LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
@@ -264,19 +292,35 @@
 
     switch (info.pl_siginfo.si_code) {
     case TRAP_BRKPT:
+      LLDB_LOG(log, "SIGTRAP/TRAP_BRKPT: si_addr: {0}",
+               info.pl_siginfo.si_addr);
+
       if (thread) {
-        thread->SetStoppedByBreakpoint();
+        auto thread_info =
+            m_threads_stepping_with_breakpoint.find(thread->GetID());
+        if (thread_info != m_threads_stepping_with_breakpoint.end()) {
+          thread->SetStoppedByTrace();
+          Status brkpt_error = RemoveBreakpoint(thread_info->second);
+          if (brkpt_error.Fail())
+            LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}",
+                     thread_info->first, brkpt_error);
+          m_threads_stepping_with_breakpoint.erase(thread_info);
+        } else
+          thread->SetStoppedByBreakpoint();
         FixupBreakpointPCAsNeeded(*thread);
       }
       SetState(StateType::eStateStopped, true);
       return;
     case TRAP_TRACE:
+      LLDB_LOG(log, "SIGTRAP/TRAP_TRACE: si_addr: {0}",
+               info.pl_siginfo.si_addr);
+
       if (thread) {
         auto &regctx = static_cast<NativeRegisterContextFreeBSD &>(
             thread->GetRegisterContext());
         uint32_t wp_index = LLDB_INVALID_INDEX32;
-        Status error =
-            regctx.GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
+        Status error = regctx.GetWatchpointHitIndex(
+            wp_index, reinterpret_cast<uintptr_t>(info.pl_siginfo.si_addr));
         if (error.Fail())
           LLDB_LOG(log,
                    "received error while checking for watchpoint hits, pid = "
@@ -354,6 +398,27 @@
   return error;
 }
 
+llvm::Expected<llvm::ArrayRef<uint8_t>>
+NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
+  static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
+  static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
+
+  switch (GetArchitecture().GetMachine()) {
+  case llvm::Triple::arm:
+    switch (size_hint) {
+    case 2:
+      return llvm::makeArrayRef(g_thumb_opcode);
+    case 4:
+      return llvm::makeArrayRef(g_arm_opcode);
+    default:
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "Unrecognised trap opcode size hint!");
+    }
+  default:
+    return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
+  }
+}
+
 Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
   LLDB_LOG(log, "pid {0}", GetID());
@@ -623,9 +688,8 @@
 Status NativeProcessFreeBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
                                            bool hardware) {
   if (hardware)
-    return Status("NativeProcessFreeBSD does not support hardware breakpoints");
-  else
-    return SetSoftwareBreakpoint(addr, size);
+    return SetHardwareBreakpoint(addr, size);
+  return SetSoftwareBreakpoint(addr, size);
 }
 
 Status NativeProcessFreeBSD::GetLoadedModuleFileSpec(const char *module_path,
@@ -668,17 +732,17 @@
 
 void NativeProcessFreeBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  // Process all pending waitpid notifications.
   int status;
   ::pid_t wait_pid =
       llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
 
   if (wait_pid == 0)
-    return; // We are done.
+    return;
 
   if (wait_pid == -1) {
     Status error(errno, eErrorTypePOSIX);
     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+    return;
   }
 
   WaitStatus wait_status = WaitStatus::Decode(status);
@@ -848,7 +912,7 @@
       PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
-  events |= PTRACE_LWP;
+  events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
   status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
@@ -878,3 +942,70 @@
 
   return error;
 }
+
+bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
+  return !m_arch.IsMIPS();
+}
+
+void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+                                        NativeThreadFreeBSD &parent_thread) {
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+  LLDB_LOG(log, "fork, child_pid={0}", child_pid);
+
+  int status;
+  ::pid_t wait_pid =
+      llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
+  if (wait_pid != child_pid) {
+    LLDB_LOG(log,
+             "waiting for pid {0} failed. Assuming the pid has "
+             "disappeared in the meantime",
+             child_pid);
+    return;
+  }
+  if (WIFEXITED(status)) {
+    LLDB_LOG(log,
+             "waiting for pid {0} returned an 'exited' event. Not "
+             "tracking it.",
+             child_pid);
+    return;
+  }
+
+  struct ptrace_lwpinfo info;
+  const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info));
+  if (siginfo_err.Fail()) {
+    LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+    return;
+  }
+  assert(info.pl_event == PL_EVENT_SIGNAL);
+  lldb::tid_t child_tid = info.pl_lwpid;
+
+  std::unique_ptr<NativeProcessFreeBSD> child_process{
+      new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
+                               m_delegate, m_arch, m_main_loop)};
+  if (!is_vfork)
+    child_process->m_software_breakpoints = m_software_breakpoints;
+
+  Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+  if ((m_enabled_extensions & expected_ext) == expected_ext) {
+    child_process->SetupTrace();
+    for (const auto &thread : child_process->m_threads)
+      static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+    child_process->SetState(StateType::eStateStopped, false);
+
+    m_delegate.NewSubprocess(this, std::move(child_process));
+    if (is_vfork)
+      parent_thread.SetStoppedByVFork(child_pid, child_tid);
+    else
+      parent_thread.SetStoppedByFork(child_pid, child_tid);
+    SetState(StateType::eStateStopped, true);
+  } else {
+    child_process->Detach();
+    Status pt_error =
+        PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
+    if (pt_error.Fail()) {
+      LLDB_LOG_ERROR(log, pt_error.ToError(),
+                     "unable to resume parent process {1}: {0}", GetID());
+      SetState(StateType::eStateInvalid);
+    }
+  }
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
similarity index 88%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
index 3c7a940..7ec9d17 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -10,6 +10,8 @@
 #define liblldb_NativeProcessFreeBSD_H_
 
 #include "Plugins/Process/POSIX/NativeProcessELF.h"
+#include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
+
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/FileSpec.h"
@@ -25,7 +27,8 @@
 /// for debugging.
 ///
 /// Changes in the inferior process state are broadcasted.
-class NativeProcessFreeBSD : public NativeProcessELF {
+class NativeProcessFreeBSD : public NativeProcessELF,
+                             private NativeProcessSoftwareSingleStep {
 public:
   class Factory : public NativeProcessProtocol::Factory {
   public:
@@ -36,6 +39,8 @@
     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
            MainLoop &mainloop) const override;
+
+    Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -84,9 +89,16 @@
   static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
                               int data = 0, int *result = nullptr);
 
+  bool SupportHardwareSingleStepping() const;
+
+protected:
+  llvm::Expected<llvm::ArrayRef<uint8_t>>
+  GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
+
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
+  MainLoop& m_main_loop;
   LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
@@ -104,6 +116,8 @@
   void MonitorSIGSTOP(lldb::pid_t pid);
   void MonitorSIGTRAP(lldb::pid_t pid);
   void MonitorSignal(lldb::pid_t pid, int signal);
+  void MonitorClone(::pid_t child_pid, bool is_vfork,
+                    NativeThreadFreeBSD &parent_thread);
 
   Status PopulateMemoryRegionCache();
   void SigchldHandler();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp
similarity index 92%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp
index ac3cc4f..3d744f7 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.cpp
@@ -8,7 +8,7 @@
 
 #include "NativeRegisterContextFreeBSD.h"
 
-#include "Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h"
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
 
 #include "lldb/Host/common/NativeProcessProtocol.h"
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
similarity index 100%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
new file mode 100644
index 0000000..c4ee377
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.cpp
@@ -0,0 +1,202 @@
+//===-- NativeRegisterContextFreeBSD_arm.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#include "NativeRegisterContextFreeBSD_arm.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+  return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+    : NativeRegisterContextRegisterInfo(
+          native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}
+
+RegisterInfoPOSIX_arm &
+NativeRegisterContextFreeBSD_arm::GetRegisterInfo() const {
+  return static_cast<RegisterInfoPOSIX_arm &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetRegisterSetCount() const {
+  return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_arm::GetRegisterSet(uint32_t set_index) const {
+  return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetUserRegisterCount() const {
+  uint32_t count = 0;
+  for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+    count += GetRegisterSet(set_index)->num_registers;
+  return count;
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadRegisterSet(uint32_t set) {
+  switch (set) {
+  case RegisterInfoPOSIX_arm::GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case RegisterInfoPOSIX_arm::FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_GETVFPREGS, m_thread.GetID(),
+        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_arm::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegisterSet(uint32_t set) {
+  switch (set) {
+  case RegisterInfoPOSIX_arm::GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case RegisterInfoPOSIX_arm::FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_SETVFPREGS, m_thread.GetID(),
+        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_arm::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_arm::ReadRegister(const RegisterInfo *reg_info,
+                                               RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info) {
+    error.SetErrorString("reg_info NULL");
+    return error;
+  }
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+                     reg_info->byte_size, endian::InlHostByteOrder());
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info)
+    return Status("reg_info NULL");
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+           reg_info->byte_size);
+
+  return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+  if (error.Fail())
+    return error;
+
+  error = ReadRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+  if (error.Fail())
+    return error;
+
+  data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+  uint8_t *dst = data_sp->GetBytes();
+  ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  if (!data_sp) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_arm::%s invalid data_sp provided",
+        __FUNCTION__);
+    return error;
+  }
+
+  if (data_sp->GetByteSize() != m_reg_data.size()) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_arm::%s data_sp contained mismatched "
+        "data size, expected %" PRIu64 ", actual %" PRIu64,
+        __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+    return error;
+  }
+
+  uint8_t *src = data_sp->GetBytes();
+  if (src == nullptr) {
+    error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s "
+                                   "DataBuffer::GetBytes() returned a null "
+                                   "pointer",
+                                   __FUNCTION__);
+    return error;
+  }
+  ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+  error = WriteRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+  if (error.Fail())
+    return error;
+
+  return WriteRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm::CopyHardwareWatchpointsFrom(
+    NativeRegisterContextFreeBSD &source) {
+  return llvm::Error::success();
+}
+
+#endif // defined (__arm__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h
new file mode 100644
index 0000000..4be75b9
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm.h
@@ -0,0 +1,68 @@
+//===-- NativeRegisterContextFreeBSD_arm.h ----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+#define lldb_NativeRegisterContextFreeBSD_arm_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+#include <machine/vfp.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_arm : public NativeRegisterContextFreeBSD {
+public:
+  NativeRegisterContextFreeBSD_arm(const ArchSpec &target_arch,
+                                   NativeThreadProtocol &native_thread);
+
+  uint32_t GetRegisterSetCount() const override;
+
+  uint32_t GetUserRegisterCount() const override;
+
+  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+  Status ReadRegister(const RegisterInfo *reg_info,
+                      RegisterValue &reg_value) override;
+
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_value) override;
+
+  Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+  llvm::Error
+  CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+  std::array<uint8_t, sizeof(reg) + sizeof(vfp_state)> m_reg_data;
+
+  Status ReadRegisterSet(uint32_t set);
+  Status WriteRegisterSet(uint32_t set);
+
+  RegisterInfoPOSIX_arm &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+
+#endif // defined (__arm__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
new file mode 100644
index 0000000..4578138
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.cpp
@@ -0,0 +1,282 @@
+//===-- NativeRegisterContextFreeBSD_arm64.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__)
+
+#include "NativeRegisterContextFreeBSD_arm64.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+  return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+    : NativeRegisterContextRegisterInfo(
+          native_thread, new RegisterInfoPOSIX_arm64(target_arch, 0))
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+      ,
+      m_read_dbreg(false)
+#endif
+{
+  ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+  ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
+}
+
+RegisterInfoPOSIX_arm64 &
+NativeRegisterContextFreeBSD_arm64::GetRegisterInfo() const {
+  return static_cast<RegisterInfoPOSIX_arm64 &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm64::GetRegisterSetCount() const {
+  return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_arm64::GetRegisterSet(uint32_t set_index) const {
+  return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm64::GetUserRegisterCount() const {
+  uint32_t count = 0;
+  for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+    count += GetRegisterSet(set_index)->num_registers;
+  return count;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::ReadRegisterSet(uint32_t set) {
+  switch (set) {
+  case RegisterInfoPOSIX_arm64::GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case RegisterInfoPOSIX_arm64::FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_GETFPREGS, m_thread.GetID(),
+        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_arm64::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteRegisterSet(uint32_t set) {
+  switch (set) {
+  case RegisterInfoPOSIX_arm64::GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case RegisterInfoPOSIX_arm64::FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_SETFPREGS, m_thread.GetID(),
+        m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm64::GPR));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_arm64::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_arm64::ReadRegister(const RegisterInfo *reg_info,
+                                                 RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info) {
+    error.SetErrorString("reg_info NULL");
+    return error;
+  }
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+                     reg_info->byte_size, endian::InlHostByteOrder());
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info)
+    return Status("reg_info NULL");
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+           reg_info->byte_size);
+
+  return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_arm64::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  error = ReadRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet);
+  if (error.Fail())
+    return error;
+
+  error = ReadRegisterSet(RegisterInfoPOSIX_arm64::FPRegSet);
+  if (error.Fail())
+    return error;
+
+  data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+  uint8_t *dst = data_sp->GetBytes();
+  ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm64::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  if (!data_sp) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_arm64::%s invalid data_sp provided",
+        __FUNCTION__);
+    return error;
+  }
+
+  if (data_sp->GetByteSize() != m_reg_data.size()) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_arm64::%s data_sp contained mismatched "
+        "data size, expected %" PRIu64 ", actual %" PRIu64,
+        __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+    return error;
+  }
+
+  uint8_t *src = data_sp->GetBytes();
+  if (src == nullptr) {
+    error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm64::%s "
+                                   "DataBuffer::GetBytes() returned a null "
+                                   "pointer",
+                                   __FUNCTION__);
+    return error;
+  }
+  ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+  error = WriteRegisterSet(RegisterInfoPOSIX_arm64::GPRegSet);
+  if (error.Fail())
+    return error;
+
+  return WriteRegisterSet(RegisterInfoPOSIX_arm64::FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm64::CopyHardwareWatchpointsFrom(
+    NativeRegisterContextFreeBSD &source) {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+  auto &r_source = static_cast<NativeRegisterContextFreeBSD_arm64 &>(source);
+  llvm::Error error = r_source.ReadHardwareDebugInfo();
+  if (error)
+    return error;
+
+  m_dbreg = r_source.m_dbreg;
+  m_hbp_regs = r_source.m_hbp_regs;
+  m_hwp_regs = r_source.m_hwp_regs;
+  m_max_hbp_supported = r_source.m_max_hbp_supported;
+  m_max_hwp_supported = r_source.m_max_hwp_supported;
+  m_read_dbreg = true;
+
+  // on FreeBSD this writes both breakpoints and watchpoints
+  return WriteHardwareDebugRegs(eDREGTypeWATCH);
+#else
+  return llvm::Error::success();
+#endif
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm64::ReadHardwareDebugInfo() {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
+
+  // we're fully stateful, so no need to reread control registers ever
+  if (m_read_dbreg)
+    return llvm::Error::success();
+
+  Status res = NativeProcessFreeBSD::PtraceWrapper(PT_GETDBREGS,
+                                                   m_thread.GetID(), &m_dbreg);
+  if (res.Fail())
+    return res.ToError();
+
+  LLDB_LOG(log, "m_dbreg read: debug_ver={0}, nbkpts={1}, nwtpts={2}",
+           m_dbreg.db_debug_ver, m_dbreg.db_nbkpts, m_dbreg.db_nwtpts);
+  m_max_hbp_supported = m_dbreg.db_nbkpts;
+  m_max_hwp_supported = m_dbreg.db_nwtpts;
+  assert(m_max_hbp_supported <= m_hbp_regs.size());
+  assert(m_max_hwp_supported <= m_hwp_regs.size());
+
+  m_read_dbreg = true;
+  return llvm::Error::success();
+#else
+  return llvm::createStringError(
+      llvm::inconvertibleErrorCode(),
+      "Hardware breakpoints/watchpoints require FreeBSD 14.0");
+#endif
+}
+
+llvm::Error
+NativeRegisterContextFreeBSD_arm64::WriteHardwareDebugRegs(DREGType) {
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+  assert(m_read_dbreg && "dbregs must be read before writing them back");
+
+  // copy data from m_*_regs to m_dbreg before writing it back
+  for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+    m_dbreg.db_breakregs[i].dbr_addr = m_hbp_regs[i].address;
+    m_dbreg.db_breakregs[i].dbr_ctrl = m_hbp_regs[i].control;
+  }
+  for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+    m_dbreg.db_watchregs[i].dbw_addr = m_hwp_regs[i].address;
+    m_dbreg.db_watchregs[i].dbw_ctrl = m_hwp_regs[i].control;
+  }
+
+  return NativeProcessFreeBSD::PtraceWrapper(PT_SETDBREGS, m_thread.GetID(),
+                                             &m_dbreg)
+      .ToError();
+#else
+  return llvm::createStringError(
+      llvm::inconvertibleErrorCode(),
+      "Hardware breakpoints/watchpoints require FreeBSD 14.0");
+#endif
+}
+
+#endif // defined (__aarch64__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
new file mode 100644
index 0000000..a230f8f
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_arm64.h
@@ -0,0 +1,86 @@
+//===-- NativeRegisterContextFreeBSD_arm64.h --------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__aarch64__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_arm64_h
+#define lldb_NativeRegisterContextFreeBSD_arm64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/param.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+
+#include <array>
+
+#if __FreeBSD_version >= 1300139
+#  define LLDB_HAS_FREEBSD_WATCHPOINT 1
+#endif
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_arm64
+    : public NativeRegisterContextFreeBSD,
+      public NativeRegisterContextDBReg_arm64 {
+public:
+  NativeRegisterContextFreeBSD_arm64(const ArchSpec &target_arch,
+                                     NativeThreadProtocol &native_thread);
+
+  uint32_t GetRegisterSetCount() const override;
+
+  uint32_t GetUserRegisterCount() const override;
+
+  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+  Status ReadRegister(const RegisterInfo *reg_info,
+                      RegisterValue &reg_value) override;
+
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_value) override;
+
+  Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+  llvm::Error
+  CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+  // Due to alignment, FreeBSD reg/fpreg are a few bytes larger than
+  // LLDB's GPR/FPU structs.  However, all fields have matching offsets
+  // and sizes, so we do not have to worry about these (and we have
+  // a unittest to assert that).
+  std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+#ifdef LLDB_HAS_FREEBSD_WATCHPOINT
+  dbreg m_dbreg;
+  bool m_read_dbreg;
+#endif
+
+  Status ReadRegisterSet(uint32_t set);
+  Status WriteRegisterSet(uint32_t set);
+
+  llvm::Error ReadHardwareDebugInfo() override;
+  llvm::Error WriteHardwareDebugRegs(DREGType hwbType) override;
+
+  RegisterInfoPOSIX_arm64 &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_arm64_h
+
+#endif // defined (__aarch64__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
new file mode 100644
index 0000000..8e722c0
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
@@ -0,0 +1,186 @@
+//===-- NativeRegisterContextFreeBSD_mips64.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__mips64__)
+
+#include "NativeRegisterContextFreeBSD_mips64.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+  return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+    : NativeRegisterContextRegisterInfo(
+          native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {}
+
+RegisterContextFreeBSD_mips64 &
+NativeRegisterContextFreeBSD_mips64::GetRegisterInfo() const {
+  return static_cast<RegisterContextFreeBSD_mips64 &>(
+      *m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
+  return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_mips64::GetRegisterSet(uint32_t set_index) const {
+  return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {
+  uint32_t count = 0;
+  for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+    count += GetRegisterSet(set_index)->num_registers;
+  return count;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) {
+  switch (set) {
+  case GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) {
+  switch (set) {
+  case GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,
+                                                  RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info) {
+    error.SetErrorString("reg_info NULL");
+    return error;
+  }
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  RegSetKind set = GPRegSet;
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+                     reg_info->byte_size, endian::InlHostByteOrder());
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info)
+    return Status("reg_info NULL");
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  RegSetKind set = GPRegSet;
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+           reg_info->byte_size);
+
+  return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  error = ReadRegisterSet(GPRegSet);
+  if (error.Fail())
+    return error;
+
+  data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+  uint8_t *dst = data_sp->GetBytes();
+  ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  if (!data_sp) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_mips64::%s invalid data_sp provided",
+        __FUNCTION__);
+    return error;
+  }
+
+  if (data_sp->GetByteSize() != m_reg_data.size()) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_mips64::%s data_sp contained mismatched "
+        "data size, expected %" PRIu64 ", actual %" PRIu64,
+        __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+    return error;
+  }
+
+  uint8_t *src = data_sp->GetBytes();
+  if (src == nullptr) {
+    error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s "
+                                   "DataBuffer::GetBytes() returned a null "
+                                   "pointer",
+                                   __FUNCTION__);
+    return error;
+  }
+  ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+  return WriteRegisterSet(GPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(
+    NativeRegisterContextFreeBSD &source) {
+  return llvm::Error::success();
+}
+
+#endif // defined (__mips64__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
new file mode 100644
index 0000000..6a3eb86
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
@@ -0,0 +1,71 @@
+//===-- NativeRegisterContextFreeBSD_mips64.h -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__mips64__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_mips64_h
+#define lldb_NativeRegisterContextFreeBSD_mips64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_mips64
+    : public NativeRegisterContextFreeBSD {
+public:
+  NativeRegisterContextFreeBSD_mips64(const ArchSpec &target_arch,
+                                      NativeThreadProtocol &native_thread);
+
+  uint32_t GetRegisterSetCount() const override;
+
+  uint32_t GetUserRegisterCount() const override;
+
+  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+  Status ReadRegister(const RegisterInfo *reg_info,
+                      RegisterValue &reg_value) override;
+
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_value) override;
+
+  Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+  llvm::Error
+  CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+  enum RegSetKind {
+    GPRegSet,
+  };
+  std::array<uint8_t, sizeof(reg)> m_reg_data;
+
+  Status ReadRegisterSet(RegSetKind set);
+  Status WriteRegisterSet(RegSetKind set);
+
+  RegisterContextFreeBSD_mips64 &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_mips64_h
+
+#endif // defined (__mips64__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
new file mode 100644
index 0000000..5b5d44a
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.cpp
@@ -0,0 +1,289 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__powerpc__)
+
+#include "NativeRegisterContextFreeBSD_powerpc.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+// for register enum definitions
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+static const uint32_t g_gpr_regnums[] = {
+    gpr_r0_powerpc,  gpr_r1_powerpc,  gpr_r2_powerpc,  gpr_r3_powerpc,
+    gpr_r4_powerpc,  gpr_r5_powerpc,  gpr_r6_powerpc,  gpr_r7_powerpc,
+    gpr_r8_powerpc,  gpr_r9_powerpc,  gpr_r10_powerpc, gpr_r11_powerpc,
+    gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc,
+    gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc,
+    gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc,
+    gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc,
+    gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc,
+    gpr_lr_powerpc,  gpr_cr_powerpc,  gpr_xer_powerpc, gpr_ctr_powerpc,
+    gpr_pc_powerpc,
+};
+
+static const uint32_t g_fpr_regnums[] = {
+    fpr_f0_powerpc,    fpr_f1_powerpc,  fpr_f2_powerpc,  fpr_f3_powerpc,
+    fpr_f4_powerpc,    fpr_f5_powerpc,  fpr_f6_powerpc,  fpr_f7_powerpc,
+    fpr_f8_powerpc,    fpr_f9_powerpc,  fpr_f10_powerpc, fpr_f11_powerpc,
+    fpr_f12_powerpc,   fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc,
+    fpr_f16_powerpc,   fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc,
+    fpr_f20_powerpc,   fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc,
+    fpr_f24_powerpc,   fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc,
+    fpr_f28_powerpc,   fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc,
+    fpr_fpscr_powerpc,
+};
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
+
+static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
+    {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc,
+     g_gpr_regnums},
+    {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc,
+     g_fpr_regnums},
+};
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+  return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread);
+}
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+  if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+    return new RegisterContextFreeBSD_powerpc32(target_arch);
+  } else {
+    assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+           "Register setting path assumes this is a 64-bit host");
+    return new RegisterContextFreeBSD_powerpc64(target_arch);
+  }
+}
+
+NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc(
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+    : NativeRegisterContextRegisterInfo(
+          native_thread, CreateRegisterInfoInterface(target_arch)) {}
+
+RegisterContextFreeBSD_powerpc &
+NativeRegisterContextFreeBSD_powerpc::GetRegisterInfo() const {
+  return static_cast<RegisterContextFreeBSD_powerpc &>(
+      *m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::GetRegisterSetCount() const {
+  return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_powerpc::GetRegisterSet(uint32_t set_index) const {
+  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+  case llvm::Triple::ppc:
+    return &g_reg_sets_powerpc[set_index];
+  default:
+    llvm_unreachable("Unhandled target architecture.");
+  }
+}
+
+llvm::Optional<NativeRegisterContextFreeBSD_powerpc::RegSetKind>
+NativeRegisterContextFreeBSD_powerpc::GetSetForNativeRegNum(
+    uint32_t reg_num) const {
+  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+  case llvm::Triple::ppc:
+    if (reg_num >= k_first_gpr_powerpc && reg_num <= k_last_gpr_powerpc)
+      return GPRegSet;
+    if (reg_num >= k_first_fpr && reg_num <= k_last_fpr)
+      return FPRegSet;
+    break;
+  default:
+    llvm_unreachable("Unhandled target architecture.");
+  }
+
+  llvm_unreachable("Register does not belong to any register set");
+}
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::GetUserRegisterCount() const {
+  uint32_t count = 0;
+  for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+    count += GetRegisterSet(set_index)->num_registers;
+  return count;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::ReadRegisterSet(RegSetKind set) {
+  switch (set) {
+  case GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(),
+                                               m_reg_data.data() + sizeof(reg));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet(RegSetKind set) {
+  switch (set) {
+  case GPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+                                               m_reg_data.data());
+  case FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(),
+                                               m_reg_data.data() + sizeof(reg));
+  }
+  llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_powerpc::ReadRegister(const RegisterInfo *reg_info,
+                                                   RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info) {
+    error.SetErrorString("reg_info NULL");
+    return error;
+  }
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
+    // This is likely an internal register for lldb use only and should not be
+    // directly queried.
+    error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+                                   reg_info->name);
+    return error;
+  }
+
+  RegSetKind set = opt_set.getValue();
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+                     reg_info->byte_size, endian::InlHostByteOrder());
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+  Status error;
+
+  if (!reg_info)
+    return Status("reg_info NULL");
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+  if (reg == LLDB_INVALID_REGNUM)
+    return Status("no lldb regnum for %s", reg_info && reg_info->name
+                                               ? reg_info->name
+                                               : "<unknown register>");
+
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
+    // This is likely an internal register for lldb use only and should not be
+    // directly queried.
+    error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+                                   reg_info->name);
+    return error;
+  }
+
+  RegSetKind set = opt_set.getValue();
+  error = ReadRegisterSet(set);
+  if (error.Fail())
+    return error;
+
+  assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+  ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+           reg_info->byte_size);
+
+  return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  error = ReadRegisterSet(GPRegSet);
+  if (error.Fail())
+    return error;
+
+  error = ReadRegisterSet(FPRegSet);
+  if (error.Fail())
+    return error;
+
+  data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+  uint8_t *dst = data_sp->GetBytes();
+  ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+  return error;
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  Status error;
+
+  if (!data_sp) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_powerpc::%s invalid data_sp provided",
+        __FUNCTION__);
+    return error;
+  }
+
+  if (data_sp->GetByteSize() != m_reg_data.size()) {
+    error.SetErrorStringWithFormat(
+        "NativeRegisterContextFreeBSD_powerpc::%s data_sp contained mismatched "
+        "data size, expected %zu, actual %" PRIu64,
+        __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+    return error;
+  }
+
+  uint8_t *src = data_sp->GetBytes();
+  if (src == nullptr) {
+    error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_powerpc::%s "
+                                   "DataBuffer::GetBytes() returned a null "
+                                   "pointer",
+                                   __FUNCTION__);
+    return error;
+  }
+  ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+  error = WriteRegisterSet(GPRegSet);
+  if (error.Fail())
+    return error;
+
+  return WriteRegisterSet(FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_powerpc::CopyHardwareWatchpointsFrom(
+    NativeRegisterContextFreeBSD &source) {
+  return llvm::Error::success();
+}
+
+#endif // defined (__powerpc__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h
new file mode 100644
index 0000000..884c259
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_powerpc.h
@@ -0,0 +1,74 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.h ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__powerpc__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+#define lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_powerpc
+    : public NativeRegisterContextFreeBSD {
+public:
+  NativeRegisterContextFreeBSD_powerpc(const ArchSpec &target_arch,
+                                       NativeThreadProtocol &native_thread);
+
+  uint32_t GetRegisterSetCount() const override;
+
+  uint32_t GetUserRegisterCount() const override;
+
+  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+  Status ReadRegister(const RegisterInfo *reg_info,
+                      RegisterValue &reg_value) override;
+
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_value) override;
+
+  Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+  llvm::Error
+  CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+  enum RegSetKind {
+    GPRegSet,
+    FPRegSet,
+  };
+  std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+
+  llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+  Status ReadRegisterSet(RegSetKind set);
+  Status WriteRegisterSet(RegSetKind set);
+
+  RegisterContextFreeBSD_powerpc &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+#endif // defined (__powerpc__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
similarity index 99%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
index d5052e7..9328d60 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.cpp
@@ -260,7 +260,7 @@
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
           native_thread, CreateRegisterInfoInterface(target_arch)),
-      m_regset_offsets({0}) {
+      NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {
   assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
   std::array<uint32_t, MaxRegSet + 1> first_regnos;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
similarity index 93%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
index 673cffd..efd0f91 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_x86_64.h
@@ -20,9 +20,9 @@
 
 #include <array>
 
-#include "Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h"
 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 
 #define LLDB_INVALID_XSAVE_OFFSET UINT32_MAX
@@ -34,7 +34,7 @@
 
 class NativeRegisterContextFreeBSD_x86_64
     : public NativeRegisterContextFreeBSD,
-      public NativeRegisterContextWatchpoint_x86 {
+      public NativeRegisterContextDBReg_x86 {
 public:
   NativeRegisterContextFreeBSD_x86_64(const ArchSpec &target_arch,
                                       NativeThreadProtocol &native_thread);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
similarity index 89%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
index 4349487..80b3527 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp
@@ -46,6 +46,11 @@
   if (!ret.Success())
     return ret;
   ret = NativeProcessFreeBSD::PtraceWrapper(PT_CLEARSTEP, GetID());
+  // we can get EINVAL if the architecture in question does not support
+  // hardware single-stepping -- that's fine, we have nothing to clear
+  // then
+  if (ret.GetError() == EINVAL)
+    ret.Clear();
   if (ret.Success())
     SetRunning();
   return ret;
@@ -125,6 +130,30 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadFreeBSD::SetStoppedByFork(lldb::pid_t child_pid,
+                                           lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVFork(lldb::pid_t child_pid,
+                                            lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadFreeBSD::SetStoppedByVForkDone() {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
 void NativeThreadFreeBSD::SetStoppedWithNoReason() {
   SetStopped();
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
similarity index 90%
rename from src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h
rename to src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
index 4e997b3..3ec6daa 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.h
@@ -11,7 +11,7 @@
 
 #include "lldb/Host/common/NativeThreadProtocol.h"
 
-#include "Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
 
 #include <csignal>
 #include <map>
@@ -59,6 +59,9 @@
   void SetStoppedByTrace();
   void SetStoppedByExec();
   void SetStoppedByWatchpoint(uint32_t wp_index);
+  void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVForkDone();
   void SetStoppedWithNoReason();
   void SetStopped();
   void SetRunning();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
deleted file mode 100644
index 4e6f3af..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- POSIXStopInfo.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 "POSIXStopInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//===----------------------------------------------------------------------===//
-// POSIXLimboStopInfo
-
-POSIXLimboStopInfo::~POSIXLimboStopInfo() {}
-
-lldb::StopReason POSIXLimboStopInfo::GetStopReason() const {
-  return lldb::eStopReasonThreadExiting;
-}
-
-const char *POSIXLimboStopInfo::GetDescription() { return "thread exiting"; }
-
-bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
-
-bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
-
-//===----------------------------------------------------------------------===//
-// POSIXNewThreadStopInfo
-
-POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
-
-lldb::StopReason POSIXNewThreadStopInfo::GetStopReason() const {
-  return lldb::eStopReasonNone;
-}
-
-const char *POSIXNewThreadStopInfo::GetDescription() {
-  return "thread spawned";
-}
-
-bool POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr) { return false; }
-
-bool POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr) { return false; }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
deleted file mode 100644
index 5a022c4..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- POSIXStopInfo.h -----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_POSIXStopInfo_H_
-#define liblldb_POSIXStopInfo_H_
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
-#include "lldb/Target/StopInfo.h"
-#include <string>
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXStopInfo
-/// Simple base class for all POSIX-specific StopInfo objects.
-///
-class POSIXStopInfo : public lldb_private::StopInfo {
-public:
-  POSIXStopInfo(lldb_private::Thread &thread, uint32_t status)
-      : StopInfo(thread, status) {}
-};
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXLimboStopInfo
-/// Represents the stop state of a process ready to exit.
-///
-class POSIXLimboStopInfo : public POSIXStopInfo {
-public:
-  POSIXLimboStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
-
-  ~POSIXLimboStopInfo();
-
-  lldb::StopReason GetStopReason() const override;
-
-  const char *GetDescription() override;
-
-  bool ShouldStop(lldb_private::Event *event_ptr) override;
-
-  bool ShouldNotify(lldb_private::Event *event_ptr) override;
-};
-
-//===----------------------------------------------------------------------===//
-/// \class POSIXNewThreadStopInfo
-/// Represents the stop state of process when a new thread is spawned.
-///
-
-class POSIXNewThreadStopInfo : public POSIXStopInfo {
-public:
-  POSIXNewThreadStopInfo(FreeBSDThread &thread) : POSIXStopInfo(thread, 0) {}
-
-  ~POSIXNewThreadStopInfo();
-
-  lldb::StopReason GetStopReason() const override;
-
-  const char *GetDescription() override;
-
-  bool ShouldStop(lldb_private::Event *event_ptr) override;
-
-  bool ShouldNotify(lldb_private::Event *event_ptr) override;
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
deleted file mode 100644
index a1fe45b..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ /dev/null
@@ -1,1080 +0,0 @@
-//===-- ProcessFreeBSD.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 <errno.h>
-#include <pthread.h>
-#include <pthread_np.h>
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <machine/elf.h>
-
-#include <mutex>
-#include <unordered_map>
-
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/State.h"
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/FreeBSDSignals.h"
-#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/State.h"
-
-#include "lldb/Host/posix/Fcntl.h"
-
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Threading.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LLDB_PLUGIN_DEFINE(ProcessFreeBSD)
-
-namespace {
-UnixSignalsSP &GetFreeBSDSignals() {
-  static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
-  return s_freebsd_signals_sp;
-}
-}
-
-// Static functions.
-
-lldb::ProcessSP
-ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
-                               lldb::ListenerSP listener_sp,
-                               const FileSpec *crash_file_path,
-                               bool can_connect) {
-  lldb::ProcessSP process_sp;
-  if (crash_file_path == NULL && !can_connect)
-    process_sp.reset(
-        new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals()));
-  return process_sp;
-}
-
-void ProcessFreeBSD::Initialize() {
-  static llvm::once_flag g_once_flag;
-
-  llvm::call_once(g_once_flag, []() {
-    PluginManager::RegisterPlugin(GetPluginNameStatic(),
-                                  GetPluginDescriptionStatic(), CreateInstance);
-  });
-}
-
-lldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
-  static ConstString g_name("freebsd");
-  return g_name;
-}
-
-const char *ProcessFreeBSD::GetPluginDescriptionStatic() {
-  return "Process plugin for FreeBSD";
-}
-
-// ProcessInterface protocol.
-
-lldb_private::ConstString ProcessFreeBSD::GetPluginName() {
-  return GetPluginNameStatic();
-}
-
-uint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
-
-void ProcessFreeBSD::Terminate() {}
-
-Status ProcessFreeBSD::DoDetach(bool keep_stopped) {
-  Status error;
-  if (keep_stopped) {
-    error.SetErrorString("Detaching with keep_stopped true is not currently "
-                         "supported on FreeBSD.");
-    return error;
-  }
-
-  error = m_monitor->Detach(GetID());
-
-  if (error.Success())
-    SetPrivateState(eStateDetached);
-
-  return error;
-}
-
-Status ProcessFreeBSD::DoResume() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  SetPrivateState(eStateRunning);
-
-  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-  bool do_step = false;
-  bool software_single_step = !SupportHardwareSingleStepping();
-
-  for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
-                                      t_end = m_run_tids.end();
-       t_pos != t_end; ++t_pos) {
-    m_monitor->ThreadSuspend(*t_pos, false);
-  }
-  for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
-                                      t_end = m_step_tids.end();
-       t_pos != t_end; ++t_pos) {
-    m_monitor->ThreadSuspend(*t_pos, false);
-    do_step = true;
-    if (software_single_step) {
-      Status error = SetupSoftwareSingleStepping(*t_pos);
-      if (error.Fail())
-        return error;
-    }
-  }
-  for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
-                                      t_end = m_suspend_tids.end();
-       t_pos != t_end; ++t_pos) {
-    m_monitor->ThreadSuspend(*t_pos, true);
-    // XXX Cannot PT_CONTINUE properly with suspended threads.
-    do_step = true;
-  }
-
-  LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(),
-            do_step ? "step" : "continue");
-  if (do_step && !software_single_step)
-    m_monitor->SingleStep(GetID(), m_resume_signo);
-  else
-    m_monitor->Resume(GetID(), m_resume_signo);
-
-  return Status();
-}
-
-bool ProcessFreeBSD::DoUpdateThreadList(ThreadList &old_thread_list,
-                                        ThreadList &new_thread_list) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
-            GetID());
-
-  std::vector<lldb::pid_t> tds;
-  if (!GetMonitor().GetCurrentThreadIDs(tds)) {
-    return false;
-  }
-
-  ThreadList old_thread_list_copy(old_thread_list);
-  for (size_t i = 0; i < tds.size(); ++i) {
-    tid_t tid = tds[i];
-    ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
-    if (!thread_sp) {
-      thread_sp.reset(new FreeBSDThread(*this, tid));
-      LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__,
-                tid);
-    } else {
-      LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
-                tid);
-    }
-    new_thread_list.AddThread(thread_sp);
-  }
-  for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
-    ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
-    if (old_thread_sp) {
-      LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__);
-    }
-  }
-
-  return true;
-}
-
-Status ProcessFreeBSD::WillResume() {
-  m_resume_signo = 0;
-  m_suspend_tids.clear();
-  m_run_tids.clear();
-  m_step_tids.clear();
-  return Process::WillResume();
-}
-
-void ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
-  std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
-
-  switch (message.GetKind()) {
-  case ProcessMessage::eInvalidMessage:
-    return;
-
-  case ProcessMessage::eAttachMessage:
-    SetPrivateState(eStateStopped);
-    return;
-
-  case ProcessMessage::eLimboMessage:
-  case ProcessMessage::eExitMessage:
-    SetExitStatus(message.GetExitStatus(), NULL);
-    break;
-
-  case ProcessMessage::eSignalMessage:
-  case ProcessMessage::eSignalDeliveredMessage:
-  case ProcessMessage::eBreakpointMessage:
-  case ProcessMessage::eTraceMessage:
-  case ProcessMessage::eWatchpointMessage:
-  case ProcessMessage::eCrashMessage:
-    SetPrivateState(eStateStopped);
-    break;
-
-  case ProcessMessage::eNewThreadMessage:
-    llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
-    break;
-
-  case ProcessMessage::eExecMessage:
-    SetPrivateState(eStateStopped);
-    break;
-  }
-
-  m_message_queue.push(message);
-}
-
-// Constructors and destructors.
-
-ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp,
-                               lldb::ListenerSP listener_sp,
-                               UnixSignalsSP &unix_signals_sp)
-    : Process(target_sp, listener_sp, unix_signals_sp),
-      m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL),
-      m_message_mutex(), m_exit_now(false), m_seen_initial_stop(),
-      m_resume_signo(0) {
-  // FIXME: Putting this code in the ctor and saving the byte order in a
-  // member variable is a hack to avoid const qual issues in GetByteOrder.
-  lldb::ModuleSP module = GetTarget().GetExecutableModule();
-  if (module && module->GetObjectFile())
-    m_byte_order = module->GetObjectFile()->GetByteOrder();
-}
-
-ProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
-
-// Process protocol.
-void ProcessFreeBSD::Finalize() {
-  Process::Finalize();
-
-  if (m_monitor)
-    m_monitor->StopMonitor();
-}
-
-bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
-                              bool plugin_specified_by_name) {
-  // For now we are just making sure the file exists for a given module
-  ModuleSP exe_module_sp(target_sp->GetExecutableModule());
-  if (exe_module_sp.get())
-    return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
-  // If there is no executable module, we return true since we might be
-  // preparing to attach.
-  return true;
-}
-
-Status
-ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid,
-                                        const ProcessAttachInfo &attach_info) {
-  Status error;
-  assert(m_monitor == NULL);
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOGV(log, "pid = {0}", GetID());
-
-  m_monitor = new ProcessMonitor(this, pid, error);
-
-  if (!error.Success())
-    return error;
-
-  PlatformSP platform_sp(GetTarget().GetPlatform());
-  assert(platform_sp.get());
-  if (!platform_sp)
-    return error; // FIXME: Detatch?
-
-  // Find out what we can about this process
-  ProcessInstanceInfo process_info;
-  platform_sp->GetProcessInfo(pid, process_info);
-
-  // Resolve the executable module
-  ModuleSP exe_module_sp;
-  FileSpecList executable_search_paths(
-      Target::GetDefaultExecutableSearchPaths());
-  ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
-                             GetTarget().GetArchitecture());
-  error = platform_sp->ResolveExecutable(
-      exe_module_spec, exe_module_sp,
-      executable_search_paths.GetSize() ? &executable_search_paths : NULL);
-  if (!error.Success())
-    return error;
-
-  // Fix the target architecture if necessary
-  const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
-  if (module_arch.IsValid() &&
-      !GetTarget().GetArchitecture().IsExactMatch(module_arch))
-    GetTarget().SetArchitecture(module_arch);
-
-  // Initialize the target module list
-  GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes);
-
-  SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
-
-  SetID(pid);
-
-  return error;
-}
-
-Status ProcessFreeBSD::WillLaunch(Module *module) {
-  Status error;
-  return error;
-}
-
-FileSpec
-ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
-                            const FileSpec &default_file_spec,
-                            const FileSpec &dbg_pts_file_spec) {
-  FileSpec file_spec{};
-
-  if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
-    file_spec = file_action->GetFileSpec();
-    // By default the stdio paths passed in will be pseudo-terminal (/dev/pts).
-    // If so, convert to using a different default path instead to redirect I/O
-    // to the debugger console. This should also handle user overrides to
-    // /dev/null or a different file.
-    if (!file_spec || file_spec == dbg_pts_file_spec)
-      file_spec = default_file_spec;
-  }
-  return file_spec;
-}
-
-Status ProcessFreeBSD::DoLaunch(Module *module,
-                                ProcessLaunchInfo &launch_info) {
-  Status error;
-  assert(m_monitor == NULL);
-
-  FileSpec working_dir = launch_info.GetWorkingDirectory();
-  if (working_dir) {
-    FileSystem::Instance().Resolve(working_dir);
-    if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) {
-      error.SetErrorStringWithFormat("No such file or directory: %s",
-                                   working_dir.GetCString());
-      return error;
-    }
-  }
-
-  SetPrivateState(eStateLaunching);
-
-  const lldb_private::FileAction *file_action;
-
-  // Default of empty will mean to use existing open file descriptors
-  FileSpec stdin_file_spec{};
-  FileSpec stdout_file_spec{};
-  FileSpec stderr_file_spec{};
-
-  const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSecondaryName()};
-
-  file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
-  stdin_file_spec =
-      GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
-
-  file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
-  stdout_file_spec =
-      GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
-
-  file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
-  stderr_file_spec =
-      GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
-
-  m_monitor = new ProcessMonitor(
-      this, module, launch_info.GetArguments().GetConstArgumentVector(),
-      launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec,
-      stderr_file_spec, working_dir, launch_info, error);
-
-  m_module = module;
-
-  if (!error.Success())
-    return error;
-
-  int terminal = m_monitor->GetTerminalFD();
-  if (terminal >= 0) {
-// The reader thread will close the file descriptor when done, so we pass it a
-// copy.
-#ifdef F_DUPFD_CLOEXEC
-    int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
-    if (stdio == -1) {
-      error.SetErrorToErrno();
-      return error;
-    }
-#else
-    // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
-    int stdio = fcntl(terminal, F_DUPFD, 0);
-    if (stdio == -1) {
-      error.SetErrorToErrno();
-      return error;
-    }
-    stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
-    if (stdio == -1) {
-      error.SetErrorToErrno();
-      return error;
-    }
-#endif
-    SetSTDIOFileDescriptor(stdio);
-  }
-
-  SetID(m_monitor->GetPID());
-  return error;
-}
-
-void ProcessFreeBSD::DidLaunch() {}
-
-addr_t ProcessFreeBSD::GetImageInfoAddress() {
-  Target *target = &GetTarget();
-  ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
-  Address addr = obj_file->GetImageInfoAddress(target);
-
-  if (addr.IsValid())
-    return addr.GetLoadAddress(target);
-  return LLDB_INVALID_ADDRESS;
-}
-
-Status ProcessFreeBSD::DoHalt(bool &caused_stop) {
-  Status error;
-
-  if (IsStopped()) {
-    caused_stop = false;
-  } else if (kill(GetID(), SIGSTOP)) {
-    caused_stop = false;
-    error.SetErrorToErrno();
-  } else {
-    caused_stop = true;
-  }
-  return error;
-}
-
-Status ProcessFreeBSD::DoSignal(int signal) {
-  Status error;
-
-  if (kill(GetID(), signal))
-    error.SetErrorToErrno();
-
-  return error;
-}
-
-Status ProcessFreeBSD::DoDestroy() {
-  Status error;
-
-  if (!HasExited()) {
-    assert(m_monitor);
-    m_exit_now = true;
-    if (GetID() == LLDB_INVALID_PROCESS_ID) {
-      error.SetErrorString("invalid process id");
-      return error;
-    }
-    if (!m_monitor->Kill()) {
-      error.SetErrorToErrno();
-      return error;
-    }
-
-    SetPrivateState(eStateExited);
-  }
-
-  return error;
-}
-
-void ProcessFreeBSD::DoDidExec() {
-  Target *target = &GetTarget();
-  if (target) {
-    PlatformSP platform_sp(target->GetPlatform());
-    assert(platform_sp.get());
-    if (platform_sp) {
-      ProcessInstanceInfo process_info;
-      platform_sp->GetProcessInfo(GetID(), process_info);
-      ModuleSP exe_module_sp;
-      ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
-                                 target->GetArchitecture());
-      FileSpecList executable_search_paths(
-          Target::GetDefaultExecutableSearchPaths());
-      Status error = platform_sp->ResolveExecutable(
-          exe_module_spec, exe_module_sp,
-          executable_search_paths.GetSize() ? &executable_search_paths : NULL);
-      if (!error.Success())
-        return;
-      target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
-    }
-  }
-}
-
-bool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
-  bool added_to_set = false;
-  ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
-  if (it == m_seen_initial_stop.end()) {
-    m_seen_initial_stop.insert(stop_tid);
-    added_to_set = true;
-  }
-  return added_to_set;
-}
-
-bool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
-  return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
-}
-
-FreeBSDThread *
-ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
-                                       lldb::tid_t tid) {
-  return new FreeBSDThread(process, tid);
-}
-
-void ProcessFreeBSD::RefreshStateAfterStop() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size());
-
-  std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
-
-  // This method used to only handle one message.  Changing it to loop allows
-  // it to handle the case where we hit a breakpoint while handling a different
-  // breakpoint.
-  while (!m_message_queue.empty()) {
-    ProcessMessage &message = m_message_queue.front();
-
-    // Resolve the thread this message corresponds to and pass it along.
-    lldb::tid_t tid = message.GetTID();
-    LLDB_LOGV(log, " message_queue size = {0}, pid = {1}",
-              m_message_queue.size(), tid);
-
-    m_thread_list.RefreshStateAfterStop();
-
-    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-        GetThreadList().FindThreadByID(tid, false).get());
-    if (thread)
-      thread->Notify(message);
-
-    if (message.GetKind() == ProcessMessage::eExitMessage) {
-      // FIXME: We should tell the user about this, but the limbo message is
-      // probably better for that.
-      LLDB_LOG(log, "removing thread, tid = {0}", tid);
-      std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-
-      ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
-      thread_sp.reset();
-      m_seen_initial_stop.erase(tid);
-    }
-
-    m_message_queue.pop();
-  }
-}
-
-bool ProcessFreeBSD::IsAlive() {
-  StateType state = GetPrivateState();
-  return state != eStateDetached && state != eStateExited &&
-         state != eStateInvalid && state != eStateUnloaded;
-}
-
-size_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
-                                    Status &error) {
-  assert(m_monitor);
-  return m_monitor->ReadMemory(vm_addr, buf, size, error);
-}
-
-size_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
-                                     size_t size, Status &error) {
-  assert(m_monitor);
-  return m_monitor->WriteMemory(vm_addr, buf, size, error);
-}
-
-addr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
-                                        Status &error) {
-  addr_t allocated_addr = LLDB_INVALID_ADDRESS;
-
-  unsigned prot = 0;
-  if (permissions & lldb::ePermissionsReadable)
-    prot |= eMmapProtRead;
-  if (permissions & lldb::ePermissionsWritable)
-    prot |= eMmapProtWrite;
-  if (permissions & lldb::ePermissionsExecutable)
-    prot |= eMmapProtExec;
-
-  if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
-                       eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
-    m_addr_to_mmap_size[allocated_addr] = size;
-    error.Clear();
-  } else {
-    allocated_addr = LLDB_INVALID_ADDRESS;
-    error.SetErrorStringWithFormat(
-        "unable to allocate %zu bytes of memory with permissions %s", size,
-        GetPermissionsAsCString(permissions));
-  }
-
-  return allocated_addr;
-}
-
-Status ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
-  Status error;
-  MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
-  if (pos != m_addr_to_mmap_size.end() &&
-      InferiorCallMunmap(this, addr, pos->second))
-    m_addr_to_mmap_size.erase(pos);
-  else
-    error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
-                                   addr);
-
-  return error;
-}
-
-size_t
-ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
-  static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
-  static const uint8_t g_i386_opcode[] = {0xCC};
-
-  ArchSpec arch = GetTarget().GetArchitecture();
-  const uint8_t *opcode = NULL;
-  size_t opcode_size = 0;
-
-  switch (arch.GetMachine()) {
-  default:
-    assert(false && "CPU type not supported!");
-    break;
-
-  case llvm::Triple::arm: {
-    // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
-    // linux kernel does otherwise.
-    static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
-    static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
-
-    lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
-    AddressClass addr_class = AddressClass::eUnknown;
-
-    if (bp_loc_sp)
-      addr_class = bp_loc_sp->GetAddress().GetAddressClass();
-
-    if (addr_class == AddressClass::eCodeAlternateISA ||
-        (addr_class == AddressClass::eUnknown &&
-         bp_loc_sp->GetAddress().GetOffset() & 1)) {
-      opcode = g_thumb_breakpoint_opcode;
-      opcode_size = sizeof(g_thumb_breakpoint_opcode);
-    } else {
-      opcode = g_arm_breakpoint_opcode;
-      opcode_size = sizeof(g_arm_breakpoint_opcode);
-    }
-  } break;
-  case llvm::Triple::aarch64:
-    opcode = g_aarch64_opcode;
-    opcode_size = sizeof(g_aarch64_opcode);
-    break;
-
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    opcode = g_i386_opcode;
-    opcode_size = sizeof(g_i386_opcode);
-    break;
-  }
-
-  bp_site->SetTrapOpcode(opcode, opcode_size);
-  return opcode_size;
-}
-
-Status ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
-  if (bp_site->HardwareRequired())
-    return Status("Hardware breakpoints are not supported.");
-
-  return EnableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
-  return DisableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
-  Status error;
-  if (wp) {
-    user_id_t watchID = wp->GetID();
-    addr_t addr = wp->GetLoadAddress();
-    Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-    LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
-              watchID);
-    if (wp->IsEnabled()) {
-      LLDB_LOGF(log,
-                "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
-                ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
-                watchID, (uint64_t)addr);
-      return error;
-    }
-
-    // Try to find a vacant watchpoint slot in the inferiors' main thread
-    uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
-    std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-        m_thread_list.GetThreadAtIndex(0, false).get());
-
-    if (thread)
-      wp_hw_index = thread->FindVacantWatchpointIndex();
-
-    if (wp_hw_index == LLDB_INVALID_INDEX32) {
-      error.SetErrorString("Setting hardware watchpoint failed.");
-    } else {
-      wp->SetHardwareIndex(wp_hw_index);
-      bool wp_enabled = true;
-      uint32_t thread_count = m_thread_list.GetSize(false);
-      for (uint32_t i = 0; i < thread_count; ++i) {
-        thread = static_cast<FreeBSDThread *>(
-            m_thread_list.GetThreadAtIndex(i, false).get());
-        if (thread)
-          wp_enabled &= thread->EnableHardwareWatchpoint(wp);
-        else
-          wp_enabled = false;
-      }
-      if (wp_enabled) {
-        wp->SetEnabled(true, notify);
-        return error;
-      } else {
-        // Watchpoint enabling failed on at least one of the threads so roll
-        // back all of them
-        DisableWatchpoint(wp, false);
-        error.SetErrorString("Setting hardware watchpoint failed");
-      }
-    }
-  } else
-    error.SetErrorString("Watchpoint argument was NULL.");
-  return error;
-}
-
-Status ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
-  Status error;
-  if (wp) {
-    user_id_t watchID = wp->GetID();
-    addr_t addr = wp->GetLoadAddress();
-    Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-    LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
-              watchID);
-    if (!wp->IsEnabled()) {
-      LLDB_LOGF(log,
-                "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
-                ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
-                watchID, (uint64_t)addr);
-      // This is needed (for now) to keep watchpoints disabled correctly
-      wp->SetEnabled(false, notify);
-      return error;
-    }
-
-    if (wp->IsHardware()) {
-      bool wp_disabled = true;
-      std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-      uint32_t thread_count = m_thread_list.GetSize(false);
-      for (uint32_t i = 0; i < thread_count; ++i) {
-        FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-            m_thread_list.GetThreadAtIndex(i, false).get());
-        if (thread)
-          wp_disabled &= thread->DisableHardwareWatchpoint(wp);
-        else
-          wp_disabled = false;
-      }
-      if (wp_disabled) {
-        wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
-        wp->SetEnabled(false, notify);
-        return error;
-      } else
-        error.SetErrorString("Disabling hardware watchpoint failed");
-    }
-  } else
-    error.SetErrorString("Watchpoint argument was NULL.");
-  return error;
-}
-
-Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
-  Status error;
-  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-  FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-      m_thread_list.GetThreadAtIndex(0, false).get());
-  if (thread)
-    num = thread->NumSupportedHardwareWatchpoints();
-  else
-    error.SetErrorString("Process does not exist.");
-  return error;
-}
-
-Status ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
-  Status error = GetWatchpointSupportInfo(num);
-  // Watchpoints trigger and halt the inferior after the corresponding
-  // instruction has been executed.
-  after = true;
-  return error;
-}
-
-uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
-  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-  // Do not allow recursive updates.
-  return m_thread_list.GetSize(false);
-}
-
-ByteOrder ProcessFreeBSD::GetByteOrder() const {
-  // FIXME: We should be able to extract this value directly.  See comment in
-  // ProcessFreeBSD().
-  return m_byte_order;
-}
-
-size_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Status &error) {
-  ssize_t status;
-  if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
-    error.SetErrorToErrno();
-    return 0;
-  }
-  return status;
-}
-
-// Utility functions.
-
-bool ProcessFreeBSD::HasExited() {
-  switch (GetPrivateState()) {
-  default:
-    break;
-
-  case eStateDetached:
-  case eStateExited:
-    return true;
-  }
-
-  return false;
-}
-
-bool ProcessFreeBSD::IsStopped() {
-  switch (GetPrivateState()) {
-  default:
-    break;
-
-  case eStateStopped:
-  case eStateCrashed:
-  case eStateSuspended:
-    return true;
-  }
-
-  return false;
-}
-
-bool ProcessFreeBSD::IsAThreadRunning() {
-  bool is_running = false;
-  std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
-  uint32_t thread_count = m_thread_list.GetSize(false);
-  for (uint32_t i = 0; i < thread_count; ++i) {
-    FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-        m_thread_list.GetThreadAtIndex(i, false).get());
-    StateType thread_state = thread->GetState();
-    if (thread_state == eStateRunning || thread_state == eStateStepping) {
-      is_running = true;
-      break;
-    }
-  }
-  return is_running;
-}
-
-lldb_private::DataExtractor ProcessFreeBSD::GetAuxvData() {
-  // If we're the local platform, we can ask the host for auxv data.
-  PlatformSP platform_sp = GetTarget().GetPlatform();
-  assert(platform_sp && platform_sp->IsHost());
-
-  int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()};
-  size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
-  DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0));
-
-  if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) {
-    perror("sysctl failed on auxv");
-    buf_sp.reset();
-  }
-
-  return DataExtractor(buf_sp, GetByteOrder(), GetAddressByteSize());
-}
-
-struct EmulatorBaton {
-  ProcessFreeBSD *m_process;
-  RegisterContext *m_reg_context;
-
-  // eRegisterKindDWARF -> RegisterValue
-  std::unordered_map<uint32_t, RegisterValue> m_register_values;
-
-  EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context)
-      : m_process(process), m_reg_context(reg_context) {}
-};
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                 const EmulateInstruction::Context &context,
-                                 lldb::addr_t addr, void *dst, size_t length) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
-  Status error;
-  size_t bytes_read =
-      emulator_baton->m_process->DoReadMemory(addr, dst, length, error);
-  if (!error.Success())
-    bytes_read = 0;
-  return bytes_read;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                 const RegisterInfo *reg_info,
-                                 RegisterValue &reg_value) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
-  auto it = emulator_baton->m_register_values.find(
-      reg_info->kinds[eRegisterKindDWARF]);
-  if (it != emulator_baton->m_register_values.end()) {
-    reg_value = it->second;
-    return true;
-  }
-
-  // The emulator only fills in the dwarf register numbers (and in some cases
-  // the generic register numbers). Get the full register info from the
-  // register context based on the dwarf register numbers.
-  const RegisterInfo *full_reg_info =
-      emulator_baton->m_reg_context->GetRegisterInfo(
-          eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
-
-  bool error =
-      emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
-  return error;
-}
-
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  const RegisterInfo *reg_info,
-                                  const RegisterValue &reg_value) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-  emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
-      reg_value;
-  return true;
-}
-
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  lldb::addr_t addr, const void *dst,
-                                  size_t length) {
-  return length;
-}
-
-bool ProcessFreeBSD::SingleStepBreakpointHit(
-    void *baton, lldb_private::StoppointCallbackContext *context,
-    lldb::user_id_t break_id, lldb::user_id_t break_loc_id) {
-  return false;
-}
-
-Status ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
-                                                       lldb::addr_t addr) {
-  Status error;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  if (log) {
-    LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
-    LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
-              addr);
-  }
-
-  // Validate the address.
-  if (addr == LLDB_INVALID_ADDRESS)
-    return Status("ProcessFreeBSD::%s invalid load address specified.",
-                  __FUNCTION__);
-
-  Breakpoint *const sw_step_break =
-      m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
-  sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
-  sw_step_break->SetBreakpointKind("software-single-step");
-
-  LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
-            __FUNCTION__, addr);
-
-  m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
-  return Status();
-}
-
-bool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) {
-  ThreadSP thread = GetThreadList().FindThreadByID(tid);
-  if (!thread)
-    return false;
-
-  assert(thread->GetRegisterContext());
-  lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC();
-
-  const auto &iter = m_threads_stepping_with_breakpoint.find(tid);
-  if (iter == m_threads_stepping_with_breakpoint.end())
-    return false;
-
-  lldb::break_id_t bp_id = iter->second;
-  BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id);
-  if (!bp)
-    return false;
-
-  BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc);
-  if (!bp_loc)
-    return false;
-
-  GetTarget().RemoveBreakpointByID(bp_id);
-  m_threads_stepping_with_breakpoint.erase(tid);
-  return true;
-}
-
-bool ProcessFreeBSD::SupportHardwareSingleStepping() const {
-  lldb_private::ArchSpec arch = GetTarget().GetArchitecture();
-  if (arch.GetMachine() == llvm::Triple::arm || arch.IsMIPS())
-    return false;
-  return true;
-}
-
-Status ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) {
-  std::unique_ptr<EmulateInstruction> emulator_up(
-      EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(),
-                                     eInstructionTypePCModifying, nullptr));
-
-  if (emulator_up == nullptr)
-    return Status("Instruction emulator not found!");
-
-  FreeBSDThread *thread = static_cast<FreeBSDThread *>(
-      m_thread_list.FindThreadByID(tid, false).get());
-  if (thread == NULL)
-    return Status("Thread not found not found!");
-
-  lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext();
-
-  EmulatorBaton baton(this, register_context_sp.get());
-  emulator_up->SetBaton(&baton);
-  emulator_up->SetReadMemCallback(&ReadMemoryCallback);
-  emulator_up->SetReadRegCallback(&ReadRegisterCallback);
-  emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
-  emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
-
-  if (!emulator_up->ReadInstruction())
-    return Status("Read instruction failed!");
-
-  bool emulation_result =
-      emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
-  const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
-      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-  auto pc_it =
-      baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
-
-  lldb::addr_t next_pc;
-  if (emulation_result) {
-    assert(pc_it != baton.m_register_values.end() &&
-           "Emulation was successful but PC wasn't updated");
-    next_pc = pc_it->second.GetAsUInt64();
-  } else if (pc_it == baton.m_register_values.end()) {
-    // Emulate instruction failed and it haven't changed PC. Advance PC with
-    // the size of the current opcode because the emulation of all
-    // PC modifying instruction should be successful. The failure most
-    // likely caused by a not supported instruction which don't modify PC.
-    next_pc =
-        register_context_sp->GetPC() + emulator_up->GetOpcode().GetByteSize();
-  } else {
-    // The instruction emulation failed after it modified the PC. It is an
-    // unknown error where we can't continue because the next instruction is
-    // modifying the PC but we don't  know how.
-    return Status("Instruction emulation failed unexpectedly");
-  }
-
-  SetSoftwareSingleStepBreakpoint(tid, next_pc);
-  return Status();
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
deleted file mode 100644
index b60bcd2..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
+++ /dev/null
@@ -1,221 +0,0 @@
-//===-- ProcessFreeBSD.h ------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessFreeBSD_H_
-#define liblldb_ProcessFreeBSD_H_
-
-#include "Plugins/Process/POSIX/ProcessMessage.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ThreadList.h"
-#include <mutex>
-#include <queue>
-#include <set>
-
-class ProcessMonitor;
-class FreeBSDThread;
-
-class ProcessFreeBSD : public lldb_private::Process {
-
-public:
-  // Static functions.
-  static lldb::ProcessSP
-  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                 const lldb_private::FileSpec *crash_file_path,
-                 bool can_connect);
-
-  static void Initialize();
-
-  static void Terminate();
-
-  static lldb_private::ConstString GetPluginNameStatic();
-
-  static const char *GetPluginDescriptionStatic();
-
-  // Constructors and destructors
-  ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                 lldb::UnixSignalsSP &unix_signals_sp);
-
-  ~ProcessFreeBSD();
-
-  virtual lldb_private::Status WillResume() override;
-
-  // PluginInterface protocol
-  virtual lldb_private::ConstString GetPluginName() override;
-
-  virtual uint32_t GetPluginVersion() override;
-
-public:
-  // Process protocol.
-  void Finalize() override;
-
-  bool CanDebug(lldb::TargetSP target_sp,
-                bool plugin_specified_by_name) override;
-
-  lldb_private::Status WillLaunch(lldb_private::Module *module) override;
-
-  lldb_private::Status DoAttachToProcessWithID(
-      lldb::pid_t pid,
-      const lldb_private::ProcessAttachInfo &attach_info) override;
-
-  lldb_private::Status
-  DoLaunch(lldb_private::Module *exe_module,
-           lldb_private::ProcessLaunchInfo &launch_info) override;
-
-  void DidLaunch() override;
-
-  lldb_private::Status DoResume() override;
-
-  lldb_private::Status DoHalt(bool &caused_stop) override;
-
-  lldb_private::Status DoDetach(bool keep_stopped) override;
-
-  lldb_private::Status DoSignal(int signal) override;
-
-  lldb_private::Status DoDestroy() override;
-
-  void DoDidExec() override;
-
-  void RefreshStateAfterStop() override;
-
-  bool IsAlive() override;
-
-  size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
-                      lldb_private::Status &error) override;
-
-  size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
-                       lldb_private::Status &error) override;
-
-  lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
-                                lldb_private::Status &error) override;
-
-  lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
-
-  virtual size_t
-  GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site);
-
-  lldb_private::Status
-  EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
-  lldb_private::Status
-  DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
-  lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
-                                        bool notify = true) override;
-
-  lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
-                                         bool notify = true) override;
-
-  lldb_private::Status GetWatchpointSupportInfo(uint32_t &num) override;
-
-  lldb_private::Status GetWatchpointSupportInfo(uint32_t &num,
-                                                bool &after) override;
-
-  virtual uint32_t UpdateThreadListIfNeeded();
-
-  bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
-                          lldb_private::ThreadList &new_thread_list) override;
-
-  virtual lldb::ByteOrder GetByteOrder() const;
-
-  lldb::addr_t GetImageInfoAddress() override;
-
-  size_t PutSTDIN(const char *buf, size_t len,
-                  lldb_private::Status &error) override;
-
-  lldb_private::DataExtractor GetAuxvData() override;
-
-  // ProcessFreeBSD internal API.
-
-  /// Registers the given message with this process.
-  virtual void SendMessage(const ProcessMessage &message);
-
-  ProcessMonitor &GetMonitor() {
-    assert(m_monitor);
-    return *m_monitor;
-  }
-
-  lldb_private::FileSpec
-  GetFileSpec(const lldb_private::FileAction *file_action,
-              const lldb_private::FileSpec &default_file_spec,
-              const lldb_private::FileSpec &dbg_pts_file_spec);
-
-  /// Adds the thread to the list of threads for which we have received the
-  /// initial stopping signal.
-  /// The \p stop_tid parameter indicates the thread which the stop happened
-  /// for.
-  bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
-
-  bool WaitingForInitialStop(lldb::tid_t stop_tid);
-
-  virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
-                                                lldb::tid_t tid);
-
-  static bool SingleStepBreakpointHit(
-      void *baton, lldb_private::StoppointCallbackContext *context,
-      lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-
-  lldb_private::Status SetupSoftwareSingleStepping(lldb::tid_t tid);
-
-  lldb_private::Status SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
-                                                       lldb::addr_t addr);
-
-  bool IsSoftwareStepBreakpoint(lldb::tid_t tid);
-
-  bool SupportHardwareSingleStepping() const;
-
-  typedef std::vector<lldb::tid_t> tid_collection;
-  tid_collection &GetStepTids() { return m_step_tids; }
-
-protected:
-  static const size_t MAX_TRAP_OPCODE_SIZE = 8;
-
-  /// Target byte order.
-  lldb::ByteOrder m_byte_order;
-
-  /// Process monitor;
-  ProcessMonitor *m_monitor;
-
-  /// The module we are executing.
-  lldb_private::Module *m_module;
-
-  /// Message queue notifying this instance of inferior process state changes.
-  std::recursive_mutex m_message_mutex;
-  std::queue<ProcessMessage> m_message_queue;
-
-  /// Drive any exit events to completion.
-  bool m_exit_now;
-
-  /// Returns true if the process has exited.
-  bool HasExited();
-
-  /// Returns true if the process is stopped.
-  bool IsStopped();
-
-  /// Returns true if at least one running is currently running
-  bool IsAThreadRunning();
-
-  typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
-  MMapMap m_addr_to_mmap_size;
-
-  typedef std::set<lldb::tid_t> ThreadStopSet;
-  /// Every thread begins with a stop signal. This keeps track
-  /// of the threads for which we have received the stop signal.
-  ThreadStopSet m_seen_initial_stop;
-
-  friend class FreeBSDThread;
-
-  tid_collection m_suspend_tids;
-  tid_collection m_run_tids;
-  tid_collection m_step_tids;
-  std::map<lldb::tid_t, lldb::break_id_t> m_threads_stepping_with_breakpoint;
-
-  int m_resume_signo;
-};
-
-#endif // liblldb_ProcessFreeBSD_H_
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
deleted file mode 100644
index 4637458..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ /dev/null
@@ -1,1424 +0,0 @@
-//===-- ProcessMonitor.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 <errno.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "lldb/Host/Host.h"
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Scalar.h"
-#include "lldb/Utility/Status.h"
-#include "llvm/Support/Errno.h"
-
-#include "FreeBSDThread.h"
-#include "Plugins/Process/POSIX/CrashReason.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Wrapper for ptrace to catch errors and log calls.
-
-const char *Get_PT_IO_OP(int op) {
-  switch (op) {
-  case PIOD_READ_D:
-    return "READ_D";
-  case PIOD_WRITE_D:
-    return "WRITE_D";
-  case PIOD_READ_I:
-    return "READ_I";
-  case PIOD_WRITE_I:
-    return "WRITE_I";
-  default:
-    return "Unknown op";
-  }
-}
-
-// Wrapper for ptrace to catch errors and log calls. Note that ptrace sets
-// errno on error because -1 is reserved as a valid result.
-extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
-                          const char *reqName, const char *file, int line) {
-  long int result;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  if (log) {
-    LLDB_LOGF(log,
-              "ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
-              reqName, pid, addr, data, file, line);
-    if (req == PT_IO) {
-      struct ptrace_io_desc *pi = (struct ptrace_io_desc *)addr;
-
-      LLDB_LOGF(log, "PT_IO: op=%s offs=%zx size=%zu",
-                Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
-    }
-  }
-
-  // PtraceDisplayBytes(req, data);
-
-  errno = 0;
-  result = ptrace(req, pid, (caddr_t)addr, data);
-
-  // PtraceDisplayBytes(req, data);
-
-  if (log && errno != 0) {
-    const char *str;
-    switch (errno) {
-    case ESRCH:
-      str = "ESRCH";
-      break;
-    case EINVAL:
-      str = "EINVAL";
-      break;
-    case EBUSY:
-      str = "EBUSY";
-      break;
-    case EPERM:
-      str = "EPERM";
-      break;
-    default:
-      str = "<unknown>";
-    }
-    LLDB_LOGF(log, "ptrace() failed; errno=%d (%s)", errno, str);
-  }
-
-  if (log) {
-#ifdef __amd64__
-    if (req == PT_GETREGS) {
-      struct reg *r = (struct reg *)addr;
-
-      LLDB_LOGF(log, "PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
-                r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
-    }
-    if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
-      struct dbreg *r = (struct dbreg *)addr;
-      char setget = (req == PT_GETDBREGS) ? 'G' : 'S';
-
-      for (int i = 0; i <= 7; i++)
-        LLDB_LOGF(log, "PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
-    }
-#endif
-  }
-
-  return result;
-}
-
-// Wrapper for ptrace when logging is not required. Sets errno to 0 prior to
-// calling ptrace.
-extern long PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data) {
-  long result = 0;
-  errno = 0;
-  result = ptrace(req, pid, (caddr_t)addr, data);
-  return result;
-}
-
-#define PTRACE(req, pid, addr, data)                                           \
-  PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
-
-// Static implementations of ProcessMonitor::ReadMemory and
-// ProcessMonitor::WriteMemory.  This enables mutual recursion between these
-// functions without needed to go thru the thread funnel.
-
-static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf,
-                           size_t size, Status &error) {
-  struct ptrace_io_desc pi_desc;
-
-  pi_desc.piod_op = PIOD_READ_D;
-  pi_desc.piod_offs = (void *)vm_addr;
-  pi_desc.piod_addr = buf;
-  pi_desc.piod_len = size;
-
-  if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
-    error.SetErrorToErrno();
-    return 0;
-  }
-  return pi_desc.piod_len;
-}
-
-static size_t DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr,
-                            const void *buf, size_t size, Status &error) {
-  struct ptrace_io_desc pi_desc;
-
-  pi_desc.piod_op = PIOD_WRITE_D;
-  pi_desc.piod_offs = (void *)vm_addr;
-  pi_desc.piod_addr = const_cast<void *>(buf);
-  pi_desc.piod_len = size;
-
-  if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) {
-    error.SetErrorToErrno();
-    return 0;
-  }
-  return pi_desc.piod_len;
-}
-
-// Simple helper function to ensure flags are enabled on the given file
-// descriptor.
-static bool EnsureFDFlags(int fd, int flags, Status &error) {
-  int status;
-
-  if ((status = fcntl(fd, F_GETFL)) == -1) {
-    error.SetErrorToErrno();
-    return false;
-  }
-
-  if (fcntl(fd, F_SETFL, status | flags) == -1) {
-    error.SetErrorToErrno();
-    return false;
-  }
-
-  return true;
-}
-
-/// \class Operation
-/// Represents a ProcessMonitor operation.
-///
-/// Under FreeBSD, it is not possible to ptrace() from any other thread but
-/// the one that spawned or attached to the process from the start.
-/// Therefore, when a ProcessMonitor is asked to deliver or change the state
-/// of an inferior process the operation must be "funneled" to a specific
-/// thread to perform the task.  The Operation class provides an abstract base
-/// for all services the ProcessMonitor must perform via the single virtual
-/// function Execute, thus encapsulating the code that needs to run in the
-/// privileged context.
-class Operation {
-public:
-  virtual ~Operation() {}
-  virtual void Execute(ProcessMonitor *monitor) = 0;
-};
-
-/// \class ReadOperation
-/// Implements ProcessMonitor::ReadMemory.
-class ReadOperation : public Operation {
-public:
-  ReadOperation(lldb::addr_t addr, void *buff, size_t size, Status &error,
-                size_t &result)
-      : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
-        m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::addr_t m_addr;
-  void *m_buff;
-  size_t m_size;
-  Status &m_error;
-  size_t &m_result;
-};
-
-void ReadOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-
-  m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
-}
-
-/// \class WriteOperation
-/// Implements ProcessMonitor::WriteMemory.
-class WriteOperation : public Operation {
-public:
-  WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
-                 Status &error, size_t &result)
-      : m_addr(addr), m_buff(buff), m_size(size), m_error(error),
-        m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::addr_t m_addr;
-  const void *m_buff;
-  size_t m_size;
-  Status &m_error;
-  size_t &m_result;
-};
-
-void WriteOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-
-  m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
-}
-
-/// \class ReadRegOperation
-/// Implements ProcessMonitor::ReadRegisterValue.
-class ReadRegOperation : public Operation {
-public:
-  ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
-                   RegisterValue &value, bool &result)
-      : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
-        m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor);
-
-private:
-  lldb::tid_t m_tid;
-  unsigned m_offset;
-  unsigned m_size;
-  RegisterValue &m_value;
-  bool &m_result;
-};
-
-void ReadRegOperation::Execute(ProcessMonitor *monitor) {
-  struct reg regs;
-  int rc;
-
-  if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
-    m_result = false;
-  } else {
-    // 'struct reg' contains only 32- or 64-bit register values.  Punt on
-    // others.  Also, not all entries may be uintptr_t sized, such as 32-bit
-    // processes on powerpc64 (probably the same for i386 on amd64)
-    if (m_size == sizeof(uint32_t))
-      m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
-    else if (m_size == sizeof(uint64_t))
-      m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
-    else
-      memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
-    m_result = true;
-  }
-}
-
-/// \class WriteRegOperation
-/// Implements ProcessMonitor::WriteRegisterValue.
-class WriteRegOperation : public Operation {
-public:
-  WriteRegOperation(lldb::tid_t tid, unsigned offset,
-                    const RegisterValue &value, bool &result)
-      : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  unsigned m_offset;
-  const RegisterValue &m_value;
-  bool &m_result;
-};
-
-void WriteRegOperation::Execute(ProcessMonitor *monitor) {
-  struct reg regs;
-
-  if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
-    m_result = false;
-    return;
-  }
-  *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
-      (uintptr_t)m_value.GetAsUInt64();
-  if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class ReadDebugRegOperation
-/// Implements ProcessMonitor::ReadDebugRegisterValue.
-class ReadDebugRegOperation : public Operation {
-public:
-  ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
-                        RegisterValue &value, bool &result)
-      : m_tid(tid), m_offset(offset), m_size(size), m_value(value),
-        m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  unsigned m_offset;
-  unsigned m_size;
-  RegisterValue &m_value;
-  bool &m_result;
-};
-
-void ReadDebugRegOperation::Execute(ProcessMonitor *monitor) {
-  struct dbreg regs;
-  int rc;
-
-  if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
-    m_result = false;
-  } else {
-    if (m_size == sizeof(uintptr_t))
-      m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
-    else
-      memcpy((void *)&m_value, (((caddr_t)&regs) + m_offset), m_size);
-    m_result = true;
-  }
-}
-
-/// \class WriteDebugRegOperation
-/// Implements ProcessMonitor::WriteDebugRegisterValue.
-class WriteDebugRegOperation : public Operation {
-public:
-  WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
-                         const RegisterValue &value, bool &result)
-      : m_tid(tid), m_offset(offset), m_value(value), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  unsigned m_offset;
-  const RegisterValue &m_value;
-  bool &m_result;
-};
-
-void WriteDebugRegOperation::Execute(ProcessMonitor *monitor) {
-  struct dbreg regs;
-
-  if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
-    m_result = false;
-    return;
-  }
-  *(uintptr_t *)(((caddr_t)&regs) + m_offset) =
-      (uintptr_t)m_value.GetAsUInt64();
-  if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class ReadGPROperation
-/// Implements ProcessMonitor::ReadGPR.
-class ReadGPROperation : public Operation {
-public:
-  ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
-      : m_tid(tid), m_buf(buf), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  void *m_buf;
-  bool &m_result;
-};
-
-void ReadGPROperation::Execute(ProcessMonitor *monitor) {
-  int rc;
-
-  errno = 0;
-  rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
-  if (errno != 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class ReadFPROperation
-/// Implements ProcessMonitor::ReadFPR.
-class ReadFPROperation : public Operation {
-public:
-  ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
-      : m_tid(tid), m_buf(buf), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  void *m_buf;
-  bool &m_result;
-};
-
-void ReadFPROperation::Execute(ProcessMonitor *monitor) {
-  if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class WriteGPROperation
-/// Implements ProcessMonitor::WriteGPR.
-class WriteGPROperation : public Operation {
-public:
-  WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
-      : m_tid(tid), m_buf(buf), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  void *m_buf;
-  bool &m_result;
-};
-
-void WriteGPROperation::Execute(ProcessMonitor *monitor) {
-  if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class WriteFPROperation
-/// Implements ProcessMonitor::WriteFPR.
-class WriteFPROperation : public Operation {
-public:
-  WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
-      : m_tid(tid), m_buf(buf), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  void *m_buf;
-  bool &m_result;
-};
-
-void WriteFPROperation::Execute(ProcessMonitor *monitor) {
-  if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class ResumeOperation
-/// Implements ProcessMonitor::Resume.
-class ResumeOperation : public Operation {
-public:
-  ResumeOperation(uint32_t signo, bool &result)
-      : m_signo(signo), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  uint32_t m_signo;
-  bool &m_result;
-};
-
-void ResumeOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-  int data = 0;
-
-  if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
-    data = m_signo;
-
-  if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data)) {
-    Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-    LLDB_LOG(log, "ResumeOperation ({0}) failed: {1}", pid,
-             llvm::sys::StrError(errno));
-    m_result = false;
-  } else
-    m_result = true;
-}
-
-/// \class SingleStepOperation
-/// Implements ProcessMonitor::SingleStep.
-class SingleStepOperation : public Operation {
-public:
-  SingleStepOperation(uint32_t signo, bool &result)
-      : m_signo(signo), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  uint32_t m_signo;
-  bool &m_result;
-};
-
-void SingleStepOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-  int data = 0;
-
-  if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
-    data = m_signo;
-
-  if (PTRACE(PT_STEP, pid, NULL, data))
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class LwpInfoOperation
-/// Implements ProcessMonitor::GetLwpInfo.
-class LwpInfoOperation : public Operation {
-public:
-  LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
-      : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  void *m_info;
-  bool &m_result;
-  int &m_err;
-};
-
-void LwpInfoOperation::Execute(ProcessMonitor *monitor) {
-  struct ptrace_lwpinfo plwp;
-
-  if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
-    m_result = false;
-    m_err = errno;
-  } else {
-    memcpy(m_info, &plwp, sizeof(plwp));
-    m_result = true;
-  }
-}
-
-/// \class ThreadSuspendOperation
-/// Implements ProcessMonitor::ThreadSuspend.
-class ThreadSuspendOperation : public Operation {
-public:
-  ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
-      : m_tid(tid), m_suspend(suspend), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  bool m_suspend;
-  bool &m_result;
-};
-
-void ThreadSuspendOperation::Execute(ProcessMonitor *monitor) {
-  m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
-}
-
-/// \class EventMessageOperation
-/// Implements ProcessMonitor::GetEventMessage.
-class EventMessageOperation : public Operation {
-public:
-  EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
-      : m_tid(tid), m_message(message), m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  lldb::tid_t m_tid;
-  unsigned long *m_message;
-  bool &m_result;
-};
-
-void EventMessageOperation::Execute(ProcessMonitor *monitor) {
-  struct ptrace_lwpinfo plwp;
-
-  if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
-    m_result = false;
-  else {
-    if (plwp.pl_flags & PL_FLAG_FORKED) {
-      *m_message = plwp.pl_child_pid;
-      m_result = true;
-    } else
-      m_result = false;
-  }
-}
-
-/// \class KillOperation
-/// Implements ProcessMonitor::Kill.
-class KillOperation : public Operation {
-public:
-  KillOperation(bool &result) : m_result(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  bool &m_result;
-};
-
-void KillOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-
-  if (PTRACE(PT_KILL, pid, NULL, 0))
-    m_result = false;
-  else
-    m_result = true;
-}
-
-/// \class DetachOperation
-/// Implements ProcessMonitor::Detach.
-class DetachOperation : public Operation {
-public:
-  DetachOperation(Status &result) : m_error(result) {}
-
-  void Execute(ProcessMonitor *monitor) override;
-
-private:
-  Status &m_error;
-};
-
-void DetachOperation::Execute(ProcessMonitor *monitor) {
-  lldb::pid_t pid = monitor->GetPID();
-
-  if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
-    m_error.SetErrorToErrno();
-}
-
-ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
-    : m_monitor(monitor) {
-  sem_init(&m_semaphore, 0, 0);
-}
-
-ProcessMonitor::OperationArgs::~OperationArgs() { sem_destroy(&m_semaphore); }
-
-ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
-                                       lldb_private::Module *module,
-                                       char const **argv, Environment env,
-                                       const FileSpec &stdin_file_spec,
-                                       const FileSpec &stdout_file_spec,
-                                       const FileSpec &stderr_file_spec,
-                                       const FileSpec &working_dir)
-    : OperationArgs(monitor), m_module(module), m_argv(argv),
-      m_env(std::move(env)), m_stdin_file_spec(stdin_file_spec),
-      m_stdout_file_spec(stdout_file_spec),
-      m_stderr_file_spec(stderr_file_spec), m_working_dir(working_dir) {}
-
-ProcessMonitor::LaunchArgs::~LaunchArgs() {}
-
-ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid)
-    : OperationArgs(monitor), m_pid(pid) {}
-
-ProcessMonitor::AttachArgs::~AttachArgs() {}
-
-/// The basic design of the ProcessMonitor is built around two threads.
-///
-/// One thread (@see SignalThread) simply blocks on a call to waitpid()
-/// looking for changes in the debugee state.  When a change is detected a
-/// ProcessMessage is sent to the associated ProcessFreeBSD instance.  This
-/// thread "drives" state changes in the debugger.
-///
-/// The second thread (@see OperationThread) is responsible for two things 1)
-/// launching or attaching to the inferior process, and then 2) servicing
-/// operations such as register reads/writes, stepping, etc.  See the comments
-/// on the Operation class for more info as to why this is needed.
-ProcessMonitor::ProcessMonitor(
-    ProcessFreeBSD *process, Module *module, const char *argv[],
-    Environment env, const FileSpec &stdin_file_spec,
-    const FileSpec &stdout_file_spec, const FileSpec &stderr_file_spec,
-    const FileSpec &working_dir,
-    const lldb_private::ProcessLaunchInfo & /* launch_info */,
-    lldb_private::Status &error)
-    : m_process(static_cast<ProcessFreeBSD *>(process)),
-      m_operation_thread(), m_monitor_thread(), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) {
-  using namespace std::placeholders;
-
-  std::unique_ptr<LaunchArgs> args(
-      new LaunchArgs(this, module, argv, std::move(env), stdin_file_spec,
-                     stdout_file_spec, stderr_file_spec, working_dir));
-
-  sem_init(&m_operation_pending, 0, 0);
-  sem_init(&m_operation_done, 0, 0);
-
-  StartLaunchOpThread(args.get(), error);
-  if (!error.Success())
-    return;
-
-  if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
-    error.SetErrorToErrno();
-    return;
-  }
-
-  // Check that the launch was a success.
-  if (!args->m_error.Success()) {
-    StopOpThread();
-    error = args->m_error;
-    return;
-  }
-
-  // Finally, start monitoring the child process for change in state.
-  llvm::Expected<lldb_private::HostThread> monitor_thread =
-    Host::StartMonitoringChildProcess(
-      std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
-      GetPID(), true);
-  if (!monitor_thread || !monitor_thread->IsJoinable()) {
-    error.SetErrorToGenericError();
-    error.SetErrorString("Process launch failed.");
-    return;
-  }
-  m_monitor_thread = *monitor_thread;
-}
-
-ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
-                               lldb_private::Status &error)
-    : m_process(static_cast<ProcessFreeBSD *>(process)),
-      m_operation_thread(), m_monitor_thread(), m_pid(pid), m_terminal_fd(-1), m_operation(0) {
-  using namespace std::placeholders;
-
-  sem_init(&m_operation_pending, 0, 0);
-  sem_init(&m_operation_done, 0, 0);
-
-  std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));
-
-  StartAttachOpThread(args.get(), error);
-  if (!error.Success())
-    return;
-
-  if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
-    error.SetErrorToErrno();
-    return;
-  }
-
-  // Check that the attach was a success.
-  if (!args->m_error.Success()) {
-    StopOpThread();
-    error = args->m_error;
-    return;
-  }
-
-  // Finally, start monitoring the child process for change in state.
-  llvm::Expected<lldb_private::HostThread> monitor_thread =
-    Host::StartMonitoringChildProcess(
-      std::bind(&ProcessMonitor::MonitorCallback, this, _1, _2, _3, _4),
-      GetPID(), true);
-  if (!monitor_thread || !monitor_thread->IsJoinable()) {
-    error.SetErrorToGenericError();
-    error.SetErrorString("Process attach failed.");
-    return;
-  }
-  m_monitor_thread = *monitor_thread;
-}
-
-ProcessMonitor::~ProcessMonitor() { StopMonitor(); }
-
-// Thread setup and tear down.
-void ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Status &error) {
-  static const char *g_thread_name = "lldb.process.freebsd.operation";
-
-  if (m_operation_thread && m_operation_thread->IsJoinable())
-    return;
-
-  llvm::Expected<lldb_private::HostThread> operation_thread =
-    ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args);
-  if (operation_thread)
-    m_operation_thread = *operation_thread;
-  else
-    error = operation_thread.takeError();
-}
-
-void *ProcessMonitor::LaunchOpThread(void *arg) {
-  LaunchArgs *args = static_cast<LaunchArgs *>(arg);
-
-  if (!Launch(args)) {
-    sem_post(&args->m_semaphore);
-    return NULL;
-  }
-
-  ServeOperation(args);
-  return NULL;
-}
-
-bool ProcessMonitor::Launch(LaunchArgs *args) {
-  ProcessMonitor *monitor = args->m_monitor;
-  ProcessFreeBSD &process = monitor->GetProcess();
-  const char **argv = args->m_argv;
-  const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
-  const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
-  const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
-  const FileSpec &working_dir = args->m_working_dir;
-
-  PseudoTerminal terminal;
-
-  // Propagate the environment if one is not supplied.
-  Environment::Envp envp =
-      (args->m_env.empty() ? Host::GetEnvironment() : args->m_env).getEnvp();
-
-  llvm::Expected<lldb::pid_t> pid = terminal.Fork();
-  if (!pid) {
-    args->m_error = pid.takeError();
-    goto FINISH;
-  }
-
-  // Recognized child exit status codes.
-  enum {
-    ePtraceFailed = 1,
-    eDupStdinFailed,
-    eDupStdoutFailed,
-    eDupStderrFailed,
-    eChdirFailed,
-    eExecFailed,
-    eSetGidFailed
-  };
-
-  // Child process.
-  if (*pid == 0) {
-    // Trace this process.
-    if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
-      exit(ePtraceFailed);
-
-    // terminal has already dupped the tty descriptors to stdin/out/err. This
-    // closes original fd from which they were copied (and avoids leaking
-    // descriptors to the debugged process.
-    terminal.CloseSecondaryFileDescriptor();
-
-    // Do not inherit setgid powers.
-    if (setgid(getgid()) != 0)
-      exit(eSetGidFailed);
-
-    // Let us have our own process group.
-    setpgid(0, 0);
-
-    // Dup file descriptors if needed.
-    //
-    // FIXME: If two or more of the paths are the same we needlessly open
-    // the same file multiple times.
-    if (stdin_file_spec)
-      if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
-        exit(eDupStdinFailed);
-
-    if (stdout_file_spec)
-      if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
-        exit(eDupStdoutFailed);
-
-    if (stderr_file_spec)
-      if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
-        exit(eDupStderrFailed);
-
-    // Change working directory
-    if (working_dir && 0 != ::chdir(working_dir.GetCString()))
-      exit(eChdirFailed);
-
-    // Execute.  We should never return.
-    execve(argv[0], const_cast<char *const *>(argv), envp);
-    exit(eExecFailed);
-  }
-
-  // Wait for the child process to to trap on its call to execve.
-  ::pid_t wpid;
-  int status;
-  if ((wpid = waitpid(*pid, &status, 0)) < 0) {
-    args->m_error.SetErrorToErrno();
-    goto FINISH;
-  } else if (WIFEXITED(status)) {
-    // open, dup or execve likely failed for some reason.
-    args->m_error.SetErrorToGenericError();
-    switch (WEXITSTATUS(status)) {
-    case ePtraceFailed:
-      args->m_error.SetErrorString("Child ptrace failed.");
-      break;
-    case eDupStdinFailed:
-      args->m_error.SetErrorString("Child open stdin failed.");
-      break;
-    case eDupStdoutFailed:
-      args->m_error.SetErrorString("Child open stdout failed.");
-      break;
-    case eDupStderrFailed:
-      args->m_error.SetErrorString("Child open stderr failed.");
-      break;
-    case eChdirFailed:
-      args->m_error.SetErrorString("Child failed to set working directory.");
-      break;
-    case eExecFailed:
-      args->m_error.SetErrorString("Child exec failed.");
-      break;
-    case eSetGidFailed:
-      args->m_error.SetErrorString("Child setgid failed.");
-      break;
-    default:
-      args->m_error.SetErrorString("Child returned unknown exit status.");
-      break;
-    }
-    goto FINISH;
-  }
-  assert(WIFSTOPPED(status) && wpid == (::pid_t)*pid &&
-         "Could not sync with inferior process.");
-
-#ifdef notyet
-  // Have the child raise an event on exit.  This is used to keep the child in
-  // limbo until it is destroyed.
-  if (PTRACE(PTRACE_SETOPTIONS, *pid, NULL, PTRACE_O_TRACEEXIT) < 0) {
-    args->m_error.SetErrorToErrno();
-    goto FINISH;
-  }
-#endif
-  // Release the master terminal descriptor and pass it off to the
-  // ProcessMonitor instance.  Similarly stash the inferior pid.
-  monitor->m_terminal_fd = terminal.ReleasePrimaryFileDescriptor();
-  monitor->m_pid = *pid;
-
-  // Set the terminal fd to be in non blocking mode (it simplifies the
-  // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
-  // descriptor to read from).
-  if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
-    goto FINISH;
-
-  process.SendMessage(ProcessMessage::Attach(*pid));
-
-FINISH:
-  return args->m_error.Success();
-}
-
-void ProcessMonitor::StartAttachOpThread(AttachArgs *args,
-                                         lldb_private::Status &error) {
-  static const char *g_thread_name = "lldb.process.freebsd.operation";
-
-  if (m_operation_thread && m_operation_thread->IsJoinable())
-    return;
-
-  llvm::Expected<lldb_private::HostThread> operation_thread =
-    ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args);
-  if (operation_thread)
-    m_operation_thread = *operation_thread;
-  else
-    error = operation_thread.takeError();
-}
-
-void *ProcessMonitor::AttachOpThread(void *arg) {
-  AttachArgs *args = static_cast<AttachArgs *>(arg);
-
-  Attach(args);
-
-  ServeOperation(args);
-  return NULL;
-}
-
-void ProcessMonitor::Attach(AttachArgs *args) {
-  lldb::pid_t pid = args->m_pid;
-
-  ProcessMonitor *monitor = args->m_monitor;
-  ProcessFreeBSD &process = monitor->GetProcess();
-
-  if (pid <= 1) {
-    args->m_error.SetErrorToGenericError();
-    args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
-    return;
-  }
-
-  // Attach to the requested process.
-  if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) {
-    args->m_error.SetErrorToErrno();
-    return;
-  }
-
-  int status;
-  if ((status = waitpid(pid, NULL, 0)) < 0) {
-    args->m_error.SetErrorToErrno();
-    return;
-  }
-
-  process.SendMessage(ProcessMessage::Attach(pid));
-}
-
-size_t
-ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids) {
-  lwpid_t *tids;
-  int tdcnt;
-
-  thread_ids.clear();
-
-  tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
-  if (tdcnt <= 0)
-    return 0;
-  tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
-  if (tids == NULL)
-    return 0;
-  if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
-    free(tids);
-    return 0;
-  }
-  thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
-  free(tids);
-  return thread_ids.size();
-}
-
-bool ProcessMonitor::MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
-                                     bool exited, int signal, int status) {
-  ProcessMessage message;
-  ProcessFreeBSD *process = monitor->m_process;
-  assert(process);
-  bool stop_monitoring;
-  struct ptrace_lwpinfo plwp;
-  int ptrace_err;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  if (exited) {
-    LLDB_LOGF(log, "ProcessMonitor::%s() got exit signal, tid = %" PRIu64,
-              __FUNCTION__, pid);
-    message = ProcessMessage::Exit(pid, status);
-    process->SendMessage(message);
-    return pid == process->GetID();
-  }
-
-  if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
-    stop_monitoring = true; // pid is gone.  Bail.
-  else {
-    switch (plwp.pl_siginfo.si_signo) {
-    case SIGTRAP:
-      message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
-      break;
-
-    default:
-      message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
-      break;
-    }
-
-    process->SendMessage(message);
-    stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
-  }
-
-  return stop_monitoring;
-}
-
-ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
-                                              const siginfo_t *info,
-                                              lldb::tid_t tid) {
-  ProcessMessage message;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  assert(monitor);
-  assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
-
-  switch (info->si_code) {
-  default:
-    assert(false && "Unexpected SIGTRAP code!");
-    break;
-
-  case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): {
-    // The inferior process is about to exit.  Maintain the process in a state
-    // of "limbo" until we are explicitly commanded to detach, destroy, resume,
-    // etc.
-    unsigned long data = 0;
-    if (!monitor->GetEventMessage(tid, &data))
-      data = -1;
-    LLDB_LOGF(log,
-              "ProcessMonitor::%s() received exit? event, data = %lx, tid "
-              "= %" PRIu64,
-              __FUNCTION__, data, tid);
-    message = ProcessMessage::Limbo(tid, (data >> 8));
-    break;
-  }
-
-  case 0:
-  case TRAP_TRACE:
-#ifdef TRAP_CAP
-  // Map TRAP_CAP to a trace trap in the absense of a more specific handler.
-  case TRAP_CAP:
-#endif
-    LLDB_LOGF(log,
-              "ProcessMonitor::%s() received trace event, tid = %" PRIu64
-              "  : si_code = %d",
-              __FUNCTION__, tid, info->si_code);
-    message = ProcessMessage::Trace(tid);
-    break;
-
-  case SI_KERNEL:
-  case TRAP_BRKPT:
-    if (monitor->m_process->IsSoftwareStepBreakpoint(tid)) {
-      LLDB_LOGF(log,
-                "ProcessMonitor::%s() received sw single step breakpoint "
-                "event, tid = %" PRIu64,
-                __FUNCTION__, tid);
-      message = ProcessMessage::Trace(tid);
-    } else {
-      LLDB_LOGF(
-          log, "ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64,
-          __FUNCTION__, tid);
-      message = ProcessMessage::Break(tid);
-    }
-    break;
-  }
-
-  return message;
-}
-
-ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
-                                             const siginfo_t *info,
-                                             lldb::tid_t tid) {
-  ProcessMessage message;
-  int signo = info->si_signo;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
-  // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a kill(2)
-  // or raise(3).  Similarly for tgkill(2) on FreeBSD.
-  //
-  // IOW, user generated signals never generate what we consider to be a
-  // "crash".
-  //
-  // Similarly, ACK signals generated by this monitor.
-  if (info->si_code == SI_USER) {
-    LLDB_LOGF(log,
-              "ProcessMonitor::%s() received signal %s with code %s, pid = %d",
-              __FUNCTION__,
-              monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo),
-              "SI_USER", info->si_pid);
-    if (info->si_pid == getpid())
-      return ProcessMessage::SignalDelivered(tid, signo);
-    else
-      return ProcessMessage::Signal(tid, signo);
-  }
-
-  LLDB_LOGF(log, "ProcessMonitor::%s() received signal %s", __FUNCTION__,
-            monitor->m_process->GetUnixSignals()->GetSignalAsCString(signo));
-
-  switch (signo) {
-  case SIGSEGV:
-  case SIGILL:
-  case SIGFPE:
-  case SIGBUS:
-    lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
-    const auto reason = GetCrashReason(*info);
-    if (reason != CrashReason::eInvalidCrashReason) {
-      return ProcessMessage::Crash(tid, reason, signo, fault_addr);
-    } // else; Use atleast si_signo info for other si_code
-  }
-
-  // Everything else is "normal" and does not require any special action on our
-  // part.
-  return ProcessMessage::Signal(tid, signo);
-}
-
-void ProcessMonitor::ServeOperation(OperationArgs *args) {
-  ProcessMonitor *monitor = args->m_monitor;
-
-  // We are finised with the arguments and are ready to go.  Sync with the
-  // parent thread and start serving operations on the inferior.
-  sem_post(&args->m_semaphore);
-
-  for (;;) {
-    // wait for next pending operation
-    sem_wait(&monitor->m_operation_pending);
-
-    monitor->m_operation->Execute(monitor);
-
-    // notify calling thread that operation is complete
-    sem_post(&monitor->m_operation_done);
-  }
-}
-
-void ProcessMonitor::DoOperation(Operation *op) {
-  std::lock_guard<std::mutex> guard(m_operation_mutex);
-
-  m_operation = op;
-
-  // notify operation thread that an operation is ready to be processed
-  sem_post(&m_operation_pending);
-
-  // wait for operation to complete
-  sem_wait(&m_operation_done);
-}
-
-size_t ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
-                                  Status &error) {
-  size_t result;
-  ReadOperation op(vm_addr, buf, size, error, result);
-  DoOperation(&op);
-  return result;
-}
-
-size_t ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf,
-                                   size_t size, lldb_private::Status &error) {
-  size_t result;
-  WriteOperation op(vm_addr, buf, size, error, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
-                                       const char *reg_name, unsigned size,
-                                       RegisterValue &value) {
-  bool result;
-  ReadRegOperation op(tid, offset, size, value, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
-                                        const char *reg_name,
-                                        const RegisterValue &value) {
-  bool result;
-  WriteRegOperation op(tid, offset, value, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ReadDebugRegisterValue(
-    lldb::tid_t tid, unsigned offset, const char *reg_name, unsigned size,
-    lldb_private::RegisterValue &value) {
-  bool result;
-  ReadDebugRegOperation op(tid, offset, size, value, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::WriteDebugRegisterValue(
-    lldb::tid_t tid, unsigned offset, const char *reg_name,
-    const lldb_private::RegisterValue &value) {
-  bool result;
-  WriteDebugRegOperation op(tid, offset, value, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
-  bool result;
-  ReadGPROperation op(tid, buf, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
-  bool result;
-  ReadFPROperation op(tid, buf, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf,
-                                     size_t buf_size, unsigned int regset) {
-  return false;
-}
-
-bool ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) {
-  bool result;
-  WriteGPROperation op(tid, buf, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) {
-  bool result;
-  WriteFPROperation op(tid, buf, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf,
-                                      size_t buf_size, unsigned int regset) {
-  return false;
-}
-
-bool ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) {
-  return false;
-}
-
-bool ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) {
-  bool result;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
-  if (log) {
-    const char *signame =
-        m_process->GetUnixSignals()->GetSignalAsCString(signo);
-    if (signame == nullptr)
-      signame = "<none>";
-    LLDB_LOGF(log,
-              "ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s",
-              __FUNCTION__, GetPID(), signame);
-  }
-  ResumeOperation op(signo, result);
-  DoOperation(&op);
-  LLDB_LOGF(log, "ProcessMonitor::%s() resuming result = %s", __FUNCTION__,
-            result ? "true" : "false");
-  return result;
-}
-
-bool ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo) {
-  bool result;
-  SingleStepOperation op(signo, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::Kill() {
-  bool result;
-  KillOperation op(result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo,
-                                int &ptrace_err) {
-  bool result;
-  LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend) {
-  bool result;
-  ThreadSuspendOperation op(tid, suspend, result);
-  DoOperation(&op);
-  return result;
-}
-
-bool ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) {
-  bool result;
-  EventMessageOperation op(tid, message, result);
-  DoOperation(&op);
-  return result;
-}
-
-lldb_private::Status ProcessMonitor::Detach(lldb::tid_t tid) {
-  lldb_private::Status error;
-  if (tid != LLDB_INVALID_THREAD_ID) {
-    DetachOperation op(error);
-    DoOperation(&op);
-  }
-  return error;
-}
-
-bool ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd,
-                                   int flags) {
-  int target_fd = llvm::sys::RetryAfterSignal(-1, open,
-      file_spec.GetCString(), flags, 0666);
-
-  if (target_fd == -1)
-    return false;
-
-  if (dup2(target_fd, fd) == -1)
-    return false;
-
-  return (close(target_fd) == -1) ? false : true;
-}
-
-void ProcessMonitor::StopMonitoringChildProcess() {
-  if (m_monitor_thread && m_monitor_thread->IsJoinable()) {
-    m_monitor_thread->Cancel();
-    m_monitor_thread->Join(nullptr);
-    m_monitor_thread->Reset();
-  }
-}
-
-void ProcessMonitor::StopMonitor() {
-  StopMonitoringChildProcess();
-  StopOpThread();
-  sem_destroy(&m_operation_pending);
-  sem_destroy(&m_operation_done);
-  if (m_terminal_fd >= 0) {
-    close(m_terminal_fd);
-    m_terminal_fd = -1;
-  }
-}
-
-// FIXME: On Linux, when a new thread is created, we receive to notifications,
-// (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the child
-// thread id as additional information, and (2) a SIGSTOP|SI_USER from the new
-// child thread indicating that it has is stopped because we attached. We have
-// no guarantee of the order in which these arrive, but we need both before we
-// are ready to proceed.  We currently keep a list of threads which have sent
-// the initial SIGSTOP|SI_USER event.  Then when we receive the
-// SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not
-// occurred we call ProcessMonitor::WaitForInitialTIDStop() to wait for it.
-//
-// Right now, the above logic is in ProcessPOSIX, so we need a definition of
-// this function in the FreeBSD ProcessMonitor implementation even if it isn't
-// logically needed.
-//
-// We really should figure out what actually happens on FreeBSD and move the
-// Linux-specific logic out of ProcessPOSIX as needed.
-
-bool ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) { return true; }
-
-void ProcessMonitor::StopOpThread() {
-  if (m_operation_thread && m_operation_thread->IsJoinable()) {
-    m_operation_thread->Cancel();
-    m_operation_thread->Join(nullptr);
-    m_operation_thread->Reset();
-  }
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
deleted file mode 100644
index c5edfc0..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ /dev/null
@@ -1,279 +0,0 @@
-//===-- ProcessMonitor.h -------------------------------------- -*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessMonitor_H_
-#define liblldb_ProcessMonitor_H_
-
-#include <semaphore.h>
-#include <signal.h>
-
-#include <mutex>
-
-#include "lldb/Host/HostThread.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-types.h"
-
-namespace lldb_private {
-class Status;
-class Module;
-class Scalar;
-} // End lldb_private namespace.
-
-class ProcessFreeBSD;
-class Operation;
-
-/// \class ProcessMonitor
-/// Manages communication with the inferior (debugee) process.
-///
-/// Upon construction, this class prepares and launches an inferior process
-/// for debugging.
-///
-/// Changes in the inferior process state are propagated to the associated
-/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the
-/// appropriate ProcessMessage events.
-///
-/// A purposely minimal set of operations are provided to interrogate and change
-/// the inferior process state.
-class ProcessMonitor {
-public:
-  /// Launches an inferior process ready for debugging.  Forms the
-  /// implementation of Process::DoLaunch.
-  ProcessMonitor(ProcessFreeBSD *process, lldb_private::Module *module,
-                 char const *argv[], lldb_private::Environment env,
-                 const lldb_private::FileSpec &stdin_file_spec,
-                 const lldb_private::FileSpec &stdout_file_spec,
-                 const lldb_private::FileSpec &stderr_file_spec,
-                 const lldb_private::FileSpec &working_dir,
-                 const lldb_private::ProcessLaunchInfo &launch_info,
-                 lldb_private::Status &error);
-
-  ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
-                 lldb_private::Status &error);
-
-  ~ProcessMonitor();
-
-  /// Provides the process number of debugee.
-  lldb::pid_t GetPID() const { return m_pid; }
-
-  /// Returns the process associated with this ProcessMonitor.
-  ProcessFreeBSD &GetProcess() { return *m_process; }
-
-  /// Returns a file descriptor to the controlling terminal of the inferior
-  /// process.
-  ///
-  /// Reads from this file descriptor yield both the standard output and
-  /// standard error of this debugee.  Even if stderr and stdout were
-  /// redirected on launch it may still happen that data is available on this
-  /// descriptor (if the inferior process opens /dev/tty, for example). This
-  /// descriptor is closed after a call to StopMonitor().
-  ///
-  /// If this monitor was attached to an existing process this method returns
-  /// -1.
-  int GetTerminalFD() const { return m_terminal_fd; }
-
-  /// Reads \p size bytes from address @vm_adder in the inferior process
-  /// address space.
-  ///
-  /// This method is provided to implement Process::DoReadMemory.
-  size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
-                    lldb_private::Status &error);
-
-  /// Writes \p size bytes from address \p vm_adder in the inferior process
-  /// address space.
-  ///
-  /// This method is provided to implement Process::DoWriteMemory.
-  size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
-                     lldb_private::Status &error);
-
-  /// Reads the contents from the register identified by the given
-  /// (architecture dependent) offset.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
-                         unsigned size, lldb_private::RegisterValue &value);
-
-  /// Writes the given value to the register identified by the given
-  /// (architecture dependent) offset.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool WriteRegisterValue(lldb::tid_t tid, unsigned offset,
-                          const char *reg_name,
-                          const lldb_private::RegisterValue &value);
-
-  /// Reads the contents from the debug register identified by the given
-  /// (architecture dependent) offset.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
-                              const char *reg_name, unsigned size,
-                              lldb_private::RegisterValue &value);
-
-  /// Writes the given value to the debug register identified by the given
-  /// (architecture dependent) offset.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
-                               const char *reg_name,
-                               const lldb_private::RegisterValue &value);
-  /// Reads all general purpose registers into the specified buffer.
-  bool ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-  /// Reads all floating point registers into the specified buffer.
-  bool ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-  /// Reads the specified register set into the specified buffer.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
-                       unsigned int regset);
-
-  /// Writes all general purpose registers into the specified buffer.
-  bool WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-  /// Writes all floating point registers into the specified buffer.
-  bool WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
-
-  /// Writes the specified register set into the specified buffer.
-  ///
-  /// This method is provided for use by RegisterContextFreeBSD derivatives.
-  bool WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size,
-                        unsigned int regset);
-
-  /// Reads the value of the thread-specific pointer for a given thread ID.
-  bool ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
-
-  /// Returns current thread IDs in process
-  size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
-
-  /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
-  /// to the memory region pointed to by \p lwpinfo.
-  bool GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
-
-  /// Suspends or unsuspends a thread prior to process resume or step.
-  bool ThreadSuspend(lldb::tid_t tid, bool suspend);
-
-  /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
-  /// corresponding to the given thread IDto the memory pointed to by @p
-  /// message.
-  bool GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
-  /// Resumes the process.  If \p signo is anything but
-  /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
-  bool Resume(lldb::tid_t unused, uint32_t signo);
-
-  /// Single steps the process.  If \p signo is anything but
-  /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
-  bool SingleStep(lldb::tid_t unused, uint32_t signo);
-
-  /// Terminate the traced process.
-  bool Kill();
-
-  lldb_private::Status Detach(lldb::tid_t tid);
-
-  void StopMonitor();
-
-  // Waits for the initial stop message from a new thread.
-  bool WaitForInitialTIDStop(lldb::tid_t tid);
-
-private:
-  ProcessFreeBSD *m_process;
-
-  llvm::Optional<lldb_private::HostThread> m_operation_thread;
-  llvm::Optional<lldb_private::HostThread> m_monitor_thread;
-  lldb::pid_t m_pid;
-
-  int m_terminal_fd;
-
-  // current operation which must be executed on the privileged thread
-  Operation *m_operation;
-  std::mutex m_operation_mutex;
-
-  // semaphores notified when Operation is ready to be processed and when
-  // the operation is complete.
-  sem_t m_operation_pending;
-  sem_t m_operation_done;
-
-  struct OperationArgs {
-    OperationArgs(ProcessMonitor *monitor);
-
-    ~OperationArgs();
-
-    ProcessMonitor *m_monitor;   // The monitor performing the attach.
-    sem_t m_semaphore;           // Posted to once operation complete.
-    lldb_private::Status m_error; // Set if process operation failed.
-  };
-
-  /// \class LauchArgs
-  ///
-  /// Simple structure to pass data to the thread responsible for launching a
-  /// child process.
-  struct LaunchArgs : OperationArgs {
-    LaunchArgs(ProcessMonitor *monitor, lldb_private::Module *module,
-               char const **argv, lldb_private::Environment env,
-               const lldb_private::FileSpec &stdin_file_spec,
-               const lldb_private::FileSpec &stdout_file_spec,
-               const lldb_private::FileSpec &stderr_file_spec,
-               const lldb_private::FileSpec &working_dir);
-
-    ~LaunchArgs();
-
-    lldb_private::Module *m_module; // The executable image to launch.
-    char const **m_argv;            // Process arguments.
-    lldb_private::Environment m_env;                // Process environment.
-    const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
-    const lldb_private::FileSpec
-        m_stdout_file_spec; // Redirect stdout or empty.
-    const lldb_private::FileSpec
-        m_stderr_file_spec;                     // Redirect stderr or empty.
-    const lldb_private::FileSpec m_working_dir; // Working directory or empty.
-  };
-
-  void StartLaunchOpThread(LaunchArgs *args, lldb_private::Status &error);
-
-  static void *LaunchOpThread(void *arg);
-
-  static bool Launch(LaunchArgs *args);
-
-  struct AttachArgs : OperationArgs {
-    AttachArgs(ProcessMonitor *monitor, lldb::pid_t pid);
-
-    ~AttachArgs();
-
-    lldb::pid_t m_pid; // pid of the process to be attached.
-  };
-
-  void StartAttachOpThread(AttachArgs *args, lldb_private::Status &error);
-
-  static void *AttachOpThread(void *args);
-
-  static void Attach(AttachArgs *args);
-
-  static void ServeOperation(OperationArgs *args);
-
-  static bool DupDescriptor(const lldb_private::FileSpec &file_spec, int fd,
-                            int flags);
-
-  static bool MonitorCallback(ProcessMonitor *monitor, lldb::pid_t pid,
-                              bool exited, int signal, int status);
-
-  static ProcessMessage MonitorSIGTRAP(ProcessMonitor *monitor,
-                                       const siginfo_t *info, lldb::pid_t pid);
-
-  static ProcessMessage MonitorSignal(ProcessMonitor *monitor,
-                                      const siginfo_t *info, lldb::pid_t pid);
-
-  void DoOperation(Operation *op);
-
-  /// Stops the child monitor thread.
-  void StopMonitoringChildProcess();
-
-  /// Stops the operation thread used to attach/launch a process.
-  void StopOpThread();
-};
-
-#endif // #ifndef liblldb_ProcessMonitor_H_
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
deleted file mode 100644
index cf52a06..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- RegisterContextPOSIX.h --------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIX_H_
-#define liblldb_RegisterContextPOSIX_H_
-
-#include "Plugins/Process/Utility/RegisterInfoInterface.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Utility/ArchSpec.h"
-
-/// \class POSIXBreakpointProtocol
-///
-/// Extends RegisterClass with a few virtual operations useful on POSIX.
-class POSIXBreakpointProtocol {
-public:
-  POSIXBreakpointProtocol() { m_watchpoints_initialized = false; }
-  virtual ~POSIXBreakpointProtocol() {}
-
-  /// Updates the register state of the associated thread after hitting a
-  /// breakpoint (if that make sense for the architecture).  Default
-  /// implementation simply returns true for architectures which do not
-  /// require any update.
-  ///
-  /// \return
-  ///    True if the operation succeeded and false otherwise.
-  virtual bool UpdateAfterBreakpoint() = 0;
-
-  /// Determines the index in lldb's register file given a kernel byte offset.
-  virtual unsigned GetRegisterIndexFromOffset(unsigned offset) = 0;
-
-  // Checks to see if a watchpoint specified by hw_index caused the inferior
-  // to stop.
-  virtual bool IsWatchpointHit(uint32_t hw_index) = 0;
-
-  // Resets any watchpoints that have been hit.
-  virtual bool ClearWatchpointHits() = 0;
-
-  // Returns the watchpoint address associated with a watchpoint hardware
-  // index.
-  virtual lldb::addr_t GetWatchpointAddress(uint32_t hw_index) = 0;
-
-  virtual bool IsWatchpointVacant(uint32_t hw_index) = 0;
-
-  virtual bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
-                                              bool read, bool write,
-                                              uint32_t hw_index) = 0;
-
-  // From lldb_private::RegisterContext
-  virtual uint32_t NumSupportedHardwareWatchpoints() = 0;
-
-  // Force m_watchpoints_initialized to TRUE
-  void ForceWatchpointsInitialized() { m_watchpoints_initialized = true; }
-
-protected:
-  bool m_watchpoints_initialized;
-};
-
-#endif // #ifndef liblldb_RegisterContextPOSIX_H_
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
deleted file mode 100644
index afb92e8..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm.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 "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm.h"
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
-#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_arm::RegisterContextPOSIXProcessMonitor_arm(
-    lldb_private::Thread &thread,
-    std::unique_ptr<RegisterInfoPOSIX_arm> register_info)
-    : RegisterContextPOSIX_arm(thread, std::move(register_info)) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm::GetMonitor() {
-  ProcessSP base = CalculateProcess();
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
-  return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof(m_fpr));
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
-    const unsigned reg, RegisterValue &value) {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
-                                   GetRegisterName(reg), GetRegisterSize(reg),
-                                   value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
-    const unsigned reg, const RegisterValue &value) {
-  unsigned reg_to_write = reg;
-  RegisterValue value_to_write = value;
-
-  // Check if this is a subregister of a full register.
-  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-  if (reg_info->invalidate_regs &&
-      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
-    RegisterValue full_value;
-    uint32_t full_reg = reg_info->invalidate_regs[0];
-    const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-    // Read the full register.
-    if (ReadRegister(full_reg_info, full_value)) {
-      Status error;
-      ByteOrder byte_order = GetByteOrder();
-      uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-      // Get the bytes for the full register.
-      const uint32_t dest_size = full_value.GetAsMemoryData(
-          full_reg_info, dst, sizeof(dst), byte_order, error);
-      if (error.Success() && dest_size) {
-        uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the source data.
-        const uint32_t src_size = value.GetAsMemoryData(
-            reg_info, src, sizeof(src), byte_order, error);
-        if (error.Success() && src_size && (src_size < dest_size)) {
-          // Copy the src bytes to the destination.
-          memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
-          // Set this full register as the value to write.
-          value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-          value_to_write.SetType(full_reg_info);
-          reg_to_write = full_reg;
-        }
-      }
-    }
-  }
-
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteRegisterValue(
-      m_thread.GetID(), GetRegisterOffset(reg_to_write),
-      GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadRegister(
-    const RegisterInfo *reg_info, RegisterValue &value) {
-  if (!reg_info)
-    return false;
-
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsFPR(reg)) {
-    if (!ReadFPR())
-      return false;
-  } else {
-    return ReadRegister(reg, value);
-  }
-
-  // Get pointer to m_fpr variable and set the data from it.
-  assert(reg_info->byte_offset < sizeof m_fpr);
-  uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
-  switch (reg_info->byte_size) {
-  case 2:
-    value.SetUInt16(*(uint16_t *)src);
-    return true;
-  case 4:
-    value.SetUInt32(*(uint32_t *)src);
-    return true;
-  case 8:
-    value.SetUInt64(*(uint64_t *)src);
-    return true;
-  default:
-    assert(false && "Unhandled data size.");
-    return false;
-  }
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteRegister(
-    const RegisterInfo *reg_info, const RegisterValue &value) {
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsGPR(reg)) {
-    return WriteRegister(reg, value);
-  } else if (IsFPR(reg)) {
-    return WriteFPR();
-  }
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ReadAllRegisterValues(
-    DataBufferSP &data_sp) {
-  bool success = false;
-  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  if (ReadGPR() && ReadFPR()) {
-    uint8_t *dst = data_sp->GetBytes();
-    success = dst != 0;
-
-    if (success) {
-      ::memcpy(dst, &m_gpr_arm, GetGPRSize());
-      dst += GetGPRSize();
-      ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-    }
-  }
-  return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::WriteAllRegisterValues(
-    const DataBufferSP &data_sp) {
-  bool success = false;
-  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
-    uint8_t *src = data_sp->GetBytes();
-    if (src) {
-      ::memcpy(&m_gpr_arm, src, GetGPRSize());
-
-      if (WriteGPR()) {
-        src += GetGPRSize();
-        ::memcpy(&m_fpr, src, sizeof(m_fpr));
-
-        success = WriteFPR();
-      }
-    }
-  }
-  return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpoint(
-    addr_t addr, size_t size, bool read, bool write) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  uint32_t hw_index;
-
-  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
-    if (IsWatchpointVacant(hw_index))
-      return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
-  }
-
-  return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ClearHardwareWatchpoint(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::HardwareSingleStep(bool enable) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::UpdateAfterBreakpoint() {
-  lldb::addr_t pc;
-
-  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
-    return false;
-
-  return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_arm::GetRegisterIndexFromOffset(
-    unsigned offset) {
-  unsigned reg;
-  for (reg = 0; reg < k_num_registers_arm; reg++) {
-    if (GetRegisterInfo()[reg].byte_offset == offset)
-      break;
-  }
-  assert(reg < k_num_registers_arm && "Invalid register offset.");
-  return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointHit(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::ClearWatchpointHits() {
-  return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_arm::GetWatchpointAddress(
-    uint32_t hw_index) {
-  return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::IsWatchpointVacant(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm::SetHardwareWatchpointWithIndex(
-    addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
-  return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm::NumSupportedHardwareWatchpoints() {
-  return 0;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
deleted file mode 100644
index bb45584..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm.h --------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_arm_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_arm : public RegisterContextPOSIX_arm,
-                                               public POSIXBreakpointProtocol {
-public:
-  RegisterContextPOSIXProcessMonitor_arm(
-      lldb_private::Thread &thread,
-      std::unique_ptr<RegisterInfoPOSIX_arm> register_info);
-
-protected:
-  bool ReadGPR() override;
-
-  bool ReadFPR() override;
-
-  bool WriteGPR() override;
-
-  bool WriteFPR() override;
-
-  // lldb_private::RegisterContext
-  bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
-  bool WriteRegister(const unsigned reg,
-                     const lldb_private::RegisterValue &value);
-
-  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
-                    lldb_private::RegisterValue &value) override;
-
-  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
-                     const lldb_private::RegisterValue &value) override;
-
-  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  bool HardwareSingleStep(bool enable) override;
-
-  // POSIXBreakpointProtocol
-  bool UpdateAfterBreakpoint() override;
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset) override;
-
-  bool IsWatchpointHit(uint32_t hw_index) override;
-
-  bool ClearWatchpointHits() override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t hw_index) override;
-
-  bool IsWatchpointVacant(uint32_t hw_index) override;
-
-  bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
-                                      bool write, uint32_t hw_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-private:
-  RegisterInfoPOSIX_arm::GPR m_gpr_arm;
-
-  RegisterInfoPOSIX_arm::FPU m_fpr;
-
-  ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
deleted file mode 100644
index 39ae0b9..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm64.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 "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_arm64.h"
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextPOSIXProcessMonitor_arm64::
-    RegisterContextPOSIXProcessMonitor_arm64(
-        lldb_private::Thread &thread,
-        std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
-    : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
-  ::memset(&m_gpr_arm64, 0, sizeof m_gpr_arm64);
-  ::memset(&m_fpr, 0, sizeof m_fpr);
-}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_arm64::GetMonitor() {
-  lldb::ProcessSP base = CalculateProcess();
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
-  return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_arm64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteFPR(m_thread.GetID(), &m_fpr, sizeof m_fpr);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
-    const unsigned reg, lldb_private::RegisterValue &value) {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
-                                   GetRegisterName(reg), GetRegisterSize(reg),
-                                   value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
-    const unsigned reg, const lldb_private::RegisterValue &value) {
-  unsigned reg_to_write = reg;
-  lldb_private::RegisterValue value_to_write = value;
-
-  // Check if this is a subregister of a full register.
-  const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-  if (reg_info->invalidate_regs &&
-      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
-    lldb_private::RegisterValue full_value;
-    uint32_t full_reg = reg_info->invalidate_regs[0];
-    const lldb_private::RegisterInfo *full_reg_info =
-        GetRegisterInfoAtIndex(full_reg);
-
-    // Read the full register.
-    if (ReadRegister(full_reg_info, full_value)) {
-      lldb_private::Status error;
-      lldb::ByteOrder byte_order = GetByteOrder();
-      uint8_t dst[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
-      // Get the bytes for the full register.
-      const uint32_t dest_size = full_value.GetAsMemoryData(
-          full_reg_info, dst, sizeof(dst), byte_order, error);
-      if (error.Success() && dest_size) {
-        uint8_t src[lldb_private::RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the source data.
-        const uint32_t src_size = value.GetAsMemoryData(
-            reg_info, src, sizeof(src), byte_order, error);
-        if (error.Success() && src_size && (src_size < dest_size)) {
-          // Copy the src bytes to the destination.
-          ::memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
-          // Set this full register as the value to write.
-          value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-          value_to_write.SetType(full_reg_info);
-          reg_to_write = full_reg;
-        }
-      }
-    }
-  }
-
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteRegisterValue(
-      m_thread.GetID(), GetRegisterOffset(reg_to_write),
-      GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadRegister(
-    const lldb_private::RegisterInfo *reg_info,
-    lldb_private::RegisterValue &value) {
-  if (!reg_info)
-    return false;
-
-  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
-  if (IsFPR(reg)) {
-    if (!ReadFPR())
-      return false;
-  } else {
-    uint32_t full_reg = reg;
-    bool is_subreg = reg_info->invalidate_regs &&
-                     (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
-    if (is_subreg) {
-      // Read the full aligned 64-bit register.
-      full_reg = reg_info->invalidate_regs[0];
-    }
-    return ReadRegister(full_reg, value);
-  }
-
-  // Get pointer to m_fpr variable and set the data from it.
-  assert(reg_info->byte_offset < sizeof m_fpr);
-  uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
-  switch (reg_info->byte_size) {
-  case 2:
-    value.SetUInt16(*(uint16_t *)src);
-    return true;
-  case 4:
-    value.SetUInt32(*(uint32_t *)src);
-    return true;
-  case 8:
-    value.SetUInt64(*(uint64_t *)src);
-    return true;
-  default:
-    assert(false && "Unhandled data size.");
-    return false;
-  }
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteRegister(
-    const lldb_private::RegisterInfo *reg_info,
-    const lldb_private::RegisterValue &value) {
-  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
-  if (IsGPR(reg))
-    return WriteRegister(reg, value);
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ReadAllRegisterValues(
-    lldb::DataBufferSP &data_sp) {
-  bool success = false;
-  data_sp.reset(new lldb_private::DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  if (ReadGPR() && ReadFPR()) {
-    uint8_t *dst = data_sp->GetBytes();
-    success = dst != 0;
-
-    if (success) {
-      ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
-      dst += GetGPRSize();
-      ::memcpy(dst, &m_fpr, sizeof m_fpr);
-    }
-  }
-  return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::WriteAllRegisterValues(
-    const lldb::DataBufferSP &data_sp) {
-  bool success = false;
-  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
-    uint8_t *src = data_sp->GetBytes();
-    if (src) {
-      ::memcpy(&m_gpr_arm64, src, GetGPRSize());
-      if (WriteGPR()) {
-        src += GetGPRSize();
-        ::memcpy(&m_fpr, src, sizeof m_fpr);
-        success = WriteFPR();
-      }
-    }
-  }
-  return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpoint(
-    lldb::addr_t addr, size_t size, bool read, bool write) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  uint32_t hw_index;
-
-  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
-    if (IsWatchpointVacant(hw_index))
-      return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
-  }
-
-  return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ClearHardwareWatchpoint(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::HardwareSingleStep(bool enable) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::UpdateAfterBreakpoint() {
-  if (GetPC() == LLDB_INVALID_ADDRESS)
-    return false;
-
-  return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_arm64::GetRegisterIndexFromOffset(
-    unsigned offset) {
-  unsigned reg;
-  for (reg = 0; reg < GetRegisterCount(); reg++) {
-    if (GetRegisterInfo()[reg].byte_offset == offset)
-      break;
-  }
-  assert(reg < GetRegisterCount() && "Invalid register offset.");
-  return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointHit(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::ClearWatchpointHits() {
-  return false;
-}
-
-lldb::addr_t RegisterContextPOSIXProcessMonitor_arm64::GetWatchpointAddress(
-    uint32_t hw_index) {
-  return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::IsWatchpointVacant(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_arm64::SetHardwareWatchpointWithIndex(
-    lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
-  return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_arm64::NumSupportedHardwareWatchpoints() {
-  return 0;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
deleted file mode 100644
index dcae1d4..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_arm64.h --------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_arm64_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_arm64
-    : public RegisterContextPOSIX_arm64,
-      public POSIXBreakpointProtocol {
-public:
-  RegisterContextPOSIXProcessMonitor_arm64(
-      lldb_private::Thread &thread,
-      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info);
-
-protected:
-  bool ReadGPR() override;
-
-  bool ReadFPR() override;
-
-  bool WriteGPR() override;
-
-  bool WriteFPR() override;
-
-  // lldb_private::RegisterContext
-  bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
-  bool WriteRegister(const unsigned reg,
-                     const lldb_private::RegisterValue &value);
-
-  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
-                    lldb_private::RegisterValue &value) override;
-
-  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
-                     const lldb_private::RegisterValue &value) override;
-
-  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  bool HardwareSingleStep(bool enable) override;
-
-  // POSIXBreakpointProtocol
-  bool UpdateAfterBreakpoint() override;
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset) override;
-
-  bool IsWatchpointHit(uint32_t hw_index) override;
-
-  bool ClearWatchpointHits() override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t hw_index) override;
-
-  bool IsWatchpointVacant(uint32_t hw_index) override;
-
-  bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
-                                      bool write, uint32_t hw_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-private:
-  RegisterInfoPOSIX_arm64::GPR m_gpr_arm64; // 64-bit general purpose registers.
-
-  RegisterInfoPOSIX_arm64::FPU
-      m_fpr; // floating-point registers including extended register sets.
-
-  ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
deleted file mode 100644
index 23c76f2..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.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 "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_mips64.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_mips64::
-    RegisterContextPOSIXProcessMonitor_mips64(
-        Thread &thread, uint32_t concrete_frame_idx,
-        lldb_private::RegisterInfoInterface *register_info)
-    : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() {
-  ProcessSP base = CalculateProcess();
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
-  return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() {
-  // XXX not yet implemented
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() {
-  // XXX not yet implemented
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
-    const unsigned reg, RegisterValue &value) {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
-                                   GetRegisterName(reg), GetRegisterSize(reg),
-                                   value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
-    const unsigned reg, const RegisterValue &value) {
-  unsigned reg_to_write = reg;
-  RegisterValue value_to_write = value;
-
-  // Check if this is a subregister of a full register.
-  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-  if (reg_info->invalidate_regs &&
-      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
-    RegisterValue full_value;
-    uint32_t full_reg = reg_info->invalidate_regs[0];
-    const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-    // Read the full register.
-    if (ReadRegister(full_reg_info, full_value)) {
-      Status error;
-      ByteOrder byte_order = GetByteOrder();
-      uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-      // Get the bytes for the full register.
-      const uint32_t dest_size = full_value.GetAsMemoryData(
-          full_reg_info, dst, sizeof(dst), byte_order, error);
-      if (error.Success() && dest_size) {
-        uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the source data.
-        const uint32_t src_size = value.GetAsMemoryData(
-            reg_info, src, sizeof(src), byte_order, error);
-        if (error.Success() && src_size && (src_size < dest_size)) {
-          // Copy the src bytes to the destination.
-          memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
-          // Set this full register as the value to write.
-          value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-          value_to_write.SetType(full_reg_info);
-          reg_to_write = full_reg;
-        }
-      }
-    }
-  }
-
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteRegisterValue(
-      m_thread.GetID(), GetRegisterOffset(reg_to_write),
-      GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(
-    const RegisterInfo *reg_info, RegisterValue &value) {
-  if (!reg_info)
-    return false;
-
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsFPR(reg)) {
-    if (!ReadFPR())
-      return false;
-  } else {
-    uint32_t full_reg = reg;
-    bool is_subreg = reg_info->invalidate_regs &&
-                     (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
-    if (is_subreg) {
-      // Read the full aligned 64-bit register.
-      full_reg = reg_info->invalidate_regs[0];
-    }
-
-    bool success = ReadRegister(full_reg, value);
-
-    if (success) {
-      // If our read was not aligned (for ah,bh,ch,dh), shift our returned
-      // value one byte to the right.
-      if (is_subreg && (reg_info->byte_offset & 0x1))
-        value.SetUInt64(value.GetAsUInt64() >> 8);
-
-      // If our return byte size was greater than the return value reg size,
-      // then use the type specified by reg_info rather than the uint64_t
-      // default
-      if (value.GetByteSize() > reg_info->byte_size)
-        value.SetType(reg_info);
-    }
-    return success;
-  }
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(
-    const RegisterInfo *reg_info, const RegisterValue &value) {
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsGPR(reg))
-    return WriteRegister(reg, value);
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(
-    DataBufferSP &data_sp) {
-  bool success = false;
-  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  if (ReadGPR() && ReadFPR()) {
-    uint8_t *dst = data_sp->GetBytes();
-    success = dst != 0;
-
-    if (success) {
-      ::memcpy(dst, &m_gpr_mips64, GetGPRSize());
-    }
-  }
-  return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(
-    const DataBufferSP &data_sp) {
-  bool success = false;
-  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
-    uint8_t *src = data_sp->GetBytes();
-    if (src) {
-      ::memcpy(&m_gpr_mips64, src, GetGPRSize());
-
-      if (WriteGPR()) {
-        src += GetGPRSize();
-      }
-    }
-  }
-  return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(
-    addr_t addr, size_t size, bool read, bool write) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  uint32_t hw_index;
-
-  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
-    if (IsWatchpointVacant(hw_index))
-      return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
-  }
-
-  return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(
-    bool enable) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint() {
-  // PC points one byte past the int3 responsible for the breakpoint.
-  lldb::addr_t pc;
-
-  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
-    return false;
-
-  SetPC(pc - 1);
-  return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(
-    unsigned offset) {
-  unsigned reg;
-  for (reg = 0; reg < k_num_registers_mips64; reg++) {
-    if (GetRegisterInfo()[reg].byte_offset == offset)
-      break;
-  }
-  assert(reg < k_num_registers_mips64 && "Invalid register offset.");
-  return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() {
-  return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(
-    uint32_t hw_index) {
-  return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(
-    addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
-  return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() {
-  return 0;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
deleted file mode 100644
index be404cc..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_mips64.h -------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
-#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"
-#include "RegisterContextPOSIX.h"
-
-class ProcessMonitor;
-
-class RegisterContextPOSIXProcessMonitor_mips64
-    : public RegisterContextPOSIX_mips64,
-      public POSIXBreakpointProtocol {
-public:
-  RegisterContextPOSIXProcessMonitor_mips64(
-      lldb_private::Thread &thread, uint32_t concrete_frame_idx,
-      lldb_private::RegisterInfoInterface *register_info);
-
-protected:
-  bool ReadGPR() override;
-
-  bool ReadFPR() override;
-
-  bool WriteGPR() override;
-
-  bool WriteFPR() override;
-
-  // lldb_private::RegisterContext
-  bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
-  bool WriteRegister(const unsigned reg,
-                     const lldb_private::RegisterValue &value);
-
-  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
-                    lldb_private::RegisterValue &value) override;
-
-  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
-                     const lldb_private::RegisterValue &value) override;
-
-  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  bool HardwareSingleStep(bool enable) override;
-
-  // POSIXBreakpointProtocol
-  bool UpdateAfterBreakpoint() override;
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset) override;
-
-  bool IsWatchpointHit(uint32_t hw_index) override;
-
-  bool ClearWatchpointHits() override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t hw_index) override;
-
-  bool IsWatchpointVacant(uint32_t hw_index) override;
-
-  bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
-                                      bool write, uint32_t hw_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-private:
-  uint64_t 
-  m_gpr_mips64[lldb_private::k_num_gpr_registers_mips64]; // general purpose registers.
-  ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
deleted file mode 100644
index f834277..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.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 "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "ProcessFreeBSD.h"
-#include "ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_powerpc.h"
-#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-#define REG_CONTEXT_SIZE (GetGPRSize())
-
-RegisterContextPOSIXProcessMonitor_powerpc::
-    RegisterContextPOSIXProcessMonitor_powerpc(
-        Thread &thread, uint32_t concrete_frame_idx,
-        lldb_private::RegisterInfoInterface *register_info)
-    : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) {}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() {
-  ProcessSP base = CalculateProcess();
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
-  return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc,
-                         sizeof(m_fpr_powerpc));
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() {
-  // XXX: Need a way to read/write process VMX registers with ptrace.
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc,
-                          sizeof(m_fpr_powerpc));
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() {
-  // XXX: Need a way to read/write process VMX registers with ptrace.
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
-    const unsigned reg, RegisterValue &value) {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
-                                   GetRegisterName(reg), GetRegisterSize(reg),
-                                   value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
-    const unsigned reg, const RegisterValue &value) {
-  unsigned reg_to_write = reg;
-  RegisterValue value_to_write = value;
-
-  // Check if this is a subregister of a full register.
-  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-  if (reg_info->invalidate_regs &&
-      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
-    RegisterValue full_value;
-    uint32_t full_reg = reg_info->invalidate_regs[0];
-    const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-    // Read the full register.
-    if (ReadRegister(full_reg_info, full_value)) {
-      Status error;
-      ByteOrder byte_order = GetByteOrder();
-      uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-      // Get the bytes for the full register.
-      const uint32_t dest_size = full_value.GetAsMemoryData(
-          full_reg_info, dst, sizeof(dst), byte_order, error);
-      if (error.Success() && dest_size) {
-        uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the source data.
-        const uint32_t src_size = value.GetAsMemoryData(
-            reg_info, src, sizeof(src), byte_order, error);
-        if (error.Success() && src_size && (src_size < dest_size)) {
-          // Copy the src bytes to the destination.
-          memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
-          // Set this full register as the value to write.
-          value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-          value_to_write.SetType(full_reg_info);
-          reg_to_write = full_reg;
-        }
-      }
-    }
-  }
-
-  ProcessMonitor &monitor = GetMonitor();
-  // Account for the fact that 32-bit targets on powerpc64 really use 64-bit
-  // registers in ptrace, but expose here 32-bit registers with a higher
-  // offset.
-  uint64_t offset = GetRegisterOffset(reg_to_write);
-  offset &= ~(sizeof(uintptr_t) - 1);
-  return monitor.WriteRegisterValue(
-      m_thread.GetID(), offset, GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(
-    const RegisterInfo *reg_info, RegisterValue &value) {
-  if (!reg_info)
-    return false;
-
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsFPR(reg)) {
-    if (!ReadFPR())
-      return false;
-    uint8_t *src = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
-    value.SetUInt64(*(uint64_t *)src);
-  } else if (IsGPR(reg)) {
-    bool success = ReadRegister(reg, value);
-
-    if (success) {
-      // If our return byte size was greater than the return value reg size,
-      // then use the type specified by reg_info rather than the uint64_t
-      // default
-      if (value.GetByteSize() > reg_info->byte_size)
-        value.SetType(reg_info);
-    }
-    return success;
-  }
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(
-    const RegisterInfo *reg_info, const RegisterValue &value) {
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsGPR(reg)) {
-    return WriteRegister(reg, value);
-  } else if (IsFPR(reg)) {
-    assert(reg_info->byte_offset < sizeof(m_fpr_powerpc));
-    uint8_t *dst = (uint8_t *)&m_fpr_powerpc + reg_info->byte_offset;
-    *(uint64_t *)dst = value.GetAsUInt64();
-    return WriteFPR();
-  }
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(
-    DataBufferSP &data_sp) {
-  bool success = false;
-  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  if (ReadGPR() && ReadFPR()) {
-    uint8_t *dst = data_sp->GetBytes();
-    success = dst != 0;
-
-    if (success) {
-      ::memcpy(dst, &m_gpr_powerpc, GetGPRSize());
-      dst += GetGPRSize();
-    }
-  }
-  return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(
-    const DataBufferSP &data_sp) {
-  bool success = false;
-  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
-    uint8_t *src = data_sp->GetBytes();
-    if (src) {
-      ::memcpy(&m_gpr_powerpc, src, GetGPRSize());
-
-      if (WriteGPR()) {
-        src += GetGPRSize();
-        ::memcpy(&m_fpr_powerpc, src, sizeof(m_fpr_powerpc));
-
-        success = WriteFPR();
-      }
-    }
-  }
-  return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(
-    addr_t addr, size_t size, bool read, bool write) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  uint32_t hw_index;
-
-  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
-    if (IsWatchpointVacant(hw_index))
-      return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
-  }
-
-  return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(
-    bool enable) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() {
-  lldb::addr_t pc;
-
-  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
-    return false;
-
-  return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(
-    unsigned offset) {
-  unsigned reg;
-  for (reg = 0; reg < k_num_registers_powerpc; reg++) {
-    if (GetRegisterInfo()[reg].byte_offset == offset)
-      break;
-  }
-  assert(reg < k_num_registers_powerpc && "Invalid register offset.");
-  return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() {
-  return false;
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(
-    uint32_t hw_index) {
-  return LLDB_INVALID_ADDRESS;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(
-    uint32_t hw_index) {
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(
-    addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
-  return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() {
-  return 0;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
deleted file mode 100644
index 328db44..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_powerpc.h -------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContextPOSIXProcessMonitor_powerpc
-    : public RegisterContextPOSIX_powerpc,
-      public POSIXBreakpointProtocol {
-public:
-  RegisterContextPOSIXProcessMonitor_powerpc(
-      lldb_private::Thread &thread, uint32_t concrete_frame_idx,
-      lldb_private::RegisterInfoInterface *register_info);
-
-protected:
-  bool IsVMX();
-
-  bool ReadGPR() override;
-
-  bool ReadFPR() override;
-
-  bool ReadVMX() override;
-
-  bool WriteGPR() override;
-
-  bool WriteFPR() override;
-
-  bool WriteVMX() override;
-
-  // lldb_private::RegisterContext
-  bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
-  bool WriteRegister(const unsigned reg,
-                     const lldb_private::RegisterValue &value);
-
-  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
-                    lldb_private::RegisterValue &value) override;
-
-  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
-                     const lldb_private::RegisterValue &value) override;
-
-  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  bool HardwareSingleStep(bool enable) override;
-
-  // POSIXBreakpointProtocol
-  bool UpdateAfterBreakpoint() override;
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset) override;
-
-  bool IsWatchpointHit(uint32_t hw_index) override;
-
-  bool ClearWatchpointHits() override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t hw_index) override;
-
-  bool IsWatchpointVacant(uint32_t hw_index) override;
-
-  bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
-                                      bool write, uint32_t hw_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-private:
-  ProcessMonitor &GetMonitor();
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
deleted file mode 100644
index b1739e1..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.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 "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
-#include "Plugins/Process/FreeBSD/ProcessMonitor.h"
-#include "RegisterContextPOSIXProcessMonitor_x86.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-// Support ptrace extensions even when compiled without required kernel support
-#ifndef NT_X86_XSTATE
-#define NT_X86_XSTATE 0x202
-#endif
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
-
-static uint32_t size_and_rw_bits(size_t size, bool read, bool write) {
-  uint32_t rw;
-
-  if (read)
-    rw = 0x3; // READ or READ/WRITE
-  else if (write)
-    rw = 0x1; // WRITE
-  else
-    assert(0 && "read and write cannot both be false");
-
-  switch (size) {
-  case 1:
-    return rw;
-  case 2:
-    return (0x1 << 2) | rw;
-  case 4:
-    return (0x3 << 2) | rw;
-  case 8:
-    return (0x2 << 2) | rw;
-  default:
-    assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
-    return 0; // Unreachable. Just to silence compiler.
-  }
-}
-
-RegisterContextPOSIXProcessMonitor_x86_64::
-    RegisterContextPOSIXProcessMonitor_x86_64(
-        Thread &thread, uint32_t concrete_frame_idx,
-        lldb_private::RegisterInfoInterface *register_info)
-    : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info) {
-  // Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
-  const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
-  m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
-
-  m_iovec.iov_base = &m_fpr.xsave;
-  m_iovec.iov_len = sizeof(m_fpr.xsave);
-}
-
-ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
-  ProcessSP base = CalculateProcess();
-  ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(base.get());
-  return process->GetMonitor();
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  if (GetFPRType() == eFXSAVE)
-    return monitor.ReadFPR(m_thread.GetID(), &m_fpr.fxsave,
-                           sizeof(m_fpr.fxsave));
-
-  if (GetFPRType() == eXSAVE)
-    return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
-                                   sizeof(m_fpr.xsave), NT_X86_XSTATE);
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
-  ProcessMonitor &monitor = GetMonitor();
-  if (GetFPRType() == eFXSAVE)
-    return monitor.WriteFPR(m_thread.GetID(), &m_fpr.fxsave,
-                            sizeof(m_fpr.fxsave));
-
-  if (GetFPRType() == eXSAVE)
-    return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
-                                    sizeof(m_fpr.xsave), NT_X86_XSTATE);
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
-    const unsigned reg, RegisterValue &value) {
-  ProcessMonitor &monitor = GetMonitor();
-
-#if defined(__FreeBSD__)
-  if (reg >= m_reg_info.first_dr)
-    return monitor.ReadDebugRegisterValue(
-        m_thread.GetID(), GetRegisterOffset(reg), GetRegisterName(reg),
-        GetRegisterSize(reg), value);
-#endif
-  return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg),
-                                   GetRegisterName(reg), GetRegisterSize(reg),
-                                   value);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
-    const unsigned reg, const RegisterValue &value) {
-  unsigned reg_to_write = reg;
-  RegisterValue value_to_write = value;
-
-  // Check if this is a subregister of a full register.
-  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
-  if (reg_info->invalidate_regs &&
-      (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
-    RegisterValue full_value;
-    uint32_t full_reg = reg_info->invalidate_regs[0];
-    const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
-    // Read the full register.
-    if (ReadRegister(full_reg_info, full_value)) {
-      Status error;
-      ByteOrder byte_order = GetByteOrder();
-      uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
-      // Get the bytes for the full register.
-      const uint32_t dest_size = full_value.GetAsMemoryData(
-          full_reg_info, dst, sizeof(dst), byte_order, error);
-      if (error.Success() && dest_size) {
-        uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
-        // Get the bytes for the source data.
-        const uint32_t src_size = value.GetAsMemoryData(
-            reg_info, src, sizeof(src), byte_order, error);
-        if (error.Success() && src_size && (src_size < dest_size)) {
-          // Copy the src bytes to the destination.
-          memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
-          // Set this full register as the value to write.
-          value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
-          value_to_write.SetType(full_reg_info);
-          reg_to_write = full_reg;
-        }
-      }
-    }
-  }
-
-  ProcessMonitor &monitor = GetMonitor();
-#if defined(__FreeBSD__)
-  if (reg >= m_reg_info.first_dr)
-    return monitor.WriteDebugRegisterValue(
-        m_thread.GetID(), GetRegisterOffset(reg_to_write),
-        GetRegisterName(reg_to_write), value_to_write);
-#endif
-  return monitor.WriteRegisterValue(
-      m_thread.GetID(), GetRegisterOffset(reg_to_write),
-      GetRegisterName(reg_to_write), value_to_write);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
-    const RegisterInfo *reg_info, RegisterValue &value) {
-  if (!reg_info)
-    return false;
-
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsFPR(reg, GetFPRType())) {
-    if (!ReadFPR())
-      return false;
-  } else {
-    uint32_t full_reg = reg;
-    bool is_subreg = reg_info->invalidate_regs &&
-                     (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
-    if (is_subreg) {
-      // Read the full aligned 64-bit register.
-      full_reg = reg_info->invalidate_regs[0];
-    }
-
-    bool success = ReadRegister(full_reg, value);
-
-    if (success) {
-      // If our read was not aligned (for ah,bh,ch,dh), shift our returned
-      // value one byte to the right.
-      if (is_subreg && (reg_info->byte_offset & 0x1))
-        value.SetUInt64(value.GetAsUInt64() >> 8);
-
-      // If our return byte size was greater than the return value reg size,
-      // then use the type specified by reg_info rather than the uint64_t
-      // default
-      if (value.GetByteSize() > reg_info->byte_size)
-        value.SetType(reg_info);
-    }
-    return success;
-  }
-
-  if (reg_info->encoding == eEncodingVector) {
-    ByteOrder byte_order = GetByteOrder();
-
-    if (byte_order != ByteOrder::eByteOrderInvalid) {
-      if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
-        value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
-                       reg_info->byte_size, byte_order);
-      if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
-        value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
-                       reg_info->byte_size, byte_order);
-      if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
-        value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
-                       reg_info->byte_size, byte_order);
-      if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
-        // Concatenate ymm using the register halves in xmm.bytes and
-        // ymmh.bytes
-        if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
-          value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
-                         reg_info->byte_size, byte_order);
-        else
-          return false;
-      }
-      return value.GetType() == RegisterValue::eTypeBytes;
-    }
-    return false;
-  }
-
-  // Get pointer to m_fpr.fxsave variable and set the data from it. Byte
-  // offsets of all registers are calculated wrt 'UserArea' structure. However,
-  // ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)} and stores
-  // them in 'm_fpr' (of type FPR structure). To extract values of fpu
-  // registers, m_fpr should be read at byte offsets calculated wrt to FPR
-  // structure.
-
-  // Since, FPR structure is also one of the member of UserArea structure.
-  // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
-  // byte_offset(fctrl wrt UserArea)
-  assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
-  uint8_t *src =
-      (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
-  switch (reg_info->byte_size) {
-  case 1:
-    value.SetUInt8(*(uint8_t *)src);
-    return true;
-  case 2:
-    value.SetUInt16(*(uint16_t *)src);
-    return true;
-  case 4:
-    value.SetUInt32(*(uint32_t *)src);
-    return true;
-  case 8:
-    value.SetUInt64(*(uint64_t *)src);
-    return true;
-  default:
-    assert(false && "Unhandled data size.");
-    return false;
-  }
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
-    const RegisterInfo *reg_info, const RegisterValue &value) {
-  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-  if (IsGPR(reg))
-    return WriteRegister(reg, value);
-
-  if (IsFPR(reg, GetFPRType())) {
-    if (reg_info->encoding == eEncodingVector) {
-      if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
-        ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
-                 value.GetBytes(), value.GetByteSize());
-
-      if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
-        ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
-                 value.GetBytes(), value.GetByteSize());
-
-      if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
-        ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
-                 value.GetBytes(), value.GetByteSize());
-
-      if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
-        if (GetFPRType() != eXSAVE)
-          return false; // the target processor does not support AVX
-
-        // Store ymm register content, and split into the register halves in
-        // xmm.bytes and ymmh.bytes
-        ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
-                 value.GetBytes(), value.GetByteSize());
-        if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
-          return false;
-      }
-    } else {
-      // Get pointer to m_fpr.fxsave variable and set the data to it. Byte
-      // offsets of all registers are calculated wrt 'UserArea' structure.
-      // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
-      // only fpu registers using ptrace(PT_SETFPREGS,..) API. Hence fpu
-      // registers should be written in m_fpr at byte offsets calculated wrt
-      // FPR structure.
-
-      // Since, FPR structure is also one of the member of UserArea structure.
-      // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
-      // byte_offset(fctrl wrt UserArea)
-      assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
-             sizeof(m_fpr));
-      uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
-                     m_fctrl_offset_in_userarea;
-      switch (reg_info->byte_size) {
-      case 1:
-        *(uint8_t *)dst = value.GetAsUInt8();
-        break;
-      case 2:
-        *(uint16_t *)dst = value.GetAsUInt16();
-        break;
-      case 4:
-        *(uint32_t *)dst = value.GetAsUInt32();
-        break;
-      case 8:
-        *(uint64_t *)dst = value.GetAsUInt64();
-        break;
-      default:
-        assert(false && "Unhandled data size.");
-        return false;
-      }
-    }
-
-    if (WriteFPR()) {
-      if (IsAVX(reg))
-        return CopyYMMtoXSTATE(reg, GetByteOrder());
-      return true;
-    }
-  }
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
-    DataBufferSP &data_sp) {
-  bool success = false;
-  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  if (ReadGPR() && ReadFPR()) {
-    uint8_t *dst = data_sp->GetBytes();
-    success = dst != 0;
-
-    if (success) {
-      ::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
-      dst += GetGPRSize();
-      if (GetFPRType() == eFXSAVE)
-        ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
-    }
-
-    if (GetFPRType() == eXSAVE) {
-      ByteOrder byte_order = GetByteOrder();
-
-      // Assemble the YMM register content from the register halves.
-      for (uint32_t reg = m_reg_info.first_ymm;
-           success && reg <= m_reg_info.last_ymm; ++reg)
-        success = CopyXSTATEtoYMM(reg, byte_order);
-
-      if (success) {
-        // Copy the extended register state including the assembled ymm
-        // registers.
-        ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-      }
-    }
-  }
-  return success;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(
-    const DataBufferSP &data_sp) {
-  bool success = false;
-  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
-    uint8_t *src = data_sp->GetBytes();
-    if (src) {
-      ::memcpy(&m_gpr_x86_64, src, GetGPRSize());
-
-      if (WriteGPR()) {
-        src += GetGPRSize();
-        if (GetFPRType() == eFXSAVE)
-          ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
-        if (GetFPRType() == eXSAVE)
-          ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
-
-        success = WriteFPR();
-        if (success) {
-          if (GetFPRType() == eXSAVE) {
-            ByteOrder byte_order = GetByteOrder();
-
-            // Parse the YMM register content from the register halves.
-            for (uint32_t reg = m_reg_info.first_ymm;
-                 success && reg <= m_reg_info.last_ymm; ++reg)
-              success = CopyYMMtoXSTATE(reg, byte_order);
-          }
-        }
-      }
-    }
-  }
-  return success;
-}
-
-uint32_t RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(
-    addr_t addr, size_t size, bool read, bool write) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-  uint32_t hw_index;
-
-  for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) {
-    if (IsWatchpointVacant(hw_index))
-      return SetHardwareWatchpointWithIndex(addr, size, read, write, hw_index);
-  }
-
-  return LLDB_INVALID_INDEX32;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(
-    uint32_t hw_index) {
-  if (hw_index < NumSupportedHardwareWatchpoints()) {
-    RegisterValue current_dr7_bits;
-
-    if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
-      uint64_t new_dr7_bits =
-          current_dr7_bits.GetAsUInt64() & ~(3 << (2 * hw_index));
-
-      if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
-        return true;
-    }
-  }
-
-  return false;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(
-    bool enable) {
-  enum { TRACE_BIT = 0x100 };
-  uint64_t rflags;
-
-  if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
-    return false;
-
-  if (enable) {
-    if (rflags & TRACE_BIT)
-      return true;
-
-    rflags |= TRACE_BIT;
-  } else {
-    if (!(rflags & TRACE_BIT))
-      return false;
-
-    rflags &= ~TRACE_BIT;
-  }
-
-  return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint() {
-  // PC points one byte past the int3 responsible for the breakpoint.
-  lldb::addr_t pc;
-
-  if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
-    return false;
-
-  SetPC(pc - 1);
-  return true;
-}
-
-unsigned RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(
-    unsigned offset) {
-  unsigned reg;
-  for (reg = 0; reg < m_reg_info.num_registers; reg++) {
-    if (GetRegisterInfo()[reg].byte_offset == offset)
-      break;
-  }
-  assert(reg < m_reg_info.num_registers && "Invalid register offset.");
-  return reg;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(
-    uint32_t hw_index) {
-  bool is_hit = false;
-
-  if (m_watchpoints_initialized == false) {
-    // Reset the debug status and debug control registers
-    RegisterValue zero_bits = RegisterValue(uint64_t(0));
-    if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
-        !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
-      assert(false && "Could not initialize watchpoint registers");
-    m_watchpoints_initialized = true;
-  }
-
-  if (hw_index < NumSupportedHardwareWatchpoints()) {
-    RegisterValue value;
-
-    if (ReadRegister(m_reg_info.first_dr + 6, value)) {
-      uint64_t val = value.GetAsUInt64();
-      is_hit = val & (1 << hw_index);
-    }
-  }
-
-  return is_hit;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits() {
-  return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
-}
-
-addr_t RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(
-    uint32_t hw_index) {
-  addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
-
-  if (hw_index < NumSupportedHardwareWatchpoints()) {
-    if (!IsWatchpointVacant(hw_index)) {
-      RegisterValue value;
-
-      if (ReadRegister(m_reg_info.first_dr + hw_index, value))
-        wp_monitor_addr = value.GetAsUInt64();
-    }
-  }
-
-  return wp_monitor_addr;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(
-    uint32_t hw_index) {
-  bool is_vacant = false;
-  RegisterValue value;
-
-  assert(hw_index < NumSupportedHardwareWatchpoints());
-
-  if (m_watchpoints_initialized == false) {
-    // Reset the debug status and debug control registers
-    RegisterValue zero_bits = RegisterValue(uint64_t(0));
-    if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) ||
-        !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
-      assert(false && "Could not initialize watchpoint registers");
-    m_watchpoints_initialized = true;
-  }
-
-  if (ReadRegister(m_reg_info.first_dr + 7, value)) {
-    uint64_t val = value.GetAsUInt64();
-    is_vacant = (val & (3 << 2 * hw_index)) == 0;
-  }
-
-  return is_vacant;
-}
-
-bool RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(
-    addr_t addr, size_t size, bool read, bool write, uint32_t hw_index) {
-  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
-  if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
-    return false;
-
-  if (!(size == 1 || size == 2 || size == 4 || size == 8))
-    return false;
-
-  if (read == false && write == false)
-    return false;
-
-  if (!IsWatchpointVacant(hw_index))
-    return false;
-
-  // Set both dr7 (debug control register) and dri (debug address register).
-
-  // dr7{7-0} encodes the local/global enable bits:
-  //  global enable --. .-- local enable
-  //                  | |
-  //                  v v
-  //      dr0 -> bits{1-0}
-  //      dr1 -> bits{3-2}
-  //      dr2 -> bits{5-4}
-  //      dr3 -> bits{7-6}
-  //
-  // dr7{31-16} encodes the rw/len bits:
-  //  b_x+3, b_x+2, b_x+1, b_x
-  //      where bits{x+1, x} => rw
-  //            0b00: execute, 0b01: write, 0b11: read-or-write,
-  //            0b10: io read-or-write (unused)
-  //      and bits{x+3, x+2} => len
-  //            0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
-  //
-  //      dr0 -> bits{19-16}
-  //      dr1 -> bits{23-20}
-  //      dr2 -> bits{27-24}
-  //      dr3 -> bits{31-28}
-  if (hw_index < num_hw_watchpoints) {
-    RegisterValue current_dr7_bits;
-
-    if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits)) {
-      uint64_t new_dr7_bits =
-          current_dr7_bits.GetAsUInt64() |
-          (1 << (2 * hw_index) |
-           size_and_rw_bits(size, read, write) << (16 + 4 * hw_index));
-
-      if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
-          WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
-        return true;
-    }
-  }
-
-  return false;
-}
-
-uint32_t
-RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints() {
-  // Available debug address registers: dr0, dr1, dr2, dr3
-  return 4;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
deleted file mode 100644
index 1afb366..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- RegisterContextPOSIXProcessMonitor_x86.h ----------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
-
-#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
-#include "RegisterContextPOSIX.h"
-#include <sys/uio.h>
-
-class RegisterContextPOSIXProcessMonitor_x86_64
-    : public RegisterContextPOSIX_x86,
-      public POSIXBreakpointProtocol {
-public:
-  RegisterContextPOSIXProcessMonitor_x86_64(
-      lldb_private::Thread &thread, uint32_t concrete_frame_idx,
-      lldb_private::RegisterInfoInterface *register_info);
-
-protected:
-  bool ReadGPR() override;
-
-  bool ReadFPR() override;
-
-  bool WriteGPR() override;
-
-  bool WriteFPR() override;
-
-  // lldb_private::RegisterContext
-  bool ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
-  bool WriteRegister(const unsigned reg,
-                     const lldb_private::RegisterValue &value);
-
-  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
-                    lldb_private::RegisterValue &value) override;
-
-  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
-                     const lldb_private::RegisterValue &value) override;
-
-  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  bool HardwareSingleStep(bool enable) override;
-
-  // POSIXBreakpointProtocol
-  bool UpdateAfterBreakpoint() override;
-
-  unsigned GetRegisterIndexFromOffset(unsigned offset) override;
-
-  bool IsWatchpointHit(uint32_t hw_index) override;
-
-  bool ClearWatchpointHits() override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t hw_index) override;
-
-  bool IsWatchpointVacant(uint32_t hw_index) override;
-
-  bool SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read,
-                                      bool write, uint32_t hw_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-private:
-  ProcessMonitor &GetMonitor();
-  uint32_t
-      m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
-  struct iovec m_iovec;
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
deleted file mode 100644
index 8c1cec5..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_lldb_library(lldbPluginProcessFreeBSDRemote
-  NativeProcessFreeBSD.cpp
-  NativeRegisterContextFreeBSD.cpp
-  NativeRegisterContextFreeBSD_x86_64.cpp
-  NativeThreadFreeBSD.cpp
-
-  LINK_LIBS
-    lldbHost
-    lldbSymbol
-    lldbTarget
-    lldbUtility
-    lldbPluginProcessPOSIX
-    lldbPluginProcessUtility
-  LINK_COMPONENTS
-    Support
-  )
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/Linux/CMakeLists.txt
index dd2a889..c4edc57 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/CMakeLists.txt
@@ -1,14 +1,13 @@
 add_lldb_library(lldbPluginProcessLinux
+  IntelPTManager.cpp
   NativeProcessLinux.cpp
   NativeRegisterContextLinux.cpp
   NativeRegisterContextLinux_arm.cpp
   NativeRegisterContextLinux_arm64.cpp
-  NativeRegisterContextLinux_mips64.cpp
   NativeRegisterContextLinux_ppc64le.cpp
   NativeRegisterContextLinux_s390x.cpp
   NativeRegisterContextLinux_x86_64.cpp
   NativeThreadLinux.cpp
-  ProcessorTrace.cpp
   SingleStepCheck.cpp
 
   LINK_LIBS
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
new file mode 100644
index 0000000..0bd4893
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
@@ -0,0 +1,685 @@
+//===-- IntelPTManager.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 <algorithm>
+#include <fstream>
+#include <sstream>
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+
+#include "IntelPTManager.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "lldb/Host/linux/Support.h"
+#include "lldb/Utility/StreamString.h"
+
+#include <sys/ioctl.h>
+#include <sys/syscall.h>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace process_linux;
+using namespace llvm;
+
+const char *kOSEventIntelPTTypeFile =
+    "/sys/bus/event_source/devices/intel_pt/type";
+
+const char *kPSBPeriodCapFile =
+    "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc";
+
+const char *kPSBPeriodValidValuesFile =
+    "/sys/bus/event_source/devices/intel_pt/caps/psb_periods";
+
+const char *kTSCBitOffsetFile =
+    "/sys/bus/event_source/devices/intel_pt/format/tsc";
+
+const char *kPSBPeriodBitOffsetFile =
+    "/sys/bus/event_source/devices/intel_pt/format/psb_period";
+
+enum IntelPTConfigFileType {
+  Hex = 0,
+  // 0 or 1
+  ZeroOne,
+  Decimal,
+  // a bit index file always starts with the prefix config: following by an int,
+  // which represents the offset of the perf_event_attr.config value where to
+  // store a given configuration.
+  BitOffset
+};
+
+static Expected<uint32_t> ReadIntelPTConfigFile(const char *file,
+                                                IntelPTConfigFileType type) {
+  ErrorOr<std::unique_ptr<MemoryBuffer>> stream =
+      MemoryBuffer::getFileAsStream(file);
+
+  if (!stream)
+    return createStringError(inconvertibleErrorCode(),
+                             "Can't open the file '%s'", file);
+
+  uint32_t value = 0;
+  StringRef text_buffer = stream.get()->getBuffer();
+
+  if (type == BitOffset) {
+    const char *prefix = "config:";
+    if (!text_buffer.startswith(prefix))
+      return createStringError(inconvertibleErrorCode(),
+                               "The file '%s' contents doesn't start with '%s'",
+                               file, prefix);
+    text_buffer = text_buffer.substr(strlen(prefix));
+  }
+
+  auto getRadix = [&]() {
+    switch (type) {
+    case Hex:
+      return 16;
+    case ZeroOne:
+    case Decimal:
+    case BitOffset:
+      return 10;
+    }
+  };
+
+  auto createError = [&](const char *expected_value_message) {
+    return createStringError(
+        inconvertibleErrorCode(),
+        "The file '%s' has an invalid value. It should be %s.", file,
+        expected_value_message);
+  };
+
+  if (text_buffer.trim().consumeInteger(getRadix(), value) ||
+      (type == ZeroOne && value != 0 && value != 1)) {
+    switch (type) {
+    case Hex:
+      return createError("an unsigned hexadecimal int");
+    case ZeroOne:
+      return createError("0 or 1");
+    case Decimal:
+    case BitOffset:
+      return createError("an unsigned decimal int");
+    }
+  }
+  return value;
+}
+/// Return the Linux perf event type for Intel PT.
+static Expected<uint32_t> GetOSEventType() {
+  return ReadIntelPTConfigFile(kOSEventIntelPTTypeFile,
+                               IntelPTConfigFileType::Decimal);
+}
+
+static Error CheckPsbPeriod(size_t psb_period) {
+  Expected<uint32_t> cap =
+      ReadIntelPTConfigFile(kPSBPeriodCapFile, IntelPTConfigFileType::ZeroOne);
+  if (!cap)
+    return cap.takeError();
+  if (*cap == 0)
+    return createStringError(inconvertibleErrorCode(),
+                             "psb_period is unsupported in the system.");
+
+  Expected<uint32_t> valid_values = ReadIntelPTConfigFile(
+      kPSBPeriodValidValuesFile, IntelPTConfigFileType::Hex);
+  if (!valid_values)
+    return valid_values.takeError();
+
+  if (valid_values.get() & (1 << psb_period))
+    return Error::success();
+
+  std::ostringstream error;
+  // 0 is always a valid value
+  error << "Invalid psb_period. Valid values are: 0";
+  uint32_t mask = valid_values.get();
+  while (mask) {
+    int index = __builtin_ctz(mask);
+    if (index > 0)
+      error << ", " << index;
+    // clear the lowest bit
+    mask &= mask - 1;
+  }
+  error << ".";
+  return createStringError(inconvertibleErrorCode(), error.str().c_str());
+}
+
+size_t IntelPTThreadTrace::GetTraceBufferSize() const {
+  return m_mmap_meta->aux_size;
+}
+
+static Expected<uint64_t>
+GeneratePerfEventConfigValue(bool enable_tsc, Optional<size_t> psb_period) {
+  uint64_t config = 0;
+  // tsc is always supported
+  if (enable_tsc) {
+    if (Expected<uint32_t> offset = ReadIntelPTConfigFile(
+            kTSCBitOffsetFile, IntelPTConfigFileType::BitOffset))
+      config |= 1 << *offset;
+    else
+      return offset.takeError();
+  }
+  if (psb_period) {
+    if (Error error = CheckPsbPeriod(*psb_period))
+      return std::move(error);
+
+    if (Expected<uint32_t> offset = ReadIntelPTConfigFile(
+            kPSBPeriodBitOffsetFile, IntelPTConfigFileType::BitOffset))
+      config |= *psb_period << *offset;
+    else
+      return offset.takeError();
+  }
+  return config;
+}
+
+Error IntelPTThreadTrace::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
+                                     uint64_t buffer_size, bool enable_tsc,
+                                     Optional<size_t> psb_period) {
+#ifndef PERF_ATTR_SIZE_VER5
+  llvm_unreachable("Intel PT Linux perf event not supported");
+#else
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+  m_tid = tid;
+  LLDB_LOG(log, "called thread id {0}", tid);
+  uint64_t page_size = getpagesize();
+
+  if (__builtin_popcount(buffer_size) != 1 || buffer_size < 4096) {
+    return createStringError(
+        inconvertibleErrorCode(),
+        "The trace buffer size must be a power of 2 greater than or equal to "
+        "4096 (2^12) bytes. It was %" PRIu64 ".",
+        buffer_size);
+  }
+  uint64_t numpages = static_cast<uint64_t>(
+      llvm::PowerOf2Floor((buffer_size + page_size - 1) / page_size));
+  numpages = std::max<uint64_t>(1, numpages);
+  buffer_size = page_size * numpages;
+
+  perf_event_attr attr;
+  memset(&attr, 0, sizeof(attr));
+  attr.size = sizeof(attr);
+  attr.exclude_kernel = 1;
+  attr.sample_type = PERF_SAMPLE_TIME;
+  attr.sample_id_all = 1;
+  attr.exclude_hv = 1;
+  attr.exclude_idle = 1;
+  attr.mmap = 1;
+
+  if (Expected<uint64_t> config_value =
+          GeneratePerfEventConfigValue(enable_tsc, psb_period)) {
+    attr.config = *config_value;
+    LLDB_LOG(log, "intel pt config {0}", attr.config);
+  } else {
+    return config_value.takeError();
+  }
+
+  if (Expected<uint32_t> intel_pt_type = GetOSEventType()) {
+    attr.type = *intel_pt_type;
+    LLDB_LOG(log, "intel pt type {0}", attr.type);
+  } else {
+    return intel_pt_type.takeError();
+  }
+
+  LLDB_LOG(log, "buffer size {0} ", buffer_size);
+
+  errno = 0;
+  auto fd =
+      syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0);
+  if (fd == -1) {
+    LLDB_LOG(log, "syscall error {0}", errno);
+    return createStringError(inconvertibleErrorCode(),
+                             "perf event syscall failed");
+  }
+
+  m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());
+
+  errno = 0;
+  auto base =
+      mmap(nullptr, (buffer_size + page_size), PROT_WRITE, MAP_SHARED, fd, 0);
+
+  if (base == MAP_FAILED) {
+    LLDB_LOG(log, "mmap base error {0}", errno);
+    return createStringError(inconvertibleErrorCode(),
+                             "Meta buffer allocation failed");
+  }
+
+  m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
+      reinterpret_cast<perf_event_mmap_page *>(base),
+      munmap_delete(buffer_size + page_size));
+
+  m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
+  m_mmap_meta->aux_size = buffer_size;
+
+  errno = 0;
+  auto mmap_aux = mmap(nullptr, buffer_size, PROT_READ, MAP_SHARED, fd,
+                       static_cast<long int>(m_mmap_meta->aux_offset));
+
+  if (mmap_aux == MAP_FAILED) {
+    LLDB_LOG(log, "second mmap done {0}", errno);
+    return createStringError(inconvertibleErrorCode(),
+                             "Trace buffer allocation failed");
+  }
+  m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
+      reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(buffer_size));
+  return Error::success();
+#endif
+}
+
+llvm::MutableArrayRef<uint8_t> IntelPTThreadTrace::GetDataBuffer() const {
+#ifndef PERF_ATTR_SIZE_VER5
+  llvm_unreachable("Intel PT Linux perf event not supported");
+#else
+  return MutableArrayRef<uint8_t>(
+      (reinterpret_cast<uint8_t *>(m_mmap_meta.get()) +
+       m_mmap_meta->data_offset),
+      m_mmap_meta->data_size);
+#endif
+}
+
+llvm::MutableArrayRef<uint8_t> IntelPTThreadTrace::GetAuxBuffer() const {
+#ifndef PERF_ATTR_SIZE_VER5
+  llvm_unreachable("Intel PT Linux perf event not supported");
+#else
+  return MutableArrayRef<uint8_t>(m_mmap_aux.get(), m_mmap_meta->aux_size);
+#endif
+}
+
+Expected<ArrayRef<uint8_t>> IntelPTThreadTrace::GetCPUInfo() {
+  static llvm::Optional<std::vector<uint8_t>> cpu_info;
+  if (!cpu_info) {
+    auto buffer_or_error = getProcFile("cpuinfo");
+    if (!buffer_or_error)
+      return Status(buffer_or_error.getError()).ToError();
+    MemoryBuffer &buffer = **buffer_or_error;
+    cpu_info = std::vector<uint8_t>(
+        reinterpret_cast<const uint8_t *>(buffer.getBufferStart()),
+        reinterpret_cast<const uint8_t *>(buffer.getBufferEnd()));
+  }
+  return *cpu_info;
+}
+
+llvm::Expected<IntelPTThreadTraceUP>
+IntelPTThreadTrace::Create(lldb::pid_t pid, lldb::tid_t tid, size_t buffer_size,
+                           bool enable_tsc, Optional<size_t> psb_period) {
+  IntelPTThreadTraceUP thread_trace_up(new IntelPTThreadTrace());
+
+  if (llvm::Error err = thread_trace_up->StartTrace(pid, tid, buffer_size,
+                                                    enable_tsc, psb_period))
+    return std::move(err);
+
+  return std::move(thread_trace_up);
+}
+
+Expected<std::vector<uint8_t>>
+IntelPTThreadTrace::GetIntelPTBuffer(size_t offset, size_t size) const {
+  std::vector<uint8_t> data(size, 0);
+  MutableArrayRef<uint8_t> buffer_ref(data);
+  Status error = ReadPerfTraceAux(buffer_ref, 0);
+  if (error.Fail())
+    return error.ToError();
+  return data;
+}
+
+Status
+IntelPTThreadTrace::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
+                                     size_t offset) const {
+#ifndef PERF_ATTR_SIZE_VER5
+  llvm_unreachable("perf event not supported");
+#else
+  // Disable the perf event to force a flush out of the CPU's internal buffer.
+  // Besides, we can guarantee that the CPU won't override any data as we are
+  // reading the buffer.
+  //
+  // The Intel documentation says:
+  //
+  // Packets are first buffered internally and then written out asynchronously.
+  // To collect packet output for postprocessing, a collector needs first to
+  // ensure that all packet data has been flushed from internal buffers.
+  // Software can ensure this by stopping packet generation by clearing
+  // IA32_RTIT_CTL.TraceEn (see “Disabling Packet Generation” in
+  // Section 35.2.7.2).
+  //
+  // This is achieved by the PERF_EVENT_IOC_DISABLE ioctl request, as mentioned
+  // in the man page of perf_event_open.
+  ioctl(*m_fd, PERF_EVENT_IOC_DISABLE);
+
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+  Status error;
+  uint64_t head = m_mmap_meta->aux_head;
+
+  LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);
+
+  /**
+   * When configured as ring buffer, the aux buffer keeps wrapping around
+   * the buffer and its not possible to detect how many times the buffer
+   * wrapped. Initially the buffer is filled with zeros,as shown below
+   * so in order to get complete buffer we first copy firstpartsize, followed
+   * by any left over part from beginning to aux_head
+   *
+   * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size
+   *                 aux_head->||<- firstpartsize  ->|
+   *
+   * */
+
+  ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast<size_t>(head), offset);
+  LLDB_LOG(log, "ReadCyclic BUffer Done");
+
+  // Reenable tracing now we have read the buffer
+  ioctl(*m_fd, PERF_EVENT_IOC_ENABLE);
+  return error;
+#endif
+}
+
+Status
+IntelPTThreadTrace::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
+                                      size_t offset) const {
+#ifndef PERF_ATTR_SIZE_VER5
+  llvm_unreachable("perf event not supported");
+#else
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+  uint64_t bytes_remaining = buffer.size();
+  Status error;
+
+  uint64_t head = m_mmap_meta->data_head;
+
+  /*
+   * The data buffer and aux buffer have different implementations
+   * with respect to their definition of head pointer. In the case
+   * of Aux data buffer the head always wraps around the aux buffer
+   * and we don't need to care about it, whereas the data_head keeps
+   * increasing and needs to be wrapped by modulus operator
+   */
+
+  LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining);
+
+  auto data_buffer = GetDataBuffer();
+
+  if (head > data_buffer.size()) {
+    head = head % data_buffer.size();
+    LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head);
+
+    ReadCyclicBuffer(buffer, data_buffer, static_cast<size_t>(head), offset);
+    bytes_remaining -= buffer.size();
+  } else {
+    LLDB_LOG(log, "Head - {0}", head);
+    if (offset >= head) {
+      LLDB_LOG(log, "Invalid Offset ");
+      error.SetErrorString("invalid offset");
+      buffer = buffer.slice(buffer.size());
+      return error;
+    }
+
+    auto data = data_buffer.slice(offset, (head - offset));
+    auto remaining = std::copy(data.begin(), data.end(), buffer.begin());
+    bytes_remaining -= (remaining - buffer.begin());
+  }
+  buffer = buffer.drop_back(bytes_remaining);
+  return error;
+#endif
+}
+
+void IntelPTThreadTrace::ReadCyclicBuffer(llvm::MutableArrayRef<uint8_t> &dst,
+                                          llvm::MutableArrayRef<uint8_t> src,
+                                          size_t src_cyc_index, size_t offset) {
+
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+
+  if (dst.empty() || src.empty()) {
+    dst = dst.drop_back(dst.size());
+    return;
+  }
+
+  if (dst.data() == nullptr || src.data() == nullptr) {
+    dst = dst.drop_back(dst.size());
+    return;
+  }
+
+  if (src_cyc_index > src.size()) {
+    dst = dst.drop_back(dst.size());
+    return;
+  }
+
+  if (offset >= src.size()) {
+    LLDB_LOG(log, "Too Big offset ");
+    dst = dst.drop_back(dst.size());
+    return;
+  }
+
+  llvm::SmallVector<MutableArrayRef<uint8_t>, 2> parts = {
+      src.slice(src_cyc_index), src.take_front(src_cyc_index)};
+
+  if (offset > parts[0].size()) {
+    parts[1] = parts[1].slice(offset - parts[0].size());
+    parts[0] = parts[0].drop_back(parts[0].size());
+  } else if (offset == parts[0].size()) {
+    parts[0] = parts[0].drop_back(parts[0].size());
+  } else {
+    parts[0] = parts[0].slice(offset);
+  }
+  auto next = dst.begin();
+  auto bytes_left = dst.size();
+  for (auto part : parts) {
+    size_t chunk_size = std::min(part.size(), bytes_left);
+    next = std::copy_n(part.begin(), chunk_size, next);
+    bytes_left -= chunk_size;
+  }
+  dst = dst.drop_back(bytes_left);
+}
+
+TraceThreadState IntelPTThreadTrace::GetState() const {
+  return {static_cast<int64_t>(m_tid),
+          {TraceBinaryData{"threadTraceBuffer",
+                           static_cast<int64_t>(GetTraceBufferSize())}}};
+}
+
+/// IntelPTThreadTraceCollection
+
+bool IntelPTThreadTraceCollection::TracesThread(lldb::tid_t tid) const {
+  return m_thread_traces.count(tid);
+}
+
+Error IntelPTThreadTraceCollection::TraceStop(lldb::tid_t tid) {
+  auto it = m_thread_traces.find(tid);
+  if (it == m_thread_traces.end())
+    return createStringError(inconvertibleErrorCode(),
+                             "Thread %" PRIu64 " not currently traced", tid);
+  m_total_buffer_size -= it->second->GetTraceBufferSize();
+  m_thread_traces.erase(tid);
+  return Error::success();
+}
+
+Error IntelPTThreadTraceCollection::TraceStart(
+    lldb::tid_t tid, const TraceIntelPTStartRequest &request) {
+  if (TracesThread(tid))
+    return createStringError(inconvertibleErrorCode(),
+                             "Thread %" PRIu64 " already traced", tid);
+
+  Expected<IntelPTThreadTraceUP> trace_up = IntelPTThreadTrace::Create(
+      m_pid, tid, request.threadBufferSize, request.enableTsc,
+      request.psbPeriod.map([](int64_t period) { return (size_t)period; }));
+  if (!trace_up)
+    return trace_up.takeError();
+
+  m_total_buffer_size += (*trace_up)->GetTraceBufferSize();
+  m_thread_traces.try_emplace(tid, std::move(*trace_up));
+  return Error::success();
+}
+
+size_t IntelPTThreadTraceCollection::GetTotalBufferSize() const {
+  return m_total_buffer_size;
+}
+
+std::vector<TraceThreadState>
+IntelPTThreadTraceCollection::GetThreadStates() const {
+  std::vector<TraceThreadState> states;
+  for (const auto &it : m_thread_traces)
+    states.push_back(it.second->GetState());
+  return states;
+}
+
+Expected<const IntelPTThreadTrace &>
+IntelPTThreadTraceCollection::GetTracedThread(lldb::tid_t tid) const {
+  auto it = m_thread_traces.find(tid);
+  if (it == m_thread_traces.end())
+    return createStringError(inconvertibleErrorCode(),
+                             "Thread %" PRIu64 " not currently traced", tid);
+  return *it->second.get();
+}
+
+void IntelPTThreadTraceCollection::Clear() {
+  m_thread_traces.clear();
+  m_total_buffer_size = 0;
+}
+
+/// IntelPTProcessTrace
+
+bool IntelPTProcessTrace::TracesThread(lldb::tid_t tid) const {
+  return m_thread_traces.TracesThread(tid);
+}
+
+Error IntelPTProcessTrace::TraceStop(lldb::tid_t tid) {
+  return m_thread_traces.TraceStop(tid);
+}
+
+Error IntelPTProcessTrace::TraceStart(lldb::tid_t tid) {
+  if (m_thread_traces.GetTotalBufferSize() + m_tracing_params.threadBufferSize >
+      static_cast<size_t>(*m_tracing_params.processBufferSizeLimit))
+    return createStringError(
+        inconvertibleErrorCode(),
+        "Thread %" PRIu64 " can't be traced as the process trace size limit "
+        "has been reached. Consider retracing with a higher "
+        "limit.",
+        tid);
+
+  return m_thread_traces.TraceStart(tid, m_tracing_params);
+}
+
+const IntelPTThreadTraceCollection &
+IntelPTProcessTrace::GetThreadTraces() const {
+  return m_thread_traces;
+}
+
+/// IntelPTManager
+
+Error IntelPTManager::TraceStop(lldb::tid_t tid) {
+  if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid))
+    return m_process_trace->TraceStop(tid);
+  return m_thread_traces.TraceStop(tid);
+}
+
+Error IntelPTManager::TraceStop(const TraceStopRequest &request) {
+  if (request.IsProcessTracing()) {
+    Clear();
+    return Error::success();
+  } else {
+    Error error = Error::success();
+    for (int64_t tid : *request.tids)
+      error = joinErrors(std::move(error),
+                         TraceStop(static_cast<lldb::tid_t>(tid)));
+    return error;
+  }
+}
+
+Error IntelPTManager::TraceStart(
+    const TraceIntelPTStartRequest &request,
+    const std::vector<lldb::tid_t> &process_threads) {
+  if (request.IsProcessTracing()) {
+    if (IsProcessTracingEnabled()) {
+      return createStringError(
+          inconvertibleErrorCode(),
+          "Process currently traced. Stop process tracing first");
+    }
+    m_process_trace = IntelPTProcessTrace(m_pid, request);
+
+    Error error = Error::success();
+    for (lldb::tid_t tid : process_threads)
+      error = joinErrors(std::move(error), m_process_trace->TraceStart(tid));
+    return error;
+  } else {
+    Error error = Error::success();
+    for (int64_t tid : *request.tids)
+      error = joinErrors(std::move(error),
+                         m_thread_traces.TraceStart(tid, request));
+    return error;
+  }
+}
+
+Error IntelPTManager::OnThreadCreated(lldb::tid_t tid) {
+  if (!IsProcessTracingEnabled())
+    return Error::success();
+  return m_process_trace->TraceStart(tid);
+}
+
+Error IntelPTManager::OnThreadDestroyed(lldb::tid_t tid) {
+  if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid))
+    return m_process_trace->TraceStop(tid);
+  else if (m_thread_traces.TracesThread(tid))
+    return m_thread_traces.TraceStop(tid);
+  return Error::success();
+}
+
+Expected<json::Value> IntelPTManager::GetState() const {
+  Expected<ArrayRef<uint8_t>> cpu_info = IntelPTThreadTrace::GetCPUInfo();
+  if (!cpu_info)
+    return cpu_info.takeError();
+
+  TraceGetStateResponse state;
+  state.processBinaryData.push_back(
+      {"cpuInfo", static_cast<int64_t>(cpu_info->size())});
+
+  std::vector<TraceThreadState> thread_states =
+      m_thread_traces.GetThreadStates();
+  state.tracedThreads.insert(state.tracedThreads.end(), thread_states.begin(),
+                             thread_states.end());
+
+  if (IsProcessTracingEnabled()) {
+    thread_states = m_process_trace->GetThreadTraces().GetThreadStates();
+    state.tracedThreads.insert(state.tracedThreads.end(), thread_states.begin(),
+                               thread_states.end());
+  }
+  return toJSON(state);
+}
+
+Expected<const IntelPTThreadTrace &>
+IntelPTManager::GetTracedThread(lldb::tid_t tid) const {
+  if (IsProcessTracingEnabled() && m_process_trace->TracesThread(tid))
+    return m_process_trace->GetThreadTraces().GetTracedThread(tid);
+  return m_thread_traces.GetTracedThread(tid);
+}
+
+Expected<std::vector<uint8_t>>
+IntelPTManager::GetBinaryData(const TraceGetBinaryDataRequest &request) const {
+  if (request.kind == "threadTraceBuffer") {
+    if (Expected<const IntelPTThreadTrace &> trace =
+            GetTracedThread(*request.tid))
+      return trace->GetIntelPTBuffer(request.offset, request.size);
+    else
+      return trace.takeError();
+  } else if (request.kind == "cpuInfo") {
+    return IntelPTThreadTrace::GetCPUInfo();
+  }
+  return createStringError(inconvertibleErrorCode(),
+                           "Unsuported trace binary data kind: %s",
+                           request.kind.c_str());
+}
+
+void IntelPTManager::ClearProcessTracing() { m_process_trace = None; }
+
+bool IntelPTManager::IsSupported() {
+  Expected<uint32_t> intel_pt_type = GetOSEventType();
+  if (!intel_pt_type) {
+    llvm::consumeError(intel_pt_type.takeError());
+    return false;
+  }
+  return true;
+}
+
+bool IntelPTManager::IsProcessTracingEnabled() const {
+  return (bool)m_process_trace;
+}
+
+void IntelPTManager::Clear() {
+  ClearProcessTracing();
+  m_thread_traces.Clear();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.h
new file mode 100644
index 0000000..38566a2
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/IntelPTManager.h
@@ -0,0 +1,263 @@
+//===-- IntelPTManager.h -------------------------------------- -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IntelPTManager_H_
+#define liblldb_IntelPTManager_H_
+
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
+#include "lldb/lldb-types.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+
+#include <linux/perf_event.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+namespace lldb_private {
+
+namespace process_linux {
+
+/// This class keeps track of one tracing instance of
+/// Intel(R) Processor Trace on Linux OS at thread level.
+///
+/// The kernel interface for us is the perf_event_open.
+class IntelPTThreadTrace;
+typedef std::unique_ptr<IntelPTThreadTrace> IntelPTThreadTraceUP;
+
+class IntelPTThreadTrace {
+
+  class munmap_delete {
+    size_t m_length;
+
+  public:
+    munmap_delete(size_t length) : m_length(length) {}
+    void operator()(void *ptr) {
+      if (m_length)
+        munmap(ptr, m_length);
+    }
+  };
+
+  class file_close {
+
+  public:
+    file_close() = default;
+    void operator()(int *ptr) {
+      if (ptr == nullptr)
+        return;
+      if (*ptr == -1)
+        return;
+      close(*ptr);
+      std::default_delete<int>()(ptr);
+    }
+  };
+
+  std::unique_ptr<perf_event_mmap_page, munmap_delete> m_mmap_meta;
+  std::unique_ptr<uint8_t, munmap_delete> m_mmap_aux;
+  std::unique_ptr<int, file_close> m_fd;
+  lldb::tid_t m_tid;
+
+  /// Start tracing a thread
+  ///
+  /// \param[in] pid
+  ///     The pid of the process whose thread will be traced.
+  ///
+  /// \param[in] buffer_size
+  ///     Size of the thread buffer in bytes.
+  ///
+  /// \param[in] enable_tsc
+  ///     Whether to use enable TSC timestamps or not.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \param[in] psb_period
+  ///     This value defines the period in which PSB packets will be generated.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \return
+  ///     \a llvm::Error::success if tracing was successful, or an
+  ///     \a llvm::Error otherwise.
+  llvm::Error StartTrace(lldb::pid_t pid, lldb::tid_t tid, uint64_t buffer_size,
+                         bool enable_tsc, llvm::Optional<size_t> psb_period);
+
+  llvm::MutableArrayRef<uint8_t> GetAuxBuffer() const;
+  llvm::MutableArrayRef<uint8_t> GetDataBuffer() const;
+
+  IntelPTThreadTrace()
+      : m_mmap_meta(nullptr, munmap_delete(0)),
+        m_mmap_aux(nullptr, munmap_delete(0)), m_fd(nullptr, file_close()) {}
+
+public:
+  /// Get the content of /proc/cpuinfo that can be later used to decode traces.
+  static llvm::Expected<llvm::ArrayRef<uint8_t>> GetCPUInfo();
+
+  /// Start tracing a thread.
+  ///
+  /// See \a StartTrace.
+  ///
+  /// \return
+  ///   A \a IntelPTThreadTrace instance if tracing was successful, or
+  ///   an \a llvm::Error otherwise.
+  static llvm::Expected<IntelPTThreadTraceUP>
+  Create(lldb::pid_t pid, lldb::tid_t tid, size_t buffer_size, bool enable_tsc,
+         llvm::Optional<size_t> psb_period);
+
+  /// Read the trace buffer of the currently traced thread.
+  ///
+  /// \param[in] offset
+  ///     Offset of the data to read.
+  ///
+  /// \param[in] size
+  ///     Number of bytes to read.
+  ///
+  /// \return
+  ///     A vector with the requested binary data. The vector will have the
+  ///     size of the requested \a size. Non-available positions will be
+  ///     filled with zeroes.
+  llvm::Expected<std::vector<uint8_t>> GetIntelPTBuffer(size_t offset,
+                                                        size_t size) const;
+
+  Status ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
+                          size_t offset = 0) const;
+
+  Status ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
+                           size_t offset = 0) const;
+
+  /// Get the size in bytes of the aux section of the thread or process traced
+  /// by this object.
+  size_t GetTraceBufferSize() const;
+
+  /// Read data from a cyclic buffer
+  ///
+  /// \param[in] [out] buf
+  ///     Destination buffer, the buffer will be truncated to written size.
+  ///
+  /// \param[in] src
+  ///     Source buffer which must be a cyclic buffer.
+  ///
+  /// \param[in] src_cyc_index
+  ///     The index pointer (start of the valid data in the cyclic
+  ///     buffer).
+  ///
+  /// \param[in] offset
+  ///     The offset to begin reading the data in the cyclic buffer.
+  static void ReadCyclicBuffer(llvm::MutableArrayRef<uint8_t> &dst,
+                               llvm::MutableArrayRef<uint8_t> src,
+                               size_t src_cyc_index, size_t offset);
+
+  /// Return the thread-specific part of the jLLDBTraceGetState packet.
+  TraceThreadState GetState() const;
+};
+
+/// Manages a list of thread traces.
+class IntelPTThreadTraceCollection {
+public:
+  IntelPTThreadTraceCollection(lldb::pid_t pid) : m_pid(pid) {}
+
+  /// Dispose of all traces
+  void Clear();
+
+  bool TracesThread(lldb::tid_t tid) const;
+
+  size_t GetTotalBufferSize() const;
+
+  std::vector<TraceThreadState> GetThreadStates() const;
+
+  llvm::Expected<const IntelPTThreadTrace &>
+  GetTracedThread(lldb::tid_t tid) const;
+
+  llvm::Error TraceStart(lldb::tid_t tid,
+                         const TraceIntelPTStartRequest &request);
+
+  llvm::Error TraceStop(lldb::tid_t tid);
+
+private:
+  lldb::pid_t m_pid;
+  llvm::DenseMap<lldb::tid_t, IntelPTThreadTraceUP> m_thread_traces;
+  /// Total actual thread buffer size in bytes
+  size_t m_total_buffer_size = 0;
+};
+
+/// Manages a "process trace" instance.
+class IntelPTProcessTrace {
+public:
+  IntelPTProcessTrace(lldb::pid_t pid, const TraceIntelPTStartRequest &request)
+      : m_thread_traces(pid), m_tracing_params(request) {}
+
+  bool TracesThread(lldb::tid_t tid) const;
+
+  const IntelPTThreadTraceCollection &GetThreadTraces() const;
+
+  llvm::Error TraceStart(lldb::tid_t tid);
+
+  llvm::Error TraceStop(lldb::tid_t tid);
+
+private:
+  IntelPTThreadTraceCollection m_thread_traces;
+  /// Params used to trace threads when the user started "process tracing".
+  TraceIntelPTStartRequest m_tracing_params;
+};
+
+/// Main class that manages intel-pt process and thread tracing.
+class IntelPTManager {
+public:
+  IntelPTManager(lldb::pid_t pid) : m_pid(pid), m_thread_traces(pid) {}
+
+  static bool IsSupported();
+
+  /// If "process tracing" is enabled, then trace the given thread.
+  llvm::Error OnThreadCreated(lldb::tid_t tid);
+
+  /// Stops tracing a tracing upon a destroy event.
+  llvm::Error OnThreadDestroyed(lldb::tid_t tid);
+
+  /// Implementation of the jLLDBTraceStop packet
+  llvm::Error TraceStop(const TraceStopRequest &request);
+
+  /// Implementation of the jLLDBTraceStart packet
+  ///
+  /// \param[in] process_threads
+  ///     A list of all threads owned by the process.
+  llvm::Error TraceStart(const TraceIntelPTStartRequest &request,
+                         const std::vector<lldb::tid_t> &process_threads);
+
+  /// Implementation of the jLLDBTraceGetState packet
+  llvm::Expected<llvm::json::Value> GetState() const;
+
+  /// Implementation of the jLLDBTraceGetBinaryData packet
+  llvm::Expected<std::vector<uint8_t>>
+  GetBinaryData(const TraceGetBinaryDataRequest &request) const;
+
+  /// Dispose of all traces
+  void Clear();
+
+private:
+  llvm::Error TraceStop(lldb::tid_t tid);
+
+  /// Start tracing a specific thread.
+  llvm::Error TraceStart(lldb::tid_t tid,
+                         const TraceIntelPTStartRequest &request);
+
+  llvm::Expected<const IntelPTThreadTrace &>
+  GetTracedThread(lldb::tid_t tid) const;
+
+  bool IsProcessTracingEnabled() const;
+
+  void ClearProcessTracing();
+
+  lldb::pid_t m_pid;
+  /// Threads traced due to "thread tracing"
+  IntelPTThreadTraceCollection m_thread_traces;
+  /// Threads traced due to "process tracing". Only one active "process tracing"
+  /// instance is assumed for a single process.
+  llvm::Optional<IntelPTProcessTrace> m_process_trace;
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // liblldb_IntelPTManager_H_
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index e07d763..8c45796 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -8,9 +8,9 @@
 
 #include "NativeProcessLinux.h"
 
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
 #include <unistd.h>
 
 #include <fstream>
@@ -23,7 +23,6 @@
 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
 #include "Plugins/Process/Utility/LinuxProcMaps.h"
 #include "Procfs.h"
-#include "lldb/Core/EmulateInstruction.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostProcess.h"
@@ -31,6 +30,7 @@
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Host/linux/Host.h"
 #include "lldb/Host/linux/Ptrace.h"
 #include "lldb/Host/linux/Uio.h"
 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
@@ -38,7 +38,6 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/State.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StringExtractor.h"
@@ -54,11 +53,20 @@
 #include <sys/user.h>
 #include <sys/wait.h>
 
+#ifdef __aarch64__
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+#endif
+
 // Support hardware breakpoints in case it has not been defined
 #ifndef TRAP_HWBKPT
 #define TRAP_HWBKPT 4
 #endif
 
+#ifndef HWCAP2_MTE
+#define HWCAP2_MTE (1 << 18)
+#endif
+
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
@@ -282,13 +290,29 @@
       pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
+NativeProcessLinux::Extension
+NativeProcessLinux::Factory::GetSupportedExtensions() const {
+  NativeProcessLinux::Extension supported =
+      Extension::multiprocess | Extension::fork | Extension::vfork |
+      Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+
+#ifdef __aarch64__
+  // At this point we do not have a process so read auxv directly.
+  if ((getauxval(AT_HWCAP2) & HWCAP2_MTE))
+    supported |= Extension::memory_tagging;
+#endif
+
+  return supported;
+}
+
 // Public Instance Methods
 
 NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
                                        NativeDelegate &delegate,
                                        const ArchSpec &arch, MainLoop &mainloop,
                                        llvm::ArrayRef<::pid_t> tids)
-    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+      m_main_loop(mainloop), m_intel_pt_manager(pid) {
   if (m_terminal_fd != -1) {
     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
     assert(status.Success());
@@ -300,8 +324,7 @@
   assert(m_sigchld_handle && status.Success());
 
   for (const auto &tid : tids) {
-    NativeThreadLinux &thread = AddThread(tid);
-    thread.SetStoppedBySignal(SIGSTOP);
+    NativeThreadLinux &thread = AddThread(tid, /*resume*/ false);
     ThreadWasCreated(thread);
   }
 
@@ -385,14 +408,22 @@
   ptrace_opts |= PTRACE_O_TRACEEXIT;
 
   // Have the tracer trace threads which spawn in the inferior process.
-  // TODO: if we want to support tracing the inferiors' child, add the
-  // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
   ptrace_opts |= PTRACE_O_TRACECLONE;
 
   // Have the tracer notify us before execve returns (needed to disable legacy
   // SIGTRAP generation)
   ptrace_opts |= PTRACE_O_TRACEEXEC;
 
+  // Have the tracer trace forked children.
+  ptrace_opts |= PTRACE_O_TRACEFORK;
+
+  // Have the tracer trace vforks.
+  ptrace_opts |= PTRACE_O_TRACEVFORK;
+
+  // Have the tracer trace vfork-done in order to restore breakpoints after
+  // the child finishes sharing memory.
+  ptrace_opts |= PTRACE_O_TRACEVFORKDONE;
+
   return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
 }
 
@@ -446,11 +477,7 @@
     LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
              info.si_pid);
 
-    NativeThreadLinux &thread = AddThread(pid);
-
-    // Resume the newly created thread.
-    ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-    ThreadWasCreated(thread);
+    MonitorClone(pid, llvm::None);
     return;
   }
 
@@ -514,29 +541,24 @@
   }
 }
 
-void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
+void NativeProcessLinux::WaitForCloneNotification(::pid_t pid) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  if (GetThreadByID(tid)) {
-    // We are already tracking the thread - we got the event on the new thread
-    // (see MonitorSignal) before this one. We are done.
-    return;
-  }
-
-  // The thread is not tracked yet, let's wait for it to appear.
+  // The PID is not tracked yet, let's wait for it to appear.
   int status = -1;
   LLDB_LOG(log,
-           "received thread creation event for tid {0}. tid not tracked "
-           "yet, waiting for thread to appear...",
-           tid);
-  ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
-  // Since we are waiting on a specific tid, this must be the creation event.
+           "received clone event for pid {0}. pid not tracked yet, "
+           "waiting for it to appear...",
+           pid);
+  ::pid_t wait_pid =
+      llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, __WALL);
+  // Since we are waiting on a specific pid, this must be the creation event.
   // But let's do some checks just in case.
-  if (wait_pid != tid) {
+  if (wait_pid != pid) {
     LLDB_LOG(log,
-             "waiting for tid {0} failed. Assuming the thread has "
+             "waiting for pid {0} failed. Assuming the pid has "
              "disappeared in the meantime",
-             tid);
+             pid);
     // The only way I know of this could happen is if the whole process was
     // SIGKILLed in the mean time. In any case, we can't do anything about that
     // now.
@@ -544,18 +566,15 @@
   }
   if (WIFEXITED(status)) {
     LLDB_LOG(log,
-             "waiting for tid {0} returned an 'exited' event. Not "
-             "tracking the thread.",
-             tid);
+             "waiting for pid {0} returned an 'exited' event. Not "
+             "tracking it.",
+             pid);
     // Also a very improbable event.
+    m_pending_pid_map.erase(pid);
     return;
   }
 
-  LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
-  NativeThreadLinux &new_thread = AddThread(tid);
-
-  ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-  ThreadWasCreated(new_thread);
+  MonitorClone(pid, llvm::None);
 }
 
 void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
@@ -566,26 +585,26 @@
   assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
 
   switch (info.si_code) {
-  // TODO: these two cases are required if we want to support tracing of the
-  // inferiors' children.  We'd need this to debug a monitor. case (SIGTRAP |
-  // (PTRACE_EVENT_FORK << 8)): case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
-
+  case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+  case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
   case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
-    // This is the notification on the parent thread which informs us of new
-    // thread creation. We don't want to do anything with the parent thread so
-    // we just resume it. In case we want to implement "break on thread
-    // creation" functionality, we would need to stop here.
+    // This can either mean a new thread or a new process spawned via
+    // clone(2) without SIGCHLD or CLONE_VFORK flag.  Note that clone(2)
+    // can also cause PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK if one
+    // of these flags are passed.
 
     unsigned long event_message = 0;
     if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
       LLDB_LOG(log,
-               "pid {0} received thread creation event but "
-               "GetEventMessage failed so we don't know the new tid",
+               "pid {0} received clone() event but GetEventMessage failed "
+               "so we don't know the new pid/tid",
                thread.GetID());
-    } else
-      WaitForNewThread(event_message);
+      ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+    } else {
+      if (!MonitorClone(event_message, {{(info.si_code >> 8), thread.GetID()}}))
+        WaitForCloneNotification(event_message);
+    }
 
-    ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
     break;
   }
 
@@ -651,6 +670,16 @@
     break;
   }
 
+  case (SIGTRAP | (PTRACE_EVENT_VFORK_DONE << 8)): {
+    if (bool(m_enabled_extensions & Extension::vfork)) {
+      thread.SetStoppedByVForkDone();
+      StopRunningThreads(thread.GetID());
+    }
+    else
+      ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+    break;
+  }
+
   case 0:
   case TRAP_TRACE:  // We receive this on single stepping.
   case TRAP_HWBKPT: // We receive this on watchpoint hit
@@ -860,167 +889,83 @@
   StopRunningThreads(thread.GetID());
 }
 
-namespace {
+bool NativeProcessLinux::MonitorClone(
+    lldb::pid_t child_pid,
+    llvm::Optional<NativeProcessLinux::CloneInfo> clone_info) {
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+  LLDB_LOG(log, "clone, child_pid={0}, clone info?={1}", child_pid,
+           clone_info.hasValue());
 
-struct EmulatorBaton {
-  NativeProcessLinux &m_process;
-  NativeRegisterContext &m_reg_context;
+  auto find_it = m_pending_pid_map.find(child_pid);
+  if (find_it == m_pending_pid_map.end()) {
+    // not in the map, so this is the first signal for the PID
+    m_pending_pid_map.insert({child_pid, clone_info});
+    return false;
+  }
+  m_pending_pid_map.erase(find_it);
 
-  // eRegisterKindDWARF -> RegsiterValue
-  std::unordered_map<uint32_t, RegisterValue> m_register_values;
-
-  EmulatorBaton(NativeProcessLinux &process, NativeRegisterContext &reg_context)
-      : m_process(process), m_reg_context(reg_context) {}
-};
-
-} // anonymous namespace
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                 const EmulateInstruction::Context &context,
-                                 lldb::addr_t addr, void *dst, size_t length) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
-  size_t bytes_read;
-  emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
-  return bytes_read;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                 const RegisterInfo *reg_info,
-                                 RegisterValue &reg_value) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
-  auto it = emulator_baton->m_register_values.find(
-      reg_info->kinds[eRegisterKindDWARF]);
-  if (it != emulator_baton->m_register_values.end()) {
-    reg_value = it->second;
-    return true;
+  // second signal for the pid
+  assert(clone_info.hasValue() != find_it->second.hasValue());
+  if (!clone_info) {
+    // child signal does not indicate the event, so grab the one stored
+    // earlier
+    clone_info = find_it->second;
   }
 
-  // The emulator only fill in the dwarf regsiter numbers (and in some case the
-  // generic register numbers). Get the full register info from the register
-  // context based on the dwarf register numbers.
-  const RegisterInfo *full_reg_info =
-      emulator_baton->m_reg_context.GetRegisterInfo(
-          eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+  LLDB_LOG(log, "second signal for child_pid={0}, parent_tid={1}, event={2}",
+           child_pid, clone_info->parent_tid, clone_info->event);
 
-  Status error =
-      emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
-  if (error.Success())
-    return true;
+  auto *parent_thread = GetThreadByID(clone_info->parent_tid);
+  assert(parent_thread);
 
-  return false;
-}
+  switch (clone_info->event) {
+  case PTRACE_EVENT_CLONE: {
+    // PTRACE_EVENT_CLONE can either mean a new thread or a new process.
+    // Try to grab the new process' PGID to figure out which one it is.
+    // If PGID is the same as the PID, then it's a new process.  Otherwise,
+    // it's a thread.
+    auto tgid_ret = getPIDForTID(child_pid);
+    if (tgid_ret != child_pid) {
+      // A new thread should have PGID matching our process' PID.
+      assert(!tgid_ret || tgid_ret.getValue() == GetID());
 
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  const RegisterInfo *reg_info,
-                                  const RegisterValue &reg_value) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-  emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
-      reg_value;
-  return true;
-}
+      NativeThreadLinux &child_thread = AddThread(child_pid, /*resume*/ true);
+      ThreadWasCreated(child_thread);
 
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  lldb::addr_t addr, const void *dst,
-                                  size_t length) {
-  return length;
-}
-
-static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
-  const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
-      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
-  return regsiter_context.ReadRegisterAsUnsigned(flags_info,
-                                                 LLDB_INVALID_ADDRESS);
-}
-
-Status
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
-  Status error;
-  NativeRegisterContext& register_context = thread.GetRegisterContext();
-
-  std::unique_ptr<EmulateInstruction> emulator_up(
-      EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
-                                     nullptr));
-
-  if (emulator_up == nullptr)
-    return Status("Instruction emulator not found!");
-
-  EmulatorBaton baton(*this, register_context);
-  emulator_up->SetBaton(&baton);
-  emulator_up->SetReadMemCallback(&ReadMemoryCallback);
-  emulator_up->SetReadRegCallback(&ReadRegisterCallback);
-  emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
-  emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
-
-  if (!emulator_up->ReadInstruction())
-    return Status("Read instruction failed!");
-
-  bool emulation_result =
-      emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
-
-  const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
-      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-  const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
-      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
-
-  auto pc_it =
-      baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
-  auto flags_it =
-      baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
-
-  lldb::addr_t next_pc;
-  lldb::addr_t next_flags;
-  if (emulation_result) {
-    assert(pc_it != baton.m_register_values.end() &&
-           "Emulation was successfull but PC wasn't updated");
-    next_pc = pc_it->second.GetAsUInt64();
-
-    if (flags_it != baton.m_register_values.end())
-      next_flags = flags_it->second.GetAsUInt64();
-    else
-      next_flags = ReadFlags(register_context);
-  } else if (pc_it == baton.m_register_values.end()) {
-    // Emulate instruction failed and it haven't changed PC. Advance PC with
-    // the size of the current opcode because the emulation of all
-    // PC modifying instruction should be successful. The failure most
-    // likely caused by a not supported instruction which don't modify PC.
-    next_pc = register_context.GetPC() + emulator_up->GetOpcode().GetByteSize();
-    next_flags = ReadFlags(register_context);
-  } else {
-    // The instruction emulation failed after it modified the PC. It is an
-    // unknown error where we can't continue because the next instruction is
-    // modifying the PC but we don't  know how.
-    return Status("Instruction emulation failed unexpectedly.");
-  }
-
-  if (m_arch.GetMachine() == llvm::Triple::arm) {
-    if (next_flags & 0x20) {
-      // Thumb mode
-      error = SetSoftwareBreakpoint(next_pc, 2);
-    } else {
-      // Arm mode
-      error = SetSoftwareBreakpoint(next_pc, 4);
+      // Resume the parent.
+      ResumeThread(*parent_thread, parent_thread->GetState(),
+                   LLDB_INVALID_SIGNAL_NUMBER);
+      break;
     }
-  } else if (m_arch.IsMIPS() || m_arch.GetTriple().isPPC64())
-    error = SetSoftwareBreakpoint(next_pc, 4);
-  else {
-    // No size hint is given for the next breakpoint
-    error = SetSoftwareBreakpoint(next_pc, 0);
+  }
+    LLVM_FALLTHROUGH;
+  case PTRACE_EVENT_FORK:
+  case PTRACE_EVENT_VFORK: {
+    bool is_vfork = clone_info->event == PTRACE_EVENT_VFORK;
+    std::unique_ptr<NativeProcessLinux> child_process{new NativeProcessLinux(
+        static_cast<::pid_t>(child_pid), m_terminal_fd, m_delegate, m_arch,
+        m_main_loop, {static_cast<::pid_t>(child_pid)})};
+    if (!is_vfork)
+      child_process->m_software_breakpoints = m_software_breakpoints;
+
+    Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+    if (bool(m_enabled_extensions & expected_ext)) {
+      m_delegate.NewSubprocess(this, std::move(child_process));
+      // NB: non-vfork clone() is reported as fork
+      parent_thread->SetStoppedByFork(is_vfork, child_pid);
+      StopRunningThreads(parent_thread->GetID());
+    } else {
+      child_process->Detach();
+      ResumeThread(*parent_thread, parent_thread->GetState(),
+                   LLDB_INVALID_SIGNAL_NUMBER);
+    }
+    break;
+  }
+  default:
+    llvm_unreachable("unknown clone_info.event");
   }
 
-  // If setting the breakpoint fails because next_pc is out of the address
-  // space, ignore it and let the debugee segfault.
-  if (error.GetError() == EIO || error.GetError() == EFAULT) {
-    return Status();
-  } else if (error.Fail())
-    return error;
-
-  m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
-
-  return Status();
+  return true;
 }
 
 bool NativeProcessLinux::SupportHardwareSingleStepping() const {
@@ -1119,8 +1064,7 @@
           e; // Save the error, but still attempt to detach from other threads.
   }
 
-  m_processor_trace_monitor.clear();
-  m_pt_proces_trace_id = LLDB_INVALID_UID;
+  m_intel_pt_manager.Clear();
 
   return error;
 }
@@ -1487,6 +1431,132 @@
   return llvm::Error::success();
 }
 
+Status NativeProcessLinux::ReadMemoryTags(int32_t type, lldb::addr_t addr,
+                                          size_t len,
+                                          std::vector<uint8_t> &tags) {
+  llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
+      GetCurrentThread()->GetRegisterContext().GetMemoryTaggingDetails(type);
+  if (!details)
+    return Status(details.takeError());
+
+  // Ignore 0 length read
+  if (!len)
+    return Status();
+
+  // lldb will align the range it requests but it is not required to by
+  // the protocol so we'll do it again just in case.
+  // Remove non address bits too. Ptrace calls may work regardless but that
+  // is not a guarantee.
+  MemoryTagManager::TagRange range(details->manager->RemoveNonAddressBits(addr),
+                                   len);
+  range = details->manager->ExpandToGranule(range);
+
+  // Allocate enough space for all tags to be read
+  size_t num_tags = range.GetByteSize() / details->manager->GetGranuleSize();
+  tags.resize(num_tags * details->manager->GetTagSizeInBytes());
+
+  struct iovec tags_iovec;
+  uint8_t *dest = tags.data();
+  lldb::addr_t read_addr = range.GetRangeBase();
+
+  // This call can return partial data so loop until we error or
+  // get all tags back.
+  while (num_tags) {
+    tags_iovec.iov_base = dest;
+    tags_iovec.iov_len = num_tags;
+
+    Status error = NativeProcessLinux::PtraceWrapper(
+        details->ptrace_read_req, GetID(), reinterpret_cast<void *>(read_addr),
+        static_cast<void *>(&tags_iovec), 0, nullptr);
+
+    if (error.Fail()) {
+      // Discard partial reads
+      tags.resize(0);
+      return error;
+    }
+
+    size_t tags_read = tags_iovec.iov_len;
+    assert(tags_read && (tags_read <= num_tags));
+
+    dest += tags_read * details->manager->GetTagSizeInBytes();
+    read_addr += details->manager->GetGranuleSize() * tags_read;
+    num_tags -= tags_read;
+  }
+
+  return Status();
+}
+
+Status NativeProcessLinux::WriteMemoryTags(int32_t type, lldb::addr_t addr,
+                                           size_t len,
+                                           const std::vector<uint8_t> &tags) {
+  llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails> details =
+      GetCurrentThread()->GetRegisterContext().GetMemoryTaggingDetails(type);
+  if (!details)
+    return Status(details.takeError());
+
+  // Ignore 0 length write
+  if (!len)
+    return Status();
+
+  // lldb will align the range it requests but it is not required to by
+  // the protocol so we'll do it again just in case.
+  // Remove non address bits too. Ptrace calls may work regardless but that
+  // is not a guarantee.
+  MemoryTagManager::TagRange range(details->manager->RemoveNonAddressBits(addr),
+                                   len);
+  range = details->manager->ExpandToGranule(range);
+
+  // Not checking number of tags here, we may repeat them below
+  llvm::Expected<std::vector<lldb::addr_t>> unpacked_tags_or_err =
+      details->manager->UnpackTagsData(tags);
+  if (!unpacked_tags_or_err)
+    return Status(unpacked_tags_or_err.takeError());
+
+  llvm::Expected<std::vector<lldb::addr_t>> repeated_tags_or_err =
+      details->manager->RepeatTagsForRange(*unpacked_tags_or_err, range);
+  if (!repeated_tags_or_err)
+    return Status(repeated_tags_or_err.takeError());
+
+  // Repack them for ptrace to use
+  llvm::Expected<std::vector<uint8_t>> final_tag_data =
+      details->manager->PackTags(*repeated_tags_or_err);
+  if (!final_tag_data)
+    return Status(final_tag_data.takeError());
+
+  struct iovec tags_vec;
+  uint8_t *src = final_tag_data->data();
+  lldb::addr_t write_addr = range.GetRangeBase();
+  // unpacked tags size because the number of bytes per tag might not be 1
+  size_t num_tags = repeated_tags_or_err->size();
+
+  // This call can partially write tags, so we loop until we
+  // error or all tags have been written.
+  while (num_tags > 0) {
+    tags_vec.iov_base = src;
+    tags_vec.iov_len = num_tags;
+
+    Status error = NativeProcessLinux::PtraceWrapper(
+        details->ptrace_write_req, GetID(),
+        reinterpret_cast<void *>(write_addr), static_cast<void *>(&tags_vec), 0,
+        nullptr);
+
+    if (error.Fail()) {
+      // Don't attempt to restore the original values in the case of a partial
+      // write
+      return error;
+    }
+
+    size_t tags_written = tags_vec.iov_len;
+    assert(tags_written && (tags_written <= num_tags));
+
+    src += tags_written * details->manager->GetTagSizeInBytes();
+    write_addr += details->manager->GetGranuleSize() * tags_written;
+    num_tags -= tags_written;
+  }
+
+  return Status();
+}
+
 size_t NativeProcessLinux::UpdateThreads() {
   // The NativeProcessLinux monitoring threads are always up to date with
   // respect to thread state and they keep the thread list populated properly.
@@ -1676,12 +1746,33 @@
   }
 
   if (found)
-    StopTracingForThread(thread_id);
+    NotifyTracersOfThreadDestroyed(thread_id);
+
   SignalIfAllThreadsStopped();
   return found;
 }
 
-NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+Status NativeProcessLinux::NotifyTracersOfNewThread(lldb::tid_t tid) {
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+  Status error(m_intel_pt_manager.OnThreadCreated(tid));
+  if (error.Fail())
+    LLDB_LOG(log, "Failed to trace a new thread with intel-pt, tid = {0}. {1}",
+             tid, error.AsCString());
+  return error;
+}
+
+Status NativeProcessLinux::NotifyTracersOfThreadDestroyed(lldb::tid_t tid) {
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
+  Status error(m_intel_pt_manager.OnThreadDestroyed(tid));
+  if (error.Fail())
+    LLDB_LOG(log,
+             "Failed to stop a destroyed thread with intel-pt, tid = {0}. {1}",
+             tid, error.AsCString());
+  return error;
+}
+
+NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id,
+                                                 bool resume) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
   LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
 
@@ -1693,22 +1784,19 @@
     SetCurrentThreadID(thread_id);
 
   m_threads.push_back(std::make_unique<NativeThreadLinux>(*this, thread_id));
+  NativeThreadLinux &thread =
+      static_cast<NativeThreadLinux &>(*m_threads.back());
 
-  if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
-    auto traceMonitor = ProcessorTraceMonitor::Create(
-        GetID(), thread_id, m_pt_process_trace_config, true);
-    if (traceMonitor) {
-      m_pt_traced_thread_group.insert(thread_id);
-      m_processor_trace_monitor.insert(
-          std::make_pair(thread_id, std::move(*traceMonitor)));
-    } else {
-      LLDB_LOG(log, "failed to start trace on thread {0}", thread_id);
-      Status error(traceMonitor.takeError());
-      LLDB_LOG(log, "error {0}", error);
-    }
-  }
+  Status tracing_error = NotifyTracersOfNewThread(thread.GetID());
+  if (tracing_error.Fail()) {
+    thread.SetStoppedByProcessorTrace(tracing_error.AsCString());
+    StopRunningThreads(thread.GetID());
+  } else if (resume)
+    ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+  else
+    thread.SetStoppedBySignal(SIGSTOP);
 
-  return static_cast<NativeThreadLinux &>(*m_threads.back());
+  return thread;
 }
 
 Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
@@ -1926,263 +2014,43 @@
   return error;
 }
 
-llvm::Expected<ProcessorTraceMonitor &>
-NativeProcessLinux::LookupProcessorTraceInstance(lldb::user_id_t traceid,
-                                                 lldb::tid_t thread) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  if (thread == LLDB_INVALID_THREAD_ID && traceid == m_pt_proces_trace_id) {
-    LLDB_LOG(log, "thread not specified: {0}", traceid);
-    return Status("tracing not active thread not specified").ToError();
-  }
-
-  for (auto& iter : m_processor_trace_monitor) {
-    if (traceid == iter.second->GetTraceID() &&
-        (thread == iter.first || thread == LLDB_INVALID_THREAD_ID))
-      return *(iter.second);
-  }
-
-  LLDB_LOG(log, "traceid not being traced: {0}", traceid);
-  return Status("tracing not active for this thread").ToError();
+llvm::Expected<TraceSupportedResponse> NativeProcessLinux::TraceSupported() {
+  if (IntelPTManager::IsSupported())
+    return TraceSupportedResponse{"intel-pt", "Intel Processor Trace"};
+  return NativeProcessProtocol::TraceSupported();
 }
 
-Status NativeProcessLinux::GetMetaData(lldb::user_id_t traceid,
-                                       lldb::tid_t thread,
-                                       llvm::MutableArrayRef<uint8_t> &buffer,
-                                       size_t offset) {
-  TraceOptions trace_options;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  Status error;
-
-  LLDB_LOG(log, "traceid {0}", traceid);
-
-  auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
-  if (!perf_monitor) {
-    LLDB_LOG(log, "traceid not being traced: {0}", traceid);
-    buffer = buffer.slice(buffer.size());
-    error = perf_monitor.takeError();
-    return error;
+Error NativeProcessLinux::TraceStart(StringRef json_request, StringRef type) {
+  if (type == "intel-pt") {
+    if (Expected<TraceIntelPTStartRequest> request =
+            json::parse<TraceIntelPTStartRequest>(json_request,
+                                                  "TraceIntelPTStartRequest")) {
+      std::vector<lldb::tid_t> process_threads;
+      for (auto &thread : m_threads)
+        process_threads.push_back(thread->GetID());
+      return m_intel_pt_manager.TraceStart(*request, process_threads);
+    } else
+      return request.takeError();
   }
-  return (*perf_monitor).ReadPerfTraceData(buffer, offset);
+
+  return NativeProcessProtocol::TraceStart(json_request, type);
 }
 
-Status NativeProcessLinux::GetData(lldb::user_id_t traceid, lldb::tid_t thread,
-                                   llvm::MutableArrayRef<uint8_t> &buffer,
-                                   size_t offset) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  Status error;
-
-  LLDB_LOG(log, "traceid {0}", traceid);
-
-  auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
-  if (!perf_monitor) {
-    LLDB_LOG(log, "traceid not being traced: {0}", traceid);
-    buffer = buffer.slice(buffer.size());
-    error = perf_monitor.takeError();
-    return error;
-  }
-  return (*perf_monitor).ReadPerfTraceAux(buffer, offset);
+Error NativeProcessLinux::TraceStop(const TraceStopRequest &request) {
+  if (request.type == "intel-pt")
+    return m_intel_pt_manager.TraceStop(request);
+  return NativeProcessProtocol::TraceStop(request);
 }
 
-Status NativeProcessLinux::GetTraceConfig(lldb::user_id_t traceid,
-                                          TraceOptions &config) {
-  Status error;
-  if (config.getThreadID() == LLDB_INVALID_THREAD_ID &&
-      m_pt_proces_trace_id == traceid) {
-    if (m_pt_proces_trace_id == LLDB_INVALID_UID) {
-      error.SetErrorString("tracing not active for this process");
-      return error;
-    }
-    config = m_pt_process_trace_config;
-  } else {
-    auto perf_monitor =
-        LookupProcessorTraceInstance(traceid, config.getThreadID());
-    if (!perf_monitor) {
-      error = perf_monitor.takeError();
-      return error;
-    }
-    error = (*perf_monitor).GetTraceConfig(config);
-  }
-  return error;
+Expected<json::Value> NativeProcessLinux::TraceGetState(StringRef type) {
+  if (type == "intel-pt")
+    return m_intel_pt_manager.GetState();
+  return NativeProcessProtocol::TraceGetState(type);
 }
 
-llvm::Expected<TraceTypeInfo> NativeProcessLinux::GetSupportedTraceType() {
-  if (ProcessorTraceMonitor::IsSupported())
-    return TraceTypeInfo{"intel-pt", "Intel Processor Trace"};
-  return NativeProcessProtocol::GetSupportedTraceType();
-}
-
-lldb::user_id_t
-NativeProcessLinux::StartTraceGroup(const TraceOptions &config,
-                                           Status &error) {
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  if (config.getType() != TraceType::eTraceTypeProcessorTrace)
-    return LLDB_INVALID_UID;
-
-  if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
-    error.SetErrorString("tracing already active on this process");
-    return m_pt_proces_trace_id;
-  }
-
-  for (const auto &thread_sp : m_threads) {
-    if (auto traceInstance = ProcessorTraceMonitor::Create(
-            GetID(), thread_sp->GetID(), config, true)) {
-      m_pt_traced_thread_group.insert(thread_sp->GetID());
-      m_processor_trace_monitor.insert(
-          std::make_pair(thread_sp->GetID(), std::move(*traceInstance)));
-    }
-  }
-
-  m_pt_process_trace_config = config;
-  error = ProcessorTraceMonitor::GetCPUType(m_pt_process_trace_config);
-
-  // Trace on Complete process will have traceid of 0
-  m_pt_proces_trace_id = 0;
-
-  LLDB_LOG(log, "Process Trace ID {0}", m_pt_proces_trace_id);
-  return m_pt_proces_trace_id;
-}
-
-lldb::user_id_t NativeProcessLinux::StartTrace(const TraceOptions &config,
-                                               Status &error) {
-  if (config.getType() != TraceType::eTraceTypeProcessorTrace)
-    return NativeProcessProtocol::StartTrace(config, error);
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  lldb::tid_t threadid = config.getThreadID();
-
-  if (threadid == LLDB_INVALID_THREAD_ID)
-    return StartTraceGroup(config, error);
-
-  auto thread_sp = GetThreadByID(threadid);
-  if (!thread_sp) {
-    // Thread not tracked by lldb so don't trace.
-    error.SetErrorString("invalid thread id");
-    return LLDB_INVALID_UID;
-  }
-
-  const auto &iter = m_processor_trace_monitor.find(threadid);
-  if (iter != m_processor_trace_monitor.end()) {
-    LLDB_LOG(log, "Thread already being traced");
-    error.SetErrorString("tracing already active on this thread");
-    return LLDB_INVALID_UID;
-  }
-
-  auto traceMonitor =
-      ProcessorTraceMonitor::Create(GetID(), threadid, config, false);
-  if (!traceMonitor) {
-    error = traceMonitor.takeError();
-    LLDB_LOG(log, "error {0}", error);
-    return LLDB_INVALID_UID;
-  }
-  lldb::user_id_t ret_trace_id = (*traceMonitor)->GetTraceID();
-  m_processor_trace_monitor.insert(
-      std::make_pair(threadid, std::move(*traceMonitor)));
-  return ret_trace_id;
-}
-
-Status NativeProcessLinux::StopTracingForThread(lldb::tid_t thread) {
-  Status error;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  LLDB_LOG(log, "Thread {0}", thread);
-
-  const auto& iter = m_processor_trace_monitor.find(thread);
-  if (iter == m_processor_trace_monitor.end()) {
-    error.SetErrorString("tracing not active for this thread");
-    return error;
-  }
-
-  if (iter->second->GetTraceID() == m_pt_proces_trace_id) {
-    // traceid maps to the whole process so we have to erase it from the thread
-    // group.
-    LLDB_LOG(log, "traceid maps to process");
-    m_pt_traced_thread_group.erase(thread);
-  }
-  m_processor_trace_monitor.erase(iter);
-
-  return error;
-}
-
-Status NativeProcessLinux::StopTrace(lldb::user_id_t traceid,
-                                     lldb::tid_t thread) {
-  Status error;
-
-  TraceOptions trace_options;
-  trace_options.setThreadID(thread);
-  error = NativeProcessLinux::GetTraceConfig(traceid, trace_options);
-
-  if (error.Fail())
-    return error;
-
-  switch (trace_options.getType()) {
-  case lldb::TraceType::eTraceTypeProcessorTrace:
-    if (traceid == m_pt_proces_trace_id &&
-        thread == LLDB_INVALID_THREAD_ID)
-      StopProcessorTracingOnProcess();
-    else
-      error = StopProcessorTracingOnThread(traceid, thread);
-    break;
-  default:
-    error.SetErrorString("trace not supported");
-    break;
-  }
-
-  return error;
-}
-
-void NativeProcessLinux::StopProcessorTracingOnProcess() {
-  for (auto thread_id_iter : m_pt_traced_thread_group)
-    m_processor_trace_monitor.erase(thread_id_iter);
-  m_pt_traced_thread_group.clear();
-  m_pt_proces_trace_id = LLDB_INVALID_UID;
-}
-
-Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid,
-                                                        lldb::tid_t thread) {
-  Status error;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  if (thread == LLDB_INVALID_THREAD_ID) {
-    for (auto& iter : m_processor_trace_monitor) {
-      if (iter.second->GetTraceID() == traceid) {
-        // Stopping a trace instance for an individual thread hence there will
-        // only be one traceid that can match.
-        m_processor_trace_monitor.erase(iter.first);
-        return error;
-      }
-      LLDB_LOG(log, "Trace ID {0}", iter.second->GetTraceID());
-    }
-
-    LLDB_LOG(log, "Invalid TraceID");
-    error.SetErrorString("invalid trace id");
-    return error;
-  }
-
-  // thread is specified so we can use find function on the map.
-  const auto& iter = m_processor_trace_monitor.find(thread);
-  if (iter == m_processor_trace_monitor.end()) {
-    // thread not found in our map.
-    LLDB_LOG(log, "thread not being traced");
-    error.SetErrorString("tracing not active for this thread");
-    return error;
-  }
-  if (iter->second->GetTraceID() != traceid) {
-    // traceid did not match so it has to be invalid.
-    LLDB_LOG(log, "Invalid TraceID");
-    error.SetErrorString("invalid trace id");
-    return error;
-  }
-
-  LLDB_LOG(log, "UID - {0} , Thread -{1}", traceid, thread);
-
-  if (traceid == m_pt_proces_trace_id) {
-    // traceid maps to the whole process so we have to erase it from the thread
-    // group.
-    LLDB_LOG(log, "traceid maps to process");
-    m_pt_traced_thread_group.erase(thread);
-  }
-  m_processor_trace_monitor.erase(iter);
-
-  return error;
+Expected<std::vector<uint8_t>> NativeProcessLinux::TraceGetBinaryData(
+    const TraceGetBinaryDataRequest &request) {
+  if (request.type == "intel-pt")
+    return m_intel_pt_manager.GetBinaryData(request);
+  return NativeProcessProtocol::TraceGetBinaryData(request);
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index b7d70a6..902afb6 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -20,9 +20,10 @@
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/lldb-types.h"
 
+#include "IntelPTManager.h"
 #include "NativeThreadLinux.h"
 #include "Plugins/Process/POSIX/NativeProcessELF.h"
-#include "ProcessorTrace.h"
+#include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
 
 namespace lldb_private {
 class Status;
@@ -36,7 +37,8 @@
 /// for debugging.
 ///
 /// Changes in the inferior process state are broadcasted.
-class NativeProcessLinux : public NativeProcessELF {
+class NativeProcessLinux : public NativeProcessELF,
+                           private NativeProcessSoftwareSingleStep {
 public:
   class Factory : public NativeProcessProtocol::Factory {
   public:
@@ -47,6 +49,8 @@
     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
            MainLoop &mainloop) const override;
+
+    Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -76,6 +80,12 @@
 
   llvm::Error DeallocateMemory(lldb::addr_t addr) override;
 
+  Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
+                        std::vector<uint8_t> &tags) override;
+
+  Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
+                         const std::vector<uint8_t> &tags) override;
+
   size_t UpdateThreads() override;
 
   const ArchSpec &GetArchitecture() const override { return m_arch; }
@@ -101,23 +111,22 @@
     return getProcFile(GetID(), "auxv");
   }
 
-  lldb::user_id_t StartTrace(const TraceOptions &config,
-                             Status &error) override;
+  /// Tracing
+  /// These methods implement the jLLDBTrace packets
+  /// \{
+  llvm::Error TraceStart(llvm::StringRef json_request,
+                         llvm::StringRef type) override;
 
-  Status StopTrace(lldb::user_id_t traceid,
-                   lldb::tid_t thread) override;
+  llvm::Error TraceStop(const TraceStopRequest &request) override;
 
-  Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
-                 llvm::MutableArrayRef<uint8_t> &buffer,
-                 size_t offset = 0) override;
+  llvm::Expected<llvm::json::Value>
+  TraceGetState(llvm::StringRef type) override;
 
-  Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
-                     llvm::MutableArrayRef<uint8_t> &buffer,
-                     size_t offset = 0) override;
+  llvm::Expected<std::vector<uint8_t>>
+  TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
 
-  Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override;
-
-  virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
+  llvm::Expected<TraceSupportedResponse> TraceSupported() override;
+  /// }
 
   // Interface used by NativeRegisterContext-derived classes.
   static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
@@ -135,16 +144,13 @@
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
+  MainLoop& m_main_loop;
 
   LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
 
-  // List of thread ids stepping with a breakpoint with the address of
-  // the relevan breakpoint
-  std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
-
   /// Inferior memory (allocated by us) and its size.
   llvm::DenseMap<lldb::addr_t, lldb::addr_t> m_allocated_memory;
 
@@ -160,7 +166,7 @@
 
   void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
 
-  void WaitForNewThread(::pid_t tid);
+  void WaitForCloneNotification(::pid_t pid);
 
   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
 
@@ -173,13 +179,32 @@
   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
                      bool exited);
 
-  Status SetupSoftwareSingleStepping(NativeThreadLinux &thread);
-
   bool HasThreadNoLock(lldb::tid_t thread_id);
 
   bool StopTrackingThread(lldb::tid_t thread_id);
 
-  NativeThreadLinux &AddThread(lldb::tid_t thread_id);
+  /// Create a new thread.
+  ///
+  /// If process tracing is enabled and the thread can't be traced, then the
+  /// thread is left stopped with a \a eStopReasonProcessorTrace status, and
+  /// then the process is stopped.
+  ///
+  /// \param[in] resume
+  ///     If a tracing error didn't happen, then resume the thread after
+  ///     creation if \b true, or leave it stopped with SIGSTOP if \b false.
+  NativeThreadLinux &AddThread(lldb::tid_t thread_id, bool resume);
+
+  /// Start tracing a new thread if process tracing is enabled.
+  ///
+  /// Trace mechanisms should modify this method to provide automatic tracing
+  /// for new threads.
+  Status NotifyTracersOfNewThread(lldb::tid_t tid);
+
+  /// Stop tracing threads upon a destroy event.
+  ///
+  /// Trace mechanisms should modify this method to provide automatic trace
+  /// stopping for threads being destroyed.
+  Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid);
 
   /// Writes a siginfo_t structure corresponding to the given thread ID to the
   /// memory region pointed to by \p siginfo.
@@ -216,42 +241,23 @@
 
   Status PopulateMemoryRegionCache();
 
-  lldb::user_id_t StartTraceGroup(const TraceOptions &config,
-                                         Status &error);
+  /// Manages Intel PT process and thread traces.
+  IntelPTManager m_intel_pt_manager;
 
-  // This function is intended to be used to stop tracing
-  // on a thread that exited.
-  Status StopTracingForThread(lldb::tid_t thread);
+  struct CloneInfo {
+    int event;
+    lldb::tid_t parent_tid;
+  };
 
-  // The below function as the name suggests, looks up a ProcessorTrace
-  // instance from the m_processor_trace_monitor map. In the case of
-  // process tracing where the traceid passed would map to the complete
-  // process, it is mandatory to provide a threadid to obtain a trace
-  // instance (since ProcessorTrace is tied to a thread). In the other
-  // scenario that an individual thread is being traced, just the traceid
-  // is sufficient to obtain the actual ProcessorTrace instance.
-  llvm::Expected<ProcessorTraceMonitor &>
-  LookupProcessorTraceInstance(lldb::user_id_t traceid, lldb::tid_t thread);
+  // Map of child processes that have been signaled once, and we are
+  // waiting for the second signal.
+  llvm::DenseMap<lldb::pid_t, llvm::Optional<CloneInfo>> m_pending_pid_map;
 
-  // Stops tracing on individual threads being traced. Not intended
-  // to be used to stop tracing on complete process.
-  Status StopProcessorTracingOnThread(lldb::user_id_t traceid,
-                                      lldb::tid_t thread);
-
-  // Intended to stop tracing on complete process.
-  // Should not be used for stopping trace on
-  // individual threads.
-  void StopProcessorTracingOnProcess();
-
-  llvm::DenseMap<lldb::tid_t, ProcessorTraceMonitorUP>
-      m_processor_trace_monitor;
-
-  // Set for tracking threads being traced under
-  // same process user id.
-  llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
-
-  lldb::user_id_t m_pt_proces_trace_id = LLDB_INVALID_UID;
-  TraceOptions m_pt_process_trace_config;
+  // Handle a clone()-like event.  If received by parent, clone_info contains
+  // additional info.  Returns true if the event is handled, or false if it
+  // is pending second notification.
+  bool MonitorClone(lldb::pid_t child_pid,
+                    llvm::Optional<CloneInfo> clone_info);
 };
 
 } // namespace process_linux
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index fa067b7..b66f690 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -11,10 +11,14 @@
 
 #include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
 #include "lldb/Host/common/NativeThreadProtocol.h"
+#include "lldb/Target/MemoryTagManager.h"
+#include "llvm/Support/Error.h"
 
 namespace lldb_private {
 namespace process_linux {
 
+class NativeThreadLinux;
+
 class NativeRegisterContextLinux
     : public virtual NativeRegisterContextRegisterInfo {
 public:
@@ -24,7 +28,7 @@
   // variant should be compiled into the final executable.
   static std::unique_ptr<NativeRegisterContextLinux>
   CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
-                                       NativeThreadProtocol &native_thread);
+                                       NativeThreadLinux &native_thread);
 
   // Invalidates cached values in register context data structures
   virtual void InvalidateAllRegisters(){}
@@ -55,7 +59,29 @@
   /// they are supported.
   virtual llvm::Optional<MmapData> GetMmapData() { return llvm::None; }
 
+  struct MemoryTaggingDetails {
+    /// Object with tag handling utilities. If the function below returns
+    /// a valid structure, you can assume that this pointer is valid.
+    std::unique_ptr<MemoryTagManager> manager;
+    int ptrace_read_req;  /// ptrace operation number for memory tag read
+    int ptrace_write_req; /// ptrace operation number for memory tag write
+  };
+  /// Return architecture specific data needed to use memory tags,
+  /// if they are supported.
+  virtual llvm::Expected<MemoryTaggingDetails>
+  GetMemoryTaggingDetails(int32_t type) {
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "Architecture does not support memory tagging");
+  }
+
 protected:
+  // NB: This constructor is here only because gcc<=6.5 requires a virtual base
+  // class initializer on abstract class (even though it is never used). It can
+  // be deleted once we move to gcc>=7.0.
+  NativeRegisterContextLinux(NativeThreadProtocol &thread)
+      : NativeRegisterContextRegisterInfo(thread, nullptr) {}
+
   lldb::ByteOrder GetByteOrder() const;
 
   virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index e15e0f8..91f8828 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -47,7 +47,7 @@
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
   return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
                                                            native_thread);
 }
@@ -56,8 +56,9 @@
 
 NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-    : NativeRegisterContextRegisterInfo(
-          native_thread, new RegisterInfoPOSIX_arm(target_arch)) {
+    : NativeRegisterContextRegisterInfo(native_thread,
+                                        new RegisterInfoPOSIX_arm(target_arch)),
+      NativeRegisterContextLinux(native_thread) {
   assert(target_arch.GetMachine() == llvm::Triple::arm);
 
   ::memset(&m_fpr, 0, sizeof(m_fpr));
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index c34afe6..34a520e 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -13,6 +13,7 @@
 
 
 #include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/linux/Ptrace.h"
 #include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/RegisterValue.h"
@@ -21,6 +22,7 @@
 #include "Plugins/Process/Linux/NativeProcessLinux.h"
 #include "Plugins/Process/Linux/Procfs.h"
 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
 
 // System includes - They have to be included after framework includes because
@@ -33,6 +35,17 @@
 #define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension */
 #endif
 
+#ifndef NT_ARM_PAC_MASK
+#define NT_ARM_PAC_MASK 0x406 /* Pointer authentication code masks */
+#endif
+
+#ifndef NT_ARM_TAGGED_ADDR_CTRL
+#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* Tagged address control register */
+#endif
+
+#define HWCAP_PACA (1 << 30)
+#define HWCAP2_MTE (1 << 18)
+
 #define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
 
 using namespace lldb;
@@ -41,28 +54,63 @@
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
   switch (target_arch.GetMachine()) {
   case llvm::Triple::arm:
     return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
-                                                             native_thread);
-  case llvm::Triple::aarch64:
-    return std::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
-                                                               native_thread);
+                                                            native_thread);
+  case llvm::Triple::aarch64: {
+    // Configure register sets supported by this AArch64 target.
+    // Read SVE header to check for SVE support.
+    struct user_sve_header sve_header;
+    struct iovec ioVec;
+    ioVec.iov_base = &sve_header;
+    ioVec.iov_len = sizeof(sve_header);
+    unsigned int regset = NT_ARM_SVE;
+
+    Flags opt_regsets;
+    if (NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,
+                                          native_thread.GetID(), &regset,
+                                          &ioVec, sizeof(sve_header))
+            .Success())
+      opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+    NativeProcessLinux &process = native_thread.GetProcess();
+
+    llvm::Optional<uint64_t> auxv_at_hwcap =
+        process.GetAuxValue(AuxVector::AUXV_AT_HWCAP);
+    if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
+      opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
+
+    llvm::Optional<uint64_t> auxv_at_hwcap2 =
+        process.GetAuxValue(AuxVector::AUXV_AT_HWCAP2);
+    if (auxv_at_hwcap2 && (*auxv_at_hwcap2 & HWCAP2_MTE))
+      opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskMTE);
+
+    auto register_info_up =
+        std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
+    return std::make_unique<NativeRegisterContextLinux_arm64>(
+        target_arch, native_thread, std::move(register_info_up));
+  }
   default:
     llvm_unreachable("have no register context for architecture");
   }
 }
 
 NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-    : NativeRegisterContextRegisterInfo(
-          native_thread, new RegisterInfoPOSIX_arm64(target_arch)) {
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+    std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
+    : NativeRegisterContextRegisterInfo(native_thread,
+                                        register_info_up.release()),
+      NativeRegisterContextLinux(native_thread) {
   ::memset(&m_fpr, 0, sizeof(m_fpr));
   ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
   ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
-  ::memset(&m_hbr_regs, 0, sizeof(m_hbr_regs));
+  ::memset(&m_hbp_regs, 0, sizeof(m_hbp_regs));
   ::memset(&m_sve_header, 0, sizeof(m_sve_header));
+  ::memset(&m_pac_mask, 0, sizeof(m_pac_mask));
+
+  m_mte_ctrl_reg = 0;
 
   // 16 is just a maximum value, query hardware for actual watchpoint count
   m_max_hwp_supported = 16;
@@ -74,9 +122,13 @@
   m_fpu_is_valid = false;
   m_sve_buffer_is_valid = false;
   m_sve_header_is_valid = false;
+  m_pac_mask_is_valid = false;
+  m_mte_ctrl_is_valid = false;
 
-  // SVE is not enabled until we query user_sve_header
-  m_sve_state = SVEState::Unknown;
+  if (GetRegisterInfo().IsSVEEnabled())
+    m_sve_state = SVEState::Unknown;
+  else
+    m_sve_state = SVEState::Disabled;
 }
 
 RegisterInfoPOSIX_arm64 &
@@ -155,15 +207,15 @@
       if (reg == GetRegisterInfo().GetRegNumFPSR()) {
         sve_reg_num = reg;
         if (m_sve_state == SVEState::Full)
-          offset = SVE_PT_SVE_FPSR_OFFSET(sve_vq_from_vl(m_sve_header.vl));
+          offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
         else if (m_sve_state == SVEState::FPSIMD)
-          offset = SVE_PT_FPSIMD_OFFSET + (32 * 16);
+          offset = sve::ptrace_fpsimd_offset + (32 * 16);
       } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
         sve_reg_num = reg;
         if (m_sve_state == SVEState::Full)
-          offset = SVE_PT_SVE_FPCR_OFFSET(sve_vq_from_vl(m_sve_header.vl));
+          offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
         else if (m_sve_state == SVEState::FPSIMD)
-          offset = SVE_PT_FPSIMD_OFFSET + (32 * 16) + 4;
+          offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
       } else {
         // Extract SVE Z register value register number for this reg_info
         if (reg_info->value_regs &&
@@ -208,6 +260,22 @@
         src = (uint8_t *)GetSVEBuffer() + offset;
       }
     }
+  } else if (IsPAuth(reg)) {
+    error = ReadPAuthMask();
+    if (error.Fail())
+      return error;
+
+    offset = reg_info->byte_offset - GetRegisterInfo().GetPAuthOffset();
+    assert(offset < GetPACMaskSize());
+    src = (uint8_t *)GetPACMask() + offset;
+  } else if (IsMTE(reg)) {
+    error = ReadMTEControl();
+    if (error.Fail())
+      return error;
+
+    offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
+    assert(offset < GetMTEControlSize());
+    src = (uint8_t *)GetMTEControl() + offset;
   } else
     return Status("failed - register wasn't recognized to be a GPR or an FPR, "
                   "write strategy unknown");
@@ -273,15 +341,15 @@
       if (reg == GetRegisterInfo().GetRegNumFPSR()) {
         sve_reg_num = reg;
         if (m_sve_state == SVEState::Full)
-          offset = SVE_PT_SVE_FPSR_OFFSET(sve_vq_from_vl(m_sve_header.vl));
+          offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
         else if (m_sve_state == SVEState::FPSIMD)
-          offset = SVE_PT_FPSIMD_OFFSET + (32 * 16);
+          offset = sve::ptrace_fpsimd_offset + (32 * 16);
       } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
         sve_reg_num = reg;
         if (m_sve_state == SVEState::Full)
-          offset = SVE_PT_SVE_FPCR_OFFSET(sve_vq_from_vl(m_sve_header.vl));
+          offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
         else if (m_sve_state == SVEState::FPSIMD)
-          offset = SVE_PT_FPSIMD_OFFSET + (32 * 16) + 4;
+          offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
       } else {
         // Extract SVE Z register value register number for this reg_info
         if (reg_info->value_regs &&
@@ -366,6 +434,17 @@
         return WriteAllSVE();
       }
     }
+  } else if (IsMTE(reg)) {
+    error = ReadMTEControl();
+    if (error.Fail())
+      return error;
+
+    offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
+    assert(offset < GetMTEControlSize());
+    dst = (uint8_t *)GetMTEControl() + offset;
+    ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
+
+    return WriteMTEControl();
   }
 
   return Status("Failed to write register value");
@@ -451,436 +530,20 @@
 }
 
 bool NativeRegisterContextLinux_arm64::IsSVE(unsigned reg) const {
-  if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
-      RegisterInfoPOSIX_arm64::SVERegSet)
-    return true;
-  return false;
+  return GetRegisterInfo().IsSVEReg(reg);
 }
 
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
-  LLDB_LOGF(log, "NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
-  Status error;
-
-  // Read hardware breakpoint and watchpoint information.
-  error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return 0;
-
-  return m_max_hbp_supported;
+bool NativeRegisterContextLinux_arm64::IsPAuth(unsigned reg) const {
+  return GetRegisterInfo().IsPAuthReg(reg);
 }
 
-uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
-                                                        size_t size) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-  LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
-
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return LLDB_INVALID_INDEX32;
-
-  uint32_t control_value = 0, bp_index = 0;
-
-  // Check if size has a valid hardware breakpoint length.
-  if (size != 4)
-    return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
-                                 // breakpoint
-
-  // Check 4-byte alignment for hardware breakpoint target address.
-  if (addr & 0x03)
-    return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
-
-  // Setup control value
-  control_value = 0;
-  control_value |= ((1 << size) - 1) << 5;
-  control_value |= (2 << 1) | 1;
-
-  // Iterate over stored breakpoints and find a free bp_index
-  bp_index = LLDB_INVALID_INDEX32;
-  for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
-    if ((m_hbr_regs[i].control & 1) == 0) {
-      bp_index = i; // Mark last free slot
-    } else if (m_hbr_regs[i].address == addr) {
-      return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
-    }
-  }
-
-  if (bp_index == LLDB_INVALID_INDEX32)
-    return LLDB_INVALID_INDEX32;
-
-  // Update breakpoint in local cache
-  m_hbr_regs[bp_index].real_addr = addr;
-  m_hbr_regs[bp_index].address = addr;
-  m_hbr_regs[bp_index].control = control_value;
-
-  // PTRACE call to set corresponding hardware breakpoint register.
-  error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
-  if (error.Fail()) {
-    m_hbr_regs[bp_index].address = 0;
-    m_hbr_regs[bp_index].control &= ~1;
-
-    return LLDB_INVALID_INDEX32;
-  }
-
-  return bp_index;
+bool NativeRegisterContextLinux_arm64::IsMTE(unsigned reg) const {
+  return GetRegisterInfo().IsMTEReg(reg);
 }
 
-bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint(
-    uint32_t hw_idx) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-  LLDB_LOG(log, "hw_idx: {0}", hw_idx);
-
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return false;
-
-  if (hw_idx >= m_max_hbp_supported)
-    return false;
-
-  // Create a backup we can revert to in case of failure.
-  lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
-  uint32_t tempControl = m_hbr_regs[hw_idx].control;
-
-  m_hbr_regs[hw_idx].control &= ~1;
-  m_hbr_regs[hw_idx].address = 0;
-
-  // PTRACE call to clear corresponding hardware breakpoint register.
-  error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
-  if (error.Fail()) {
-    m_hbr_regs[hw_idx].control = tempControl;
-    m_hbr_regs[hw_idx].address = tempAddr;
-
-    return false;
-  }
-
-  return true;
-}
-
-Status NativeRegisterContextLinux_arm64::GetHardwareBreakHitIndex(
-    uint32_t &bp_index, lldb::addr_t trap_addr) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
-  LLDB_LOGF(log, "NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
-  lldb::addr_t break_addr;
-
-  for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
-    break_addr = m_hbr_regs[bp_index].address;
-
-    if ((m_hbr_regs[bp_index].control & 0x1) && (trap_addr == break_addr)) {
-      m_hbr_regs[bp_index].hit_addr = trap_addr;
-      return Status();
-    }
-  }
-
-  bp_index = LLDB_INVALID_INDEX32;
-  return Status();
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareBreakpoints() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
-  LLDB_LOGF(log, "NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
-  Status error;
-
-  // Read hardware breakpoint and watchpoint information.
-  error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return error;
-
-  lldb::addr_t tempAddr = 0;
-  uint32_t tempControl = 0;
-
-  for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
-    if (m_hbr_regs[i].control & 0x01) {
-      // Create a backup we can revert to in case of failure.
-      tempAddr = m_hbr_regs[i].address;
-      tempControl = m_hbr_regs[i].control;
-
-      // Clear watchpoints in local cache
-      m_hbr_regs[i].control &= ~1;
-      m_hbr_regs[i].address = 0;
-
-      // Ptrace call to update hardware debug registers
-      error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
-      if (error.Fail()) {
-        m_hbr_regs[i].control = tempControl;
-        m_hbr_regs[i].address = tempAddr;
-
-        return error;
-      }
-    }
-  }
-
-  return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return 0;
-
-  LLDB_LOG(log, "{0}", m_max_hwp_supported);
-  return m_max_hwp_supported;
-}
-
-uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
-    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
-           watch_flags);
-
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return LLDB_INVALID_INDEX32;
-
-  uint32_t control_value = 0, wp_index = 0;
-  lldb::addr_t real_addr = addr;
-
-  // Check if we are setting watchpoint other than read/write/access Also
-  // update watchpoint flag to match AArch64 write-read bit configuration.
-  switch (watch_flags) {
-  case 1:
-    watch_flags = 2;
-    break;
-  case 2:
-    watch_flags = 1;
-    break;
-  case 3:
-    break;
-  default:
-    return LLDB_INVALID_INDEX32;
-  }
-
-  // Check if size has a valid hardware watchpoint length.
-  if (size != 1 && size != 2 && size != 4 && size != 8)
-    return LLDB_INVALID_INDEX32;
-
-  // Check 8-byte alignment for hardware watchpoint target address. Below is a
-  // hack to recalculate address and size in order to make sure we can watch
-  // non 8-byte aligned addresses as well.
-  if (addr & 0x07) {
-    uint8_t watch_mask = (addr & 0x07) + size;
-
-    if (watch_mask > 0x08)
-      return LLDB_INVALID_INDEX32;
-    else if (watch_mask <= 0x02)
-      size = 2;
-    else if (watch_mask <= 0x04)
-      size = 4;
-    else
-      size = 8;
-
-    addr = addr & (~0x07);
-  }
-
-  // Setup control value
-  control_value = watch_flags << 3;
-  control_value |= ((1 << size) - 1) << 5;
-  control_value |= (2 << 1) | 1;
-
-  // Iterate over stored watchpoints and find a free wp_index
-  wp_index = LLDB_INVALID_INDEX32;
-  for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
-    if ((m_hwp_regs[i].control & 1) == 0) {
-      wp_index = i; // Mark last free slot
-    } else if (m_hwp_regs[i].address == addr) {
-      return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
-    }
-  }
-
-  if (wp_index == LLDB_INVALID_INDEX32)
-    return LLDB_INVALID_INDEX32;
-
-  // Update watchpoint in local cache
-  m_hwp_regs[wp_index].real_addr = real_addr;
-  m_hwp_regs[wp_index].address = addr;
-  m_hwp_regs[wp_index].control = control_value;
-
-  // PTRACE call to set corresponding watchpoint register.
-  error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
-  if (error.Fail()) {
-    m_hwp_regs[wp_index].address = 0;
-    m_hwp_regs[wp_index].control &= ~1;
-
-    return LLDB_INVALID_INDEX32;
-  }
-
-  return wp_index;
-}
-
-bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint(
-    uint32_t wp_index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}", wp_index);
-
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return false;
-
-  if (wp_index >= m_max_hwp_supported)
-    return false;
-
-  // Create a backup we can revert to in case of failure.
-  lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
-  uint32_t tempControl = m_hwp_regs[wp_index].control;
-
-  // Update watchpoint in local cache
-  m_hwp_regs[wp_index].control &= ~1;
-  m_hwp_regs[wp_index].address = 0;
-
-  // Ptrace call to update hardware debug registers
-  error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
-  if (error.Fail()) {
-    m_hwp_regs[wp_index].control = tempControl;
-    m_hwp_regs[wp_index].address = tempAddr;
-
-    return false;
-  }
-
-  return true;
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
-  // Read hardware breakpoint and watchpoint information.
-  Status error = ReadHardwareDebugInfo();
-
-  if (error.Fail())
-    return error;
-
-  lldb::addr_t tempAddr = 0;
-  uint32_t tempControl = 0;
-
-  for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
-    if (m_hwp_regs[i].control & 0x01) {
-      // Create a backup we can revert to in case of failure.
-      tempAddr = m_hwp_regs[i].address;
-      tempControl = m_hwp_regs[i].control;
-
-      // Clear watchpoints in local cache
-      m_hwp_regs[i].control &= ~1;
-      m_hwp_regs[i].address = 0;
-
-      // Ptrace call to update hardware debug registers
-      error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
-      if (error.Fail()) {
-        m_hwp_regs[i].control = tempControl;
-        m_hwp_regs[i].address = tempAddr;
-
-        return error;
-      }
-    }
-  }
-
-  return Status();
-}
-
-uint32_t
-NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}", wp_index);
-
-  switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
-  case 0x01:
-    return 1;
-  case 0x03:
-    return 2;
-  case 0x0f:
-    return 4;
-  case 0xff:
-    return 8;
-  default:
-    return 0;
-  }
-}
-bool NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}", wp_index);
-
-  if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
-    return true;
-  else
-    return false;
-}
-
-Status NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(
-    uint32_t &wp_index, lldb::addr_t trap_addr) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
-  uint32_t watch_size;
-  lldb::addr_t watch_addr;
-
-  for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
-    watch_size = GetWatchpointSize(wp_index);
-    watch_addr = m_hwp_regs[wp_index].address;
-
-    if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
-        trap_addr < watch_addr + watch_size) {
-      m_hwp_regs[wp_index].hit_addr = trap_addr;
-      return Status();
-    }
-  }
-
-  wp_index = LLDB_INVALID_INDEX32;
-  return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}", wp_index);
-
-  if (wp_index >= m_max_hwp_supported)
-    return LLDB_INVALID_ADDRESS;
-
-  if (WatchpointIsEnabled(wp_index))
-    return m_hwp_regs[wp_index].real_addr;
-  else
-    return LLDB_INVALID_ADDRESS;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  LLDB_LOG(log, "wp_index: {0}", wp_index);
-
-  if (wp_index >= m_max_hwp_supported)
-    return LLDB_INVALID_ADDRESS;
-
-  if (WatchpointIsEnabled(wp_index))
-    return m_hwp_regs[wp_index].hit_addr;
-  else
-    return LLDB_INVALID_ADDRESS;
-}
-
-Status NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
+llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
   if (!m_refresh_hwdebug_info) {
-    return Status();
+    return llvm::Error::success();
   }
 
   ::pid_t tid = m_thread.GetID();
@@ -896,7 +559,7 @@
                                             &ioVec, ioVec.iov_len);
 
   if (error.Fail())
-    return error;
+    return error.ToError();
 
   m_max_hwp_supported = dreg_state.dbg_info & 0xff;
 
@@ -905,24 +568,26 @@
                                             &ioVec, ioVec.iov_len);
 
   if (error.Fail())
-    return error;
+    return error.ToError();
 
   m_max_hbp_supported = dreg_state.dbg_info & 0xff;
   m_refresh_hwdebug_info = false;
 
-  return error;
+  return llvm::Error::success();
 }
 
-Status NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) {
+llvm::Error
+NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
   struct iovec ioVec;
   struct user_hwdebug_state dreg_state;
-  Status error;
+  int regset;
 
   memset(&dreg_state, 0, sizeof(dreg_state));
   ioVec.iov_base = &dreg_state;
 
-  if (hwbType == eDREGTypeWATCH) {
-    hwbType = NT_ARM_HW_WATCH;
+  switch (hwbType) {
+  case eDREGTypeWATCH:
+    regset = NT_ARM_HW_WATCH;
     ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
                     (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
 
@@ -930,19 +595,22 @@
       dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
       dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
     }
-  } else {
-    hwbType = NT_ARM_HW_BREAK;
+    break;
+  case eDREGTypeBREAK:
+    regset = NT_ARM_HW_BREAK;
     ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
                     (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
 
     for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
-      dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
-      dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
+      dreg_state.dbg_regs[i].addr = m_hbp_regs[i].address;
+      dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
     }
+    break;
   }
 
   return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
-                                           &hwbType, &ioVec, ioVec.iov_len);
+                                           &regset, &ioVec, ioVec.iov_len)
+      .ToError();
 }
 
 Status NativeRegisterContextLinux_arm64::ReadGPR() {
@@ -1014,6 +682,8 @@
   m_fpu_is_valid = false;
   m_sve_buffer_is_valid = false;
   m_sve_header_is_valid = false;
+  m_pac_mask_is_valid = false;
+  m_mte_ctrl_is_valid = false;
 
   // Update SVE registers in case there is change in configuration.
   ConfigureRegisterContext();
@@ -1031,7 +701,26 @@
 
   error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), NT_ARM_SVE);
 
-  m_sve_header_is_valid = true;
+  if (error.Success())
+    m_sve_header_is_valid = true;
+
+  return error;
+}
+
+Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
+  Status error;
+
+  if (m_pac_mask_is_valid)
+    return error;
+
+  struct iovec ioVec;
+  ioVec.iov_base = GetPACMask();
+  ioVec.iov_len = GetPACMaskSize();
+
+  error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
+
+  if (error.Success())
+    m_pac_mask_is_valid = true;
 
   return error;
 }
@@ -1091,25 +780,65 @@
   return WriteRegisterSet(&ioVec, GetSVEBufferSize(), NT_ARM_SVE);
 }
 
+Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
+  Status error;
+
+  if (m_mte_ctrl_is_valid)
+    return error;
+
+  struct iovec ioVec;
+  ioVec.iov_base = GetMTEControl();
+  ioVec.iov_len = GetMTEControlSize();
+
+  error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
+
+  if (error.Success())
+    m_mte_ctrl_is_valid = true;
+
+  return error;
+}
+
+Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
+  Status error;
+
+  error = ReadMTEControl();
+  if (error.Fail())
+    return error;
+
+  struct iovec ioVec;
+  ioVec.iov_base = GetMTEControl();
+  ioVec.iov_len = GetMTEControlSize();
+
+  m_mte_ctrl_is_valid = false;
+
+  return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
+}
+
 void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
-  // Read SVE configuration data and configure register infos.
+  // ConfigureRegisterContext gets called from InvalidateAllRegisters
+  // on every stop and configures SVE vector length.
+  // If m_sve_state is set to SVEState::Disabled on first stop, code below will
+  // be deemed non operational for the lifetime of current process.
   if (!m_sve_header_is_valid && m_sve_state != SVEState::Disabled) {
     Status error = ReadSVEHeader();
-    if (!error.Success() && m_sve_state == SVEState::Unknown) {
-      m_sve_state = SVEState::Disabled;
-      GetRegisterInfo().ConfigureVectorRegisterInfos(
-          RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64);
-    } else {
-      if ((m_sve_header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
+    if (error.Success()) {
+      // If SVE is enabled thread can switch between SVEState::FPSIMD and
+      // SVEState::Full on every stop.
+      if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
+          sve::ptrace_regs_fpsimd)
         m_sve_state = SVEState::FPSIMD;
-      else if ((m_sve_header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE)
+      else if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
+               sve::ptrace_regs_sve)
         m_sve_state = SVEState::Full;
 
+      // On every stop we configure SVE vector length by calling
+      // ConfigureVectorLength regardless of current SVEState of this thread.
       uint32_t vq = RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64SVE;
       if (sve_vl_valid(m_sve_header.vl))
-        vq = sve_vq_from_vl(m_sve_header.vl);
-      GetRegisterInfo().ConfigureVectorRegisterInfos(vq);
-      m_sve_ptrace_payload.resize(SVE_PT_SIZE(vq, SVE_PT_REGS_SVE));
+        vq = sve::vq_from_vl(m_sve_header.vl);
+
+      GetRegisterInfo().ConfigureVectorLength(vq);
+      m_sve_ptrace_payload.resize(sve::PTraceSize(vq, sve::ptrace_regs_sve));
     }
   }
 }
@@ -1125,19 +854,19 @@
   uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
   if (m_sve_state == SVEState::FPSIMD) {
     const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-    sve_reg_offset =
-        SVE_PT_FPSIMD_OFFSET + (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
+    sve_reg_offset = sve::ptrace_fpsimd_offset +
+                     (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
   } else if (m_sve_state == SVEState::Full) {
     uint32_t sve_z0_offset = GetGPRSize() + 16;
     sve_reg_offset =
-        SVE_SIG_REGS_OFFSET + reg_info->byte_offset - sve_z0_offset;
+        sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
   }
   return sve_reg_offset;
 }
 
 void *NativeRegisterContextLinux_arm64::GetSVEBuffer() {
   if (m_sve_state == SVEState::FPSIMD)
-    return m_sve_ptrace_payload.data() + SVE_PT_FPSIMD_OFFSET;
+    return m_sve_ptrace_payload.data() + sve::ptrace_fpsimd_offset;
 
   return m_sve_ptrace_payload.data();
 }
@@ -1152,4 +881,30 @@
   return expedited_reg_nums;
 }
 
+llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
+NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
+  if (type == MemoryTagManagerAArch64MTE::eMTE_allocation) {
+    return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
+                                PTRACE_PEEKMTETAGS, PTRACE_POKEMTETAGS};
+  }
+
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "Unknown AArch64 memory tag type %d", type);
+}
+
+lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
+    lldb::addr_t hit_addr) {
+  // Linux configures user-space virtual addresses with top byte ignored.
+  // We set default value of mask such that top byte is masked out.
+  lldb::addr_t mask = ~((1ULL << 56) - 1);
+
+  // Try to read pointer authentication data_mask register and calculate a
+  // consolidated data address mask after ignoring the top byte.
+  if (ReadPAuthMask().Success())
+    mask |= m_pac_mask.data_mask;
+
+  return hit_addr & ~mask;
+  ;
+}
+
 #endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 344eae24..4dfc78b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -12,6 +12,8 @@
 #define lldb_NativeRegisterContextLinux_arm64_h
 
 #include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h"
 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
 
 #include <asm/ptrace.h>
@@ -21,10 +23,13 @@
 
 class NativeProcessLinux;
 
-class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
+class NativeRegisterContextLinux_arm64
+    : public NativeRegisterContextLinux,
+      public NativeRegisterContextDBReg_arm64 {
 public:
-  NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
-                                   NativeThreadProtocol &native_thread);
+  NativeRegisterContextLinux_arm64(
+      const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up);
 
   uint32_t GetRegisterSetCount() const override;
 
@@ -49,44 +54,10 @@
 
   bool RegisterOffsetIsDynamic() const override { return true; }
 
-  // Hardware breakpoints/watchpoint management functions
-
-  uint32_t NumSupportedHardwareBreakpoints() override;
-
-  uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
-  bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
-  Status ClearAllHardwareBreakpoints() override;
-
-  Status GetHardwareBreakHitIndex(uint32_t &bp_index,
-                                  lldb::addr_t trap_addr) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
-                                 uint32_t watch_flags) override;
-
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
-  Status ClearAllHardwareWatchpoints() override;
-
-  Status GetWatchpointHitIndex(uint32_t &wp_index,
-                               lldb::addr_t trap_addr) override;
-
-  lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
-  uint32_t GetWatchpointSize(uint32_t wp_index);
-
-  bool WatchpointIsEnabled(uint32_t wp_index);
-
-  // Debug register type select
-  enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
+  llvm::Expected<MemoryTaggingDetails>
+  GetMemoryTaggingDetails(int32_t type) override;
 
 protected:
-
   Status ReadGPR() override;
 
   Status WriteGPR() override;
@@ -105,12 +76,16 @@
 
   size_t GetFPRSize() override { return sizeof(m_fpr); }
 
+  lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) override;
+
 private:
   bool m_gpr_is_valid;
   bool m_fpu_is_valid;
   bool m_sve_buffer_is_valid;
+  bool m_mte_ctrl_is_valid;
 
   bool m_sve_header_is_valid;
+  bool m_pac_mask_is_valid;
 
   struct user_pt_regs m_gpr_arm64; // 64-bit general purpose registers.
 
@@ -118,25 +93,19 @@
       m_fpr; // floating-point registers including extended register sets.
 
   SVEState m_sve_state;
-  struct user_sve_header m_sve_header;
+  struct sve::user_sve_header m_sve_header;
   std::vector<uint8_t> m_sve_ptrace_payload;
 
-  // Debug register info for hardware breakpoints and watchpoints management.
-  struct DREG {
-    lldb::addr_t address;  // Breakpoint/watchpoint address value.
-    lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
-                           // occurred.
-    lldb::addr_t real_addr; // Address value that should cause target to stop.
-    uint32_t control;       // Breakpoint/watchpoint control value.
-    uint32_t refcount;      // Serves as enable/disable and reference counter.
+  bool m_refresh_hwdebug_info;
+
+  struct user_pac_mask {
+    uint64_t data_mask;
+    uint64_t insn_mask;
   };
 
-  struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
-  struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
+  struct user_pac_mask m_pac_mask;
 
-  uint32_t m_max_hwp_supported;
-  uint32_t m_max_hbp_supported;
-  bool m_refresh_hwdebug_info;
+  uint64_t m_mte_ctrl_reg;
 
   bool IsGPR(unsigned reg) const;
 
@@ -150,7 +119,15 @@
 
   Status WriteSVEHeader();
 
+  Status ReadPAuthMask();
+
+  Status ReadMTEControl();
+
+  Status WriteMTEControl();
+
   bool IsSVE(unsigned reg) const;
+  bool IsPAuth(unsigned reg) const;
+  bool IsMTE(unsigned reg) const;
 
   uint64_t GetSVERegVG() { return m_sve_header.vl / 8; }
 
@@ -158,15 +135,23 @@
 
   void *GetSVEHeader() { return &m_sve_header; }
 
+  void *GetPACMask() { return &m_pac_mask; }
+
+  void *GetMTEControl() { return &m_mte_ctrl_reg; }
+
   void *GetSVEBuffer();
 
   size_t GetSVEHeaderSize() { return sizeof(m_sve_header); }
 
+  size_t GetPACMaskSize() { return sizeof(m_pac_mask); }
+
   size_t GetSVEBufferSize() { return m_sve_ptrace_payload.size(); }
 
-  Status ReadHardwareDebugInfo();
+  size_t GetMTEControlSize() { return sizeof(m_mte_ctrl_reg); }
 
-  Status WriteHardwareDebugRegs(int hwbType);
+  llvm::Error ReadHardwareDebugInfo() override;
+
+  llvm::Error WriteHardwareDebugRegs(DREGType hwbType) override;
 
   uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
deleted file mode 100644
index 5abbab1..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ /dev/null
@@ -1,1036 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.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
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#include "NativeRegisterContextLinux_mips64.h"
-
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-private-enumerations.h"
-#define NT_MIPS_MSA 0x600
-#define CONFIG5_FRE (1 << 8)
-#define SR_FR (1 << 26)
-#define NUM_REGISTERS 32
-
-#include <asm/ptrace.h>
-#include <sys/ptrace.h>
-
-#ifndef PTRACE_GET_WATCH_REGS
-enum pt_watch_style { pt_watch_style_mips32, pt_watch_style_mips64 };
-struct mips32_watch_regs {
-  uint32_t watchlo[8];
-  uint16_t watchhi[8];
-  uint16_t watch_masks[8];
-  uint32_t num_valid;
-} __attribute__((aligned(8)));
-
-struct mips64_watch_regs {
-  uint64_t watchlo[8];
-  uint16_t watchhi[8];
-  uint16_t watch_masks[8];
-  uint32_t num_valid;
-} __attribute__((aligned(8)));
-
-struct pt_watch_regs {
-  enum pt_watch_style style;
-  union {
-    struct mips32_watch_regs mips32;
-    struct mips64_watch_regs mips64;
-  };
-};
-
-#define PTRACE_GET_WATCH_REGS 0xd0
-#define PTRACE_SET_WATCH_REGS 0xd1
-#endif
-
-#define W (1 << 0)
-#define R (1 << 1)
-#define I (1 << 2)
-
-#define IRW (I | R | W)
-
-#ifndef PTRACE_GETREGSET
-#define PTRACE_GETREGSET 0x4204
-#endif
-struct pt_watch_regs default_watch_regs;
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
-  return std::make_unique<NativeRegisterContextLinux_mips64>(target_arch,
-                                                              native_thread);
-}
-
-#define REG_CONTEXT_SIZE                                                       \
-  (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR_linux_mips) +          \
-   sizeof(MSA_linux_mips))
-
-// NativeRegisterContextLinux_mips64 members.
-
-static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch) {
-  if ((target_arch.GetMachine() == llvm::Triple::mips) ||
-       (target_arch.GetMachine() == llvm::Triple::mipsel)) {
-    // 32-bit hosts run with a RegisterContextLinux_mips context.
-    return new RegisterContextLinux_mips(
-        target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
-  } else {
-    return new RegisterContextLinux_mips64(
-        target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
-  }
-}
-
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-    : NativeRegisterContextRegisterInfo(
-          native_thread, CreateRegisterInfoInterface(target_arch)) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    m_reg_info.num_registers = k_num_registers_mips;
-    m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
-    m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
-    m_reg_info.last_gpr = k_last_gpr_mips;
-    m_reg_info.first_fpr = k_first_fpr_mips;
-    m_reg_info.last_fpr = k_last_fpr_mips;
-    m_reg_info.first_msa = k_first_msa_mips;
-    m_reg_info.last_msa = k_last_msa_mips;
-    break;
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    m_reg_info.num_registers = k_num_registers_mips64;
-    m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
-    m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
-    m_reg_info.last_gpr = k_last_gpr_mips64;
-    m_reg_info.first_fpr = k_first_fpr_mips64;
-    m_reg_info.last_fpr = k_last_fpr_mips64;
-    m_reg_info.first_msa = k_first_msa_mips64;
-    m_reg_info.last_msa = k_last_msa_mips64;
-    break;
-  default:
-    assert(false && "Unhandled target architecture.");
-    break;
-  }
-
-  // Initialize m_iovec to point to the buffer and buffer size using the
-  // conventions of Berkeley style UIO structures, as required by PTRACE
-  // extensions.
-  m_iovec.iov_base = &m_msa;
-  m_iovec.iov_len = sizeof(MSA_linux_mips);
-
-  // init h/w watchpoint addr map
-  for (int index = 0; index <= MAX_NUM_WP; index++)
-    hw_addr_map[index] = LLDB_INVALID_ADDRESS;
-
-  ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
-  ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
-  ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
-}
-
-uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
-  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    const auto context = static_cast<const RegisterContextLinux_mips64 &>
-                         (GetRegisterInfoInterface());
-    return context.GetRegisterSetCount();
-  }
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel: {
-    const auto context = static_cast<const RegisterContextLinux_mips &>
-                         (GetRegisterInfoInterface());
-    return context.GetRegisterSetCount();
-  }
-  default:
-    llvm_unreachable("Unhandled target architecture.");
-  }
-}
-
-lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
-    lldb::addr_t fail_value) {
-  Status error;
-  RegisterValue pc_value;
-  lldb::addr_t pc = fail_value;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-  LLDB_LOG(log, "Reading PC from breakpoint location");
-
-  // PC register is at index 34 of the register array
-  const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex(gpr_pc_mips64);
-
-  error = ReadRegister(pc_info_p, pc_value);
-  if (error.Success()) {
-    pc = pc_value.GetAsUInt64();
-
-    // CAUSE register is at index 37 of the register array
-    const RegisterInfo *const cause_info_p =
-        GetRegisterInfoAtIndex(gpr_cause_mips64);
-    RegisterValue cause_value;
-
-    ReadRegister(cause_info_p, cause_value);
-
-    uint64_t cause = cause_value.GetAsUInt64();
-    LLDB_LOG(log, "PC {0:x} cause {1:x}", pc, cause);
-
-    /*
-     * The breakpoint might be in a delay slot. In this case PC points
-     * to the delayed branch instruction rather then the instruction
-     * in the delay slot. If the CAUSE.BD flag is set then adjust the
-     * PC based on the size of the branch instruction.
-    */
-    if ((cause & (1 << 31)) != 0) {
-      lldb::addr_t branch_delay = 0;
-      branch_delay =
-          4; // FIXME - Adjust according to size of branch instruction at PC
-      pc = pc + branch_delay;
-      pc_value.SetUInt64(pc);
-      WriteRegister(pc_info_p, pc_value);
-      LLDB_LOG(log, "New PC {0:x}", pc);
-    }
-  }
-
-  return pc;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
-  if (set_index >= GetRegisterSetCount())
-    return nullptr;
-
-  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el: {
-    const auto context = static_cast<const RegisterContextLinux_mips64 &>
-                          (GetRegisterInfoInterface());
-    return context.GetRegisterSet(set_index);
-  }
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel: {
-    const auto context = static_cast<const RegisterContextLinux_mips &>
-                         (GetRegisterInfoInterface());
-    return context.GetRegisterSet(set_index);
-  }
-  default:
-    llvm_unreachable("Unhandled target architecture.");
-  }
-}
-
-lldb_private::Status
-NativeRegisterContextLinux_mips64::ReadRegister(const RegisterInfo *reg_info,
-                                                RegisterValue &reg_value) {
-  Status error;
-
-  if (!reg_info) {
-    error.SetErrorString("reg_info NULL");
-    return error;
-  }
-
-  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-  uint8_t byte_size = reg_info->byte_size;
-  if (reg == LLDB_INVALID_REGNUM) {
-    // This is likely an internal register for lldb use only and should not be
-    // directly queried.
-    error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
-                                   "register, cannot read directly",
-                                   reg_info->name);
-    return error;
-  }
-
-  if (IsMSA(reg) && !IsMSAAvailable()) {
-    error.SetErrorString("MSA not available on this processor");
-    return error;
-  }
-
-  if (IsMSA(reg) || IsFPR(reg)) {
-    uint8_t *src = nullptr;
-    lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
-    error = ReadCP1();
-
-    if (!error.Success()) {
-      error.SetErrorString("failed to read co-processor 1 register");
-      return error;
-    }
-
-    if (IsFPR(reg)) {
-      if (IsFR0() && (byte_size != 4)) {
-        byte_size = 4;
-        uint8_t ptrace_index;
-        ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
-        src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
-      } else
-        src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
-    } else
-      src = (uint8_t *)&m_msa + reg_info->byte_offset -
-            (sizeof(m_gpr) + sizeof(m_fpr));
-    switch (byte_size) {
-    case 4:
-      reg_value.SetUInt32(*(uint32_t *)src);
-      break;
-    case 8:
-      reg_value.SetUInt64(*(uint64_t *)src);
-      break;
-    case 16:
-      reg_value.SetBytes((const void *)src, 16, GetByteOrder());
-      break;
-    default:
-      assert(false && "Unhandled data size.");
-      error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
-                                     reg_info->byte_size);
-      break;
-    }
-  } else {
-    error = ReadRegisterRaw(reg, reg_value);
-  }
-
-  return error;
-}
-
-lldb_private::Status NativeRegisterContextLinux_mips64::WriteRegister(
-    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
-  Status error;
-
-  assert(reg_info && "reg_info is null");
-
-  const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
-
-  if (reg_index == LLDB_INVALID_REGNUM)
-    return Status("no lldb regnum for %s", reg_info && reg_info->name
-                                               ? reg_info->name
-                                               : "<unknown register>");
-
-  if (IsMSA(reg_index) && !IsMSAAvailable()) {
-    error.SetErrorString("MSA not available on this processor");
-    return error;
-  }
-
-  if (IsFPR(reg_index) || IsMSA(reg_index)) {
-    uint8_t *dst = nullptr;
-    uint64_t *src = nullptr;
-    uint8_t byte_size = reg_info->byte_size;
-    lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
-    // Initialise the FP and MSA buffers by reading all co-processor 1
-    // registers
-    ReadCP1();
-
-    if (IsFPR(reg_index)) {
-      if (IsFR0() && (byte_size != 4)) {
-        byte_size = 4;
-        uint8_t ptrace_index;
-        ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
-        dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
-      } else
-        dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
-    } else
-      dst = (uint8_t *)&m_msa + reg_info->byte_offset -
-            (sizeof(m_gpr) + sizeof(m_fpr));
-    switch (byte_size) {
-    case 4:
-      *(uint32_t *)dst = reg_value.GetAsUInt32();
-      break;
-    case 8:
-      *(uint64_t *)dst = reg_value.GetAsUInt64();
-      break;
-    case 16:
-      src = (uint64_t *)reg_value.GetBytes();
-      *(uint64_t *)dst = *src;
-      *(uint64_t *)(dst + 8) = *(src + 1);
-      break;
-    default:
-      assert(false && "Unhandled data size.");
-      error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
-                                     reg_info->byte_size);
-      break;
-    }
-    error = WriteCP1();
-    if (!error.Success()) {
-      error.SetErrorString("failed to write co-processor 1 register");
-      return error;
-    }
-  } else {
-    error = WriteRegisterRaw(reg_index, reg_value);
-  }
-
-  return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadAllRegisterValues(
-    lldb::DataBufferSP &data_sp) {
-  Status error;
-
-  data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
-  error = ReadGPR();
-  if (!error.Success()) {
-    error.SetErrorString("ReadGPR() failed");
-    return error;
-  }
-
-  error = ReadCP1();
-  if (!error.Success()) {
-    error.SetErrorString("ReadCP1() failed");
-    return error;
-  }
-
-  uint8_t *dst = data_sp->GetBytes();
-  ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
-  dst += GetRegisterInfoInterface().GetGPRSize();
-
-  ::memcpy(dst, &m_fpr, GetFPRSize());
-  dst += GetFPRSize();
-
-  ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips));
-
-  return error;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteAllRegisterValues(
-    const lldb::DataBufferSP &data_sp) {
-  Status error;
-
-  if (!data_sp) {
-    error.SetErrorStringWithFormat(
-        "NativeRegisterContextLinux_mips64::%s invalid data_sp provided",
-        __FUNCTION__);
-    return error;
-  }
-
-  if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
-    error.SetErrorStringWithFormat(
-        "NativeRegisterContextLinux_mips64::%s data_sp contained mismatched "
-        "data size, expected %" PRIu64 ", actual %" PRIu64,
-        __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
-    return error;
-  }
-
-  uint8_t *src = data_sp->GetBytes();
-  if (src == nullptr) {
-    error.SetErrorStringWithFormat("NativeRegisterContextLinux_mips64::%s "
-                                   "DataBuffer::GetBytes() returned a null "
-                                   "pointer",
-                                   __FUNCTION__);
-    return error;
-  }
-
-  ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
-  src += GetRegisterInfoInterface().GetGPRSize();
-
-  ::memcpy(&m_fpr, src, GetFPRSize());
-  src += GetFPRSize();
-
-  ::memcpy(&m_msa, src, sizeof(MSA_linux_mips));
-
-  error = WriteGPR();
-  if (!error.Success()) {
-    error.SetErrorStringWithFormat(
-        "NativeRegisterContextLinux_mips64::%s WriteGPR() failed",
-        __FUNCTION__);
-    return error;
-  }
-
-  error = WriteCP1();
-  if (!error.Success()) {
-    error.SetErrorStringWithFormat(
-        "NativeRegisterContextLinux_mips64::%s WriteCP1() failed",
-        __FUNCTION__);
-    return error;
-  }
-
-  return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadCP1() {
-  Status error;
-
-  uint8_t *src = nullptr;
-  uint8_t *dst = nullptr;
-
-  lldb::ByteOrder byte_order = GetByteOrder();
-
-  bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
-  if (IsMSAAvailable()) {
-    error = NativeRegisterContextLinux::ReadRegisterSet(
-        &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
-    src = (uint8_t *)&m_msa + (IsBigEndian * 8);
-    dst = (uint8_t *)&m_fpr;
-    for (int i = 0; i < NUM_REGISTERS; i++) {
-      // Copy fp values from msa buffer fetched via ptrace
-      *(uint64_t *)dst = *(uint64_t *)src;
-      src = src + 16;
-      dst = dst + 8;
-    }
-    m_fpr.fir = m_msa.fir;
-    m_fpr.fcsr = m_msa.fcsr;
-    m_fpr.config5 = m_msa.config5;
-  } else {
-    error = NativeRegisterContextLinux::ReadFPR();
-  }
-  return error;
-}
-
-uint8_t *
-NativeRegisterContextLinux_mips64::ReturnFPOffset(uint8_t reg_index,
-                                                  uint32_t byte_offset) {
-
-  uint8_t *fp_buffer_ptr = nullptr;
-  lldb::ByteOrder byte_order = GetByteOrder();
-  bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-  if (reg_index % 2) {
-    uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
-    fp_buffer_ptr =
-        (uint8_t *)&m_fpr + byte_offset - offset_diff - sizeof(m_gpr);
-  } else {
-    fp_buffer_ptr =
-        (uint8_t *)&m_fpr + byte_offset + 4 * (IsBigEndian) - sizeof(m_gpr);
-  }
-  return fp_buffer_ptr;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteCP1() {
-  Status error;
-
-  uint8_t *src = nullptr;
-  uint8_t *dst = nullptr;
-
-  lldb::ByteOrder byte_order = GetByteOrder();
-
-  bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
-  if (IsMSAAvailable()) {
-    dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
-    src = (uint8_t *)&m_fpr;
-    for (int i = 0; i < NUM_REGISTERS; i++) {
-      // Copy fp values to msa buffer for ptrace
-      *(uint64_t *)dst = *(uint64_t *)src;
-      dst = dst + 16;
-      src = src + 8;
-    }
-    m_msa.fir = m_fpr.fir;
-    m_msa.fcsr = m_fpr.fcsr;
-    m_msa.config5 = m_fpr.config5;
-    error = NativeRegisterContextLinux::WriteRegisterSet(
-        &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
-  } else {
-    error = NativeRegisterContextLinux::WriteFPR();
-  }
-
-  return error;
-}
-
-bool NativeRegisterContextLinux_mips64::IsFR0() {
-  const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex(gpr_sr_mips64);
-
-  RegisterValue reg_value;
-  ReadRegister(reg_info_p, reg_value);
-
-  uint64_t value = reg_value.GetAsUInt64();
-
-  return (!(value & SR_FR));
-}
-
-bool NativeRegisterContextLinux_mips64::IsFRE() {
-  const RegisterInfo *const reg_info_p =
-      GetRegisterInfoAtIndex(gpr_config5_mips64);
-
-  RegisterValue reg_value;
-  ReadRegister(reg_info_p, reg_value);
-
-  uint64_t config5 = reg_value.GetAsUInt64();
-
-  return (config5 & CONFIG5_FRE);
-}
-
-bool NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const {
-  return (m_reg_info.first_fpr <= reg_index &&
-          reg_index <= m_reg_info.last_fpr);
-}
-
-static uint32_t GetWatchHi(struct pt_watch_regs *regs, uint32_t index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    return regs->mips32.watchhi[index];
-  else if (regs->style == pt_watch_style_mips64)
-    return regs->mips64.watchhi[index];
-  LLDB_LOG(log, "Invalid watch register style");
-  return 0;
-}
-
-static void SetWatchHi(struct pt_watch_regs *regs, uint32_t index,
-                       uint16_t value) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    regs->mips32.watchhi[index] = value;
-  else if (regs->style == pt_watch_style_mips64)
-    regs->mips64.watchhi[index] = value;
-  LLDB_LOG(log, "Invalid watch register style");
-  return;
-}
-
-static lldb::addr_t GetWatchLo(struct pt_watch_regs *regs, uint32_t index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    return regs->mips32.watchlo[index];
-  else if (regs->style == pt_watch_style_mips64)
-    return regs->mips64.watchlo[index];
-  LLDB_LOG(log, "Invalid watch register style");
-  return LLDB_INVALID_ADDRESS;
-}
-
-static void SetWatchLo(struct pt_watch_regs *regs, uint32_t index,
-                       uint64_t value) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    regs->mips32.watchlo[index] = (uint32_t)value;
-  else if (regs->style == pt_watch_style_mips64)
-    regs->mips64.watchlo[index] = value;
-  else
-    LLDB_LOG(log, "Invalid watch register style");
-}
-
-static uint32_t GetIRWMask(struct pt_watch_regs *regs, uint32_t index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    return regs->mips32.watch_masks[index] & IRW;
-  else if (regs->style == pt_watch_style_mips64)
-    return regs->mips64.watch_masks[index] & IRW;
-  LLDB_LOG(log, "Invalid watch register style");
-  return 0;
-}
-
-static uint32_t GetRegMask(struct pt_watch_regs *regs, uint32_t index) {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  if (regs->style == pt_watch_style_mips32)
-    return regs->mips32.watch_masks[index] & ~IRW;
-  else if (regs->style == pt_watch_style_mips64)
-    return regs->mips64.watch_masks[index] & ~IRW;
-  LLDB_LOG(log, "Invalid watch register style");
-  return 0;
-}
-
-static lldb::addr_t GetRangeMask(lldb::addr_t mask) {
-  lldb::addr_t mask_bit = 1;
-  while (mask_bit < mask) {
-    mask = mask | mask_bit;
-    mask_bit <<= 1;
-  }
-  return mask;
-}
-
-static int GetVacantWatchIndex(struct pt_watch_regs *regs, lldb::addr_t addr,
-                               uint32_t size, uint32_t irw,
-                               uint32_t num_valid) {
-  lldb::addr_t last_byte = addr + size - 1;
-  lldb::addr_t mask = GetRangeMask(addr ^ last_byte) | IRW;
-  lldb::addr_t base_addr = addr & ~mask;
-
-  // Check if this address is already watched by previous watch points.
-  lldb::addr_t lo;
-  uint16_t hi;
-  uint32_t vacant_watches = 0;
-  for (uint32_t index = 0; index < num_valid; index++) {
-    lo = GetWatchLo(regs, index);
-    if (lo != 0 && irw == ((uint32_t)lo & irw)) {
-      hi = GetWatchHi(regs, index) | IRW;
-      lo &= ~(lldb::addr_t)hi;
-      if (addr >= lo && last_byte <= (lo + hi))
-        return index;
-    } else
-      vacant_watches++;
-  }
-
-  // Now try to find a vacant index
-  if (vacant_watches > 0) {
-    vacant_watches = 0;
-    for (uint32_t index = 0; index < num_valid; index++) {
-      lo = GetWatchLo(regs, index);
-      if (lo == 0 && irw == (GetIRWMask(regs, index) & irw)) {
-        if (mask <= (GetRegMask(regs, index) | IRW)) {
-          // It fits, we can use it.
-          SetWatchLo(regs, index, base_addr | irw);
-          SetWatchHi(regs, index, mask & ~IRW);
-          return index;
-        } else {
-          // It doesn't fit, but has the proper IRW capabilities
-          vacant_watches++;
-        }
-      }
-    }
-
-    if (vacant_watches > 1) {
-      // Split this watchpoint across several registers
-      struct pt_watch_regs regs_copy;
-      regs_copy = *regs;
-      lldb::addr_t break_addr;
-      uint32_t segment_size;
-      for (uint32_t index = 0; index < num_valid; index++) {
-        lo = GetWatchLo(&regs_copy, index);
-        hi = GetRegMask(&regs_copy, index) | IRW;
-        if (lo == 0 && irw == (hi & irw)) {
-          lo = addr & ~(lldb::addr_t)hi;
-          break_addr = lo + hi + 1;
-          if (break_addr >= addr + size)
-            segment_size = size;
-          else
-            segment_size = break_addr - addr;
-          mask = GetRangeMask(addr ^ (addr + segment_size - 1));
-          SetWatchLo(&regs_copy, index, (addr & ~mask) | irw);
-          SetWatchHi(&regs_copy, index, mask & ~IRW);
-          if (break_addr >= addr + size) {
-            *regs = regs_copy;
-            return index;
-          }
-          size = addr + size - break_addr;
-          addr = break_addr;
-        }
-      }
-    }
-  }
-  return LLDB_INVALID_INDEX32;
-}
-
-bool NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const {
-  return (m_reg_info.first_msa <= reg_index &&
-          reg_index <= m_reg_info.last_msa);
-}
-
-bool NativeRegisterContextLinux_mips64::IsMSAAvailable() {
-  MSA_linux_mips msa_buf;
-  unsigned int regset = NT_MIPS_MSA;
-
-  Status error = NativeProcessLinux::PtraceWrapper(
-      PTRACE_GETREGSET, Host::GetCurrentProcessID(),
-      static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
-
-  if (error.Success() && msa_buf.mir) {
-    return true;
-  }
-
-  return false;
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointHit(uint32_t wp_index,
-                                                          bool &is_hit) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return Status("Watchpoint index out of range");
-
-  // reading the current state of watch regs
-  struct pt_watch_regs watch_readback;
-  Status error = DoReadWatchPointRegisterValue(
-      m_thread.GetID(), static_cast<void *>(&watch_readback));
-
-  if (GetWatchHi(&watch_readback, wp_index) & (IRW)) {
-    // clear hit flag in watchhi
-    SetWatchHi(&watch_readback, wp_index,
-               (GetWatchHi(&watch_readback, wp_index) & ~(IRW)));
-    DoWriteWatchPointRegisterValue(m_thread.GetID(),
-                                   static_cast<void *>(&watch_readback));
-
-    is_hit = true;
-    return error;
-  }
-  is_hit = false;
-  return error;
-}
-
-Status NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(
-    uint32_t &wp_index, lldb::addr_t trap_addr) {
-  uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
-  for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
-    bool is_hit;
-    Status error = IsWatchpointHit(wp_index, is_hit);
-    if (error.Fail()) {
-      wp_index = LLDB_INVALID_INDEX32;
-    } else if (is_hit) {
-      return error;
-    }
-  }
-  wp_index = LLDB_INVALID_INDEX32;
-  return Status();
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointVacant(uint32_t wp_index,
-                                                             bool &is_vacant) {
-  is_vacant = false;
-  return Status("MIPS TODO: "
-                "NativeRegisterContextLinux_mips64::IsWatchpointVacant not "
-                "implemented");
-}
-
-bool NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(
-    uint32_t wp_index) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return false;
-
-  struct pt_watch_regs regs;
-  // First reading the current state of watch regs
-  DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
-  if (regs.style == pt_watch_style_mips32) {
-    regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
-    regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
-    regs.mips32.watch_masks[wp_index] =
-        default_watch_regs.mips32.watch_masks[wp_index];
-  } else // pt_watch_style_mips64
-  {
-    regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
-    regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
-    regs.mips64.watch_masks[wp_index] =
-        default_watch_regs.mips64.watch_masks[wp_index];
-  }
-
-  Status error = DoWriteWatchPointRegisterValue(m_thread.GetID(),
-                                                static_cast<void *>(&regs));
-  if (!error.Fail()) {
-    hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
-    return true;
-  }
-  return false;
-}
-
-Status NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() {
-  return DoWriteWatchPointRegisterValue(
-      m_thread.GetID(), static_cast<void *>(&default_watch_regs));
-}
-
-Status NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex(
-    lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
-  Status error;
-  error.SetErrorString("MIPS TODO: "
-                       "NativeRegisterContextLinux_mips64::"
-                       "SetHardwareWatchpointWithIndex not implemented");
-  return error;
-}
-
-uint32_t NativeRegisterContextLinux_mips64::SetHardwareWatchpoint(
-    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
-  struct pt_watch_regs regs;
-
-  // First reading the current state of watch regs
-  DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
-  // Try if a new watch point fits in this state
-  int index = GetVacantWatchIndex(&regs, addr, size, watch_flags,
-                                  NumSupportedHardwareWatchpoints());
-
-  // New watchpoint doesn't fit
-  if (index == LLDB_INVALID_INDEX32)
-    return LLDB_INVALID_INDEX32;
-
-  // It fits, so we go ahead with updating the state of watch regs
-  DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
-  // Storing exact address
-  hw_addr_map[index] = addr;
-  return index;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointAddress(uint32_t wp_index) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return LLDB_INVALID_ADDRESS;
-
-  return hw_addr_map[wp_index];
-}
-
-struct EmulatorBaton {
-  lldb::addr_t m_watch_hit_addr;
-  NativeProcessLinux *m_process;
-  NativeRegisterContext *m_reg_context;
-
-  EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
-      : m_watch_hit_addr(LLDB_INVALID_ADDRESS), m_process(process),
-        m_reg_context(reg_context) {}
-};
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                 const EmulateInstruction::Context &context,
-                                 lldb::addr_t addr, void *dst, size_t length) {
-  size_t bytes_read;
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-  emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
-  return bytes_read;
-}
-
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  lldb::addr_t addr, const void *dst,
-                                  size_t length) {
-  return length;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                 const RegisterInfo *reg_info,
-                                 RegisterValue &reg_value) {
-  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
-  const RegisterInfo *full_reg_info =
-      emulator_baton->m_reg_context->GetRegisterInfo(
-          lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
-
-  Status error =
-      emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
-  if (error.Success())
-    return true;
-
-  return false;
-}
-
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
-                                  const EmulateInstruction::Context &context,
-                                  const RegisterInfo *reg_info,
-                                  const RegisterValue &reg_value) {
-  if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64) {
-    EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-    emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64();
-  }
-
-  return true;
-}
-
-/*
- * MIPS Linux kernel returns a masked address (last 3bits are masked)
- * when a HW watchpoint is hit. However user may not have set a watchpoint
- * on this address. Emulate instruction at PC and find the base address of
- * the load/store instruction. This will give the exact address used to
- * read/write the variable. Send this exact address to client so that
- * it can decide to stop or continue the thread.
-*/
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointHitAddress(uint32_t wp_index) {
-  if (wp_index >= NumSupportedHardwareWatchpoints())
-    return LLDB_INVALID_ADDRESS;
-
-  lldb_private::ArchSpec arch;
-  arch = GetRegisterInfoInterface().GetTargetArchitecture();
-  std::unique_ptr<EmulateInstruction> emulator_up(
-      EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny,
-                                     nullptr));
-
-  if (emulator_up == nullptr)
-    return LLDB_INVALID_ADDRESS;
-
-  EmulatorBaton baton(
-      static_cast<NativeProcessLinux *>(&m_thread.GetProcess()), this);
-  emulator_up->SetBaton(&baton);
-  emulator_up->SetReadMemCallback(&ReadMemoryCallback);
-  emulator_up->SetReadRegCallback(&ReadRegisterCallback);
-  emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
-  emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
-
-  if (!emulator_up->ReadInstruction())
-    return LLDB_INVALID_ADDRESS;
-
-  if (emulator_up->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
-    return baton.m_watch_hit_addr;
-
-  return LLDB_INVALID_ADDRESS;
-}
-
-uint32_t NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints() {
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-  struct pt_watch_regs regs;
-  static int num_valid = 0;
-  if (!num_valid) {
-    DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-    default_watch_regs =
-        regs; // Keeping default watch regs values for future use
-    switch (regs.style) {
-    case pt_watch_style_mips32:
-      num_valid = regs.mips32.num_valid; // Using num_valid as cache
-      return num_valid;
-    case pt_watch_style_mips64:
-      num_valid = regs.mips64.num_valid;
-      return num_valid;
-    }
-    LLDB_LOG(log, "Invalid watch register style");
-    return 0;
-  }
-  return num_valid;
-}
-
-Status
-NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
-                                                   RegisterValue &value) {
-  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
-  if (!reg_info)
-    return Status("register %" PRIu32 " not found", reg_index);
-
-  uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
-
-  if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
-    return Read_SR_Config(reg_info->byte_offset, reg_info->name,
-                          reg_info->byte_size, value);
-
-  return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
-                             value);
-}
-
-Status NativeRegisterContextLinux_mips64::WriteRegisterRaw(
-    uint32_t reg_index, const RegisterValue &value) {
-  const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
-  if (!reg_info)
-    return Status("register %" PRIu32 " not found", reg_index);
-
-  if (reg_info->invalidate_regs)
-    lldbassert(false && "reg_info->invalidate_regs is unhandled");
-
-  uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
-  return DoWriteRegisterValue(offset, reg_info->name, value);
-}
-
-Status NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
-                                                         const char *reg_name,
-                                                         uint32_t size,
-                                                         RegisterValue &value) {
-  GPR_linux_mips regs;
-  ::memset(&regs, 0, sizeof(GPR_linux_mips));
-
-  Status error = NativeProcessLinux::PtraceWrapper(
-      PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
-  if (error.Success()) {
-    const lldb_private::ArchSpec &arch =
-        m_thread.GetProcess().GetArchitecture();
-    void *target_address = ((uint8_t *)&regs) + offset +
-                           4 * (arch.GetMachine() == llvm::Triple::mips);
-    value.SetUInt(*(uint32_t *)target_address, size);
-  }
-  return error;
-}
-
-Status NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(
-    lldb::tid_t tid, void *watch_readback) {
-  return NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS,
-                                           m_thread.GetID(), watch_readback);
-}
-
-Status NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(
-    lldb::tid_t tid, void *watch_reg_value) {
-  return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS,
-                                           m_thread.GetID(), watch_reg_value);
-}
-
-#endif // defined (__mips__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
deleted file mode 100644
index 5465b84..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.h ---------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#ifndef lldb_NativeRegisterContextLinux_mips64_h
-#define lldb_NativeRegisterContextLinux_mips64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_mips.h"
-#include "Plugins/Process/Utility/lldb-mips-linux-register-enums.h"
-#include <sys/uio.h>
-
-#define MAX_NUM_WP 8
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
-public:
-  NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
-                                    NativeThreadProtocol &native_thread);
-
-  uint32_t GetRegisterSetCount() const override;
-
-  lldb::addr_t GetPCfromBreakpointLocation(
-      lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
-
-  lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
-  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
-  Status ReadRegister(const RegisterInfo *reg_info,
-                      RegisterValue &reg_value) override;
-
-  Status WriteRegister(const RegisterInfo *reg_info,
-                       const RegisterValue &reg_value) override;
-
-  Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
-  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
-  Status ReadCP1();
-
-  Status WriteCP1();
-
-  uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
-
-  Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
-  Status GetWatchpointHitIndex(uint32_t &wp_index,
-                               lldb::addr_t trap_addr) override;
-
-  Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
-  bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
-  Status ClearAllHardwareWatchpoints() override;
-
-  Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
-                                        uint32_t watch_flags,
-                                        uint32_t wp_index);
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
-                                 uint32_t watch_flags) override;
-
-  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-  static bool IsMSAAvailable();
-
-protected:
-  Status Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
-                        RegisterValue &value);
-
-  Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
-
-  Status WriteRegisterRaw(uint32_t reg_index,
-                          const RegisterValue &value) override;
-
-  Status DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
-  Status DoWriteWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
-  bool IsFR0();
-
-  bool IsFRE();
-
-  bool IsFPR(uint32_t reg_index) const;
-
-  bool IsMSA(uint32_t reg_index) const;
-
-  void *GetGPRBuffer() override { return &m_gpr; }
-
-  void *GetFPRBuffer() override { return &m_fpr; }
-
-  size_t GetFPRSize() override { return sizeof(FPR_linux_mips); }
-
-private:
-  // Info about register ranges.
-  struct RegInfo {
-    uint32_t num_registers;
-    uint32_t num_gpr_registers;
-    uint32_t num_fpr_registers;
-
-    uint32_t last_gpr;
-    uint32_t first_fpr;
-    uint32_t last_fpr;
-    uint32_t first_msa;
-    uint32_t last_msa;
-  };
-
-  RegInfo m_reg_info;
-
-  GPR_linux_mips m_gpr;
-
-  FPR_linux_mips m_fpr;
-
-  MSA_linux_mips m_msa;
-
-  lldb::addr_t hw_addr_map[MAX_NUM_WP];
-
-  struct iovec m_iovec;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_mips64_h
-
-#endif // defined (__mips__)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
index 22acbda..60582e4 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -115,7 +115,7 @@
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
   switch (target_arch.GetMachine()) {
   case llvm::Triple::ppc64le:
     return std::make_unique<NativeRegisterContextLinux_ppc64le>(target_arch,
@@ -128,7 +128,8 @@
 NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
-          native_thread, new RegisterInfoPOSIX_ppc64le(target_arch)) {
+          native_thread, new RegisterInfoPOSIX_ppc64le(target_arch)),
+      NativeRegisterContextLinux(native_thread) {
   if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
     llvm_unreachable("Unhandled target architecture.");
   }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index 098aa34..3c09164 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -93,7 +93,7 @@
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
   return std::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
                                                              native_thread);
 }
@@ -110,7 +110,8 @@
 NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
-          native_thread, CreateRegisterInfoInterface(target_arch)) {
+          native_thread, CreateRegisterInfoInterface(target_arch)),
+      NativeRegisterContextLinux(native_thread) {
   // Set up data about ranges of valid registers.
   switch (target_arch.GetMachine()) {
   case llvm::Triple::systemz:
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index c6aa320..bd4b168 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -10,14 +10,14 @@
 
 #include "NativeRegisterContextLinux_x86_64.h"
 
+#include "Plugins/Process/Linux/NativeThreadLinux.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
 #include <cpuid.h>
 #include <linux/elf.h>
 
@@ -250,7 +250,7 @@
 
 std::unique_ptr<NativeRegisterContextLinux>
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+    const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
   return std::unique_ptr<NativeRegisterContextLinux>(
       new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
 }
@@ -292,6 +292,8 @@
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
           native_thread, CreateRegisterInfoInterface(target_arch)),
+      NativeRegisterContextLinux(native_thread),
+      NativeRegisterContextDBReg_x86(native_thread),
       m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
       m_reg_info(), m_gpr_x86_64() {
   // Set up data about ranges of valid registers.
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index 82270dd..8287e49 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -12,7 +12,7 @@
 #define lldb_NativeRegisterContextLinux_x86_64_h
 
 #include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 #include <sys/uio.h>
@@ -24,7 +24,7 @@
 
 class NativeRegisterContextLinux_x86_64
     : public NativeRegisterContextLinux,
-      public NativeRegisterContextWatchpoint_x86 {
+      public NativeRegisterContextDBReg_x86 {
 public:
   NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
                                     NativeThreadProtocol &native_thread);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 5aec98b..a7e4e9b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -8,7 +8,7 @@
 
 #include "NativeThreadLinux.h"
 
-#include <signal.h>
+#include <csignal>
 #include <sstream>
 
 #include "NativeProcessLinux.h"
@@ -26,6 +26,7 @@
 #include "llvm/ADT/SmallString.h"
 
 #include "Plugins/Process/POSIX/CrashReason.h"
+#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
 
 #include <sys/syscall.h>
 // Try to define a macro to encapsulate the tgkill syscall
@@ -77,6 +78,9 @@
   case eStopReasonInstrumentation:
     log.Printf("%s: %s instrumentation", __FUNCTION__, header);
     return;
+  case eStopReasonProcessorTrace:
+    log.Printf("%s: %s processor trace", __FUNCTION__, header);
+    return;
   default:
     log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
                static_cast<uint32_t>(stop_info.reason));
@@ -296,11 +300,69 @@
               ? CrashReason::eInvalidAddress
               : GetCrashReason(*info);
       m_stop_description = GetCrashReasonString(reason, *info);
+
+      if (reason == CrashReason::eSyncTagCheckFault) {
+        AnnotateSyncTagCheckFault(info);
+      }
+
       break;
     }
   }
 }
 
+void NativeThreadLinux::AnnotateSyncTagCheckFault(const siginfo_t *info) {
+  int32_t allocation_tag_type = 0;
+  switch (GetProcess().GetArchitecture().GetMachine()) {
+  // aarch64_32 deliberately not here because there's no 32 bit MTE
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+    allocation_tag_type = MemoryTagManagerAArch64MTE::eMTE_allocation;
+    break;
+  default:
+    return;
+  }
+
+  auto details =
+      GetRegisterContext().GetMemoryTaggingDetails(allocation_tag_type);
+  if (!details) {
+    llvm::consumeError(details.takeError());
+    return;
+  }
+
+  // We assume that the stop description is currently:
+  // signal SIGSEGV: sync tag check fault (fault address: <addr>)
+  // Remove the closing )
+  m_stop_description.pop_back();
+
+  std::stringstream ss;
+  lldb::addr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr);
+  std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
+
+  ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr);
+
+  std::vector<uint8_t> allocation_tag_data;
+  // The fault address may not be granule aligned. ReadMemoryTags will granule
+  // align any range you give it, potentially making it larger.
+  // To prevent this set len to 1. This always results in a range that is at
+  // most 1 granule in size and includes fault_addr.
+  Status status = GetProcess().ReadMemoryTags(allocation_tag_type, fault_addr,
+                                              1, allocation_tag_data);
+
+  if (status.Success()) {
+    llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
+        manager->UnpackTagsData(allocation_tag_data, 1);
+    if (allocation_tag) {
+      ss << " allocation tag: 0x" << std::hex << allocation_tag->front() << ")";
+    } else {
+      llvm::consumeError(allocation_tag.takeError());
+      ss << ")";
+    }
+  } else
+    ss << ")";
+
+  m_stop_description += ss.str();
+}
+
 bool NativeThreadLinux::IsStopped(int *signo) {
   if (!StateIsStoppedState(m_state, false))
     return false;
@@ -391,6 +453,21 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadLinux::SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid) {
+  SetStopped();
+
+  m_stop_info.reason =
+      is_vfork ? StopReason::eStopReasonVFork : StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_pid;
+}
+
+void NativeThreadLinux::SetStoppedByVForkDone() {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
 void NativeThreadLinux::SetStoppedWithNoReason() {
   SetStopped();
 
@@ -398,6 +475,15 @@
   m_stop_info.details.signal.signo = 0;
 }
 
+void NativeThreadLinux::SetStoppedByProcessorTrace(
+    llvm::StringRef description) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonProcessorTrace;
+  m_stop_info.details.signal.signo = 0;
+  m_stop_description = description.str();
+}
+
 void NativeThreadLinux::SetExited() {
   const StateType new_state = StateType::eStateExited;
   MaybeLogStateChange(new_state);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
index fd43c89..c18665b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -14,6 +14,8 @@
 #include "lldb/Host/common/NativeThreadProtocol.h"
 #include "lldb/lldb-private-forward.h"
 
+#include "llvm/ADT/StringRef.h"
+
 #include <csignal>
 #include <map>
 #include <memory>
@@ -51,6 +53,8 @@
 
   Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
 
+  NativeProcessLinux &GetProcess();
+
 private:
   // Interface for friend classes
 
@@ -81,8 +85,14 @@
 
   void SetStoppedByTrace();
 
+  void SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid);
+
+  void SetStoppedByVForkDone();
+
   void SetStoppedWithNoReason();
 
+  void SetStoppedByProcessorTrace(llvm::StringRef description);
+
   void SetExited();
 
   Status RequestStop();
@@ -90,10 +100,13 @@
   // Private interface
   void MaybeLogStateChange(lldb::StateType new_state);
 
-  NativeProcessLinux &GetProcess();
-
   void SetStopped();
 
+  /// Extend m_stop_description with logical and allocation tag values.
+  /// If there is an error along the way just add the information we were able
+  /// to get.
+  void AnnotateSyncTagCheckFault(const siginfo_t *info);
+
   // Member Variables
   lldb::StateType m_state;
   ThreadStopInfo m_stop_info;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
deleted file mode 100644
index 1a8aa36..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-//===-- ProcessorTrace.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 <algorithm>
-#include <fstream>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "ProcessorTrace.h"
-#include "lldb/Host/linux/Support.h"
-
-#include <sys/ioctl.h>
-#include <sys/syscall.h>
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace process_linux;
-using namespace llvm;
-
-lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1;
-const char *kOSEventIntelPTTypeFile =
-    "/sys/bus/event_source/devices/intel_pt/type";
-
-Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  Status error;
-
-  config.setType(lldb::TraceType::eTraceTypeProcessorTrace);
-  config.setMetaDataBufferSize(m_mmap_meta->data_size);
-
-  config.setTraceBufferSize(m_mmap_meta->aux_size);
-
-  error = GetCPUType(config);
-
-  return error;
-#endif
-}
-
-Expected<uint32_t> ProcessorTraceMonitor::GetOSEventType() {
-  auto intel_pt_type_text =
-      llvm::MemoryBuffer::getFileAsStream(kOSEventIntelPTTypeFile);
-
-  if (!intel_pt_type_text)
-    return createStringError(inconvertibleErrorCode(),
-                             "Can't open the file '%s'",
-                             kOSEventIntelPTTypeFile);
-
-  uint32_t intel_pt_type = 0;
-  StringRef buffer = intel_pt_type_text.get()->getBuffer();
-  if (buffer.trim().getAsInteger(10, intel_pt_type))
-    return createStringError(
-        inconvertibleErrorCode(),
-        "The file '%s' has a invalid value. It should be an unsigned int.",
-        kOSEventIntelPTTypeFile);
-  return intel_pt_type;
-}
-
-bool ProcessorTraceMonitor::IsSupported() { return (bool)GetOSEventType(); }
-
-Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
-                                         const TraceOptions &config) {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  Status error;
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  LLDB_LOG(log, "called thread id {0}", tid);
-  uint64_t page_size = getpagesize();
-  uint64_t bufsize = config.getTraceBufferSize();
-  uint64_t metabufsize = config.getMetaDataBufferSize();
-
-  uint64_t numpages = static_cast<uint64_t>(
-      llvm::PowerOf2Floor((bufsize + page_size - 1) / page_size));
-  numpages = std::max<uint64_t>(1, numpages);
-  bufsize = page_size * numpages;
-
-  numpages = static_cast<uint64_t>(
-      llvm::PowerOf2Floor((metabufsize + page_size - 1) / page_size));
-  metabufsize = page_size * numpages;
-
-  perf_event_attr attr;
-  memset(&attr, 0, sizeof(attr));
-  attr.size = sizeof(attr);
-  attr.exclude_kernel = 1;
-  attr.sample_type = PERF_SAMPLE_TIME;
-  attr.sample_id_all = 1;
-  attr.exclude_hv = 1;
-  attr.exclude_idle = 1;
-  attr.mmap = 1;
-
-  Expected<uint32_t> intel_pt_type = GetOSEventType();
-
-  if (!intel_pt_type) {
-    error = intel_pt_type.takeError();
-    return error;
-  }
-
-  LLDB_LOG(log, "intel pt type {0}", *intel_pt_type);
-  attr.type = *intel_pt_type;
-
-  LLDB_LOG(log, "meta buffer size {0}", metabufsize);
-  LLDB_LOG(log, "buffer size {0} ", bufsize);
-
-  if (error.Fail()) {
-    LLDB_LOG(log, "Status in custom config");
-
-    return error;
-  }
-
-  errno = 0;
-  auto fd =
-      syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0);
-  if (fd == -1) {
-    LLDB_LOG(log, "syscall error {0}", errno);
-    error.SetErrorString("perf event syscall Failed");
-    return error;
-  }
-
-  m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());
-
-  errno = 0;
-  auto base =
-      mmap(nullptr, (metabufsize + page_size), PROT_WRITE, MAP_SHARED, fd, 0);
-
-  if (base == MAP_FAILED) {
-    LLDB_LOG(log, "mmap base error {0}", errno);
-    error.SetErrorString("Meta buffer allocation failed");
-    return error;
-  }
-
-  m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
-      reinterpret_cast<perf_event_mmap_page *>(base),
-      munmap_delete(metabufsize + page_size));
-
-  m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
-  m_mmap_meta->aux_size = bufsize;
-
-  errno = 0;
-  auto mmap_aux = mmap(nullptr, bufsize, PROT_READ, MAP_SHARED, fd,
-                       static_cast<long int>(m_mmap_meta->aux_offset));
-
-  if (mmap_aux == MAP_FAILED) {
-    LLDB_LOG(log, "second mmap done {0}", errno);
-    error.SetErrorString("Trace buffer allocation failed");
-    return error;
-  }
-  m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
-      reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize));
-  return error;
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetDataBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  return MutableArrayRef<uint8_t>(
-      (reinterpret_cast<uint8_t *>(m_mmap_meta.get()) +
-       m_mmap_meta->data_offset),
-      m_mmap_meta->data_size);
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetAuxBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  return MutableArrayRef<uint8_t>(m_mmap_aux.get(), m_mmap_meta->aux_size);
-#endif
-}
-
-Status ProcessorTraceMonitor::GetCPUType(TraceOptions &config) {
-
-  Status error;
-  uint64_t cpu_family = -1;
-  uint64_t model = -1;
-  uint64_t stepping = -1;
-  std::string vendor_id;
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  auto BufferOrError = getProcFile("cpuinfo");
-  if (!BufferOrError)
-    return BufferOrError.getError();
-
-  LLDB_LOG(log, "GetCPUType Function");
-
-  StringRef Rest = BufferOrError.get()->getBuffer();
-  while (!Rest.empty()) {
-    StringRef Line;
-    std::tie(Line, Rest) = Rest.split('\n');
-
-    SmallVector<StringRef, 2> columns;
-    Line.split(columns, StringRef(":"), -1, false);
-
-    if (columns.size() < 2)
-      continue; // continue searching
-
-    columns[1] = columns[1].trim(" ");
-    if (columns[0].contains("cpu family") &&
-        columns[1].getAsInteger(10, cpu_family))
-      continue;
-
-    else if (columns[0].contains("model") && columns[1].getAsInteger(10, model))
-      continue;
-
-    else if (columns[0].contains("stepping") &&
-             columns[1].getAsInteger(10, stepping))
-      continue;
-
-    else if (columns[0].contains("vendor_id")) {
-      vendor_id = columns[1].str();
-      if (!vendor_id.empty())
-        continue;
-    }
-    LLDB_LOG(log, "{0}:{1}:{2}:{3}", cpu_family, model, stepping, vendor_id);
-
-    if ((cpu_family != static_cast<uint64_t>(-1)) &&
-        (model != static_cast<uint64_t>(-1)) &&
-        (stepping != static_cast<uint64_t>(-1)) && (!vendor_id.empty())) {
-      auto params_dict = std::make_shared<StructuredData::Dictionary>();
-      params_dict->AddIntegerItem("cpu_family", cpu_family);
-      params_dict->AddIntegerItem("cpu_model", model);
-      params_dict->AddIntegerItem("cpu_stepping", stepping);
-      params_dict->AddStringItem("cpu_vendor", vendor_id);
-
-      llvm::StringRef intel_custom_params_key("intel-pt");
-
-      auto intel_custom_params = std::make_shared<StructuredData::Dictionary>();
-      intel_custom_params->AddItem(
-          intel_custom_params_key,
-          StructuredData::ObjectSP(std::move(params_dict)));
-
-      config.setTraceParams(intel_custom_params);
-      return error; // we are done
-    }
-  }
-
-  error.SetErrorString("cpu info not found");
-  return error;
-}
-
-llvm::Expected<ProcessorTraceMonitorUP>
-ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
-                              const TraceOptions &config,
-                              bool useProcessSettings) {
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  Status error;
-  if (tid == LLDB_INVALID_THREAD_ID) {
-    error.SetErrorString("thread not specified");
-    return error.ToError();
-  }
-
-  ProcessorTraceMonitorUP pt_monitor_up(new ProcessorTraceMonitor);
-
-  error = pt_monitor_up->StartTrace(pid, tid, config);
-  if (error.Fail())
-    return error.ToError();
-
-  pt_monitor_up->SetThreadID(tid);
-
-  if (useProcessSettings) {
-    pt_monitor_up->SetTraceID(0);
-  } else {
-    pt_monitor_up->SetTraceID(m_trace_num++);
-    LLDB_LOG(log, "Trace ID {0}", m_trace_num);
-  }
-  return std::move(pt_monitor_up);
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
-                                        size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  // Disable the perf event to force a flush out of the CPU's internal buffer.
-  // Besides, we can guarantee that the CPU won't override any data as we are
-  // reading the buffer.
-  //
-  // The Intel documentation says:
-  //
-  // Packets are first buffered internally and then written out asynchronously.
-  // To collect packet output for postprocessing, a collector needs first to
-  // ensure that all packet data has been flushed from internal buffers.
-  // Software can ensure this by stopping packet generation by clearing
-  // IA32_RTIT_CTL.TraceEn (see “Disabling Packet Generation” in
-  // Section 35.2.7.2).
-  //
-  // This is achieved by the PERF_EVENT_IOC_DISABLE ioctl request, as mentioned
-  // in the man page of perf_event_open.
-  ioctl(*m_fd, PERF_EVENT_IOC_DISABLE);
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  Status error;
-  uint64_t head = m_mmap_meta->aux_head;
-
-  LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);
-
-  /**
-   * When configured as ring buffer, the aux buffer keeps wrapping around
-   * the buffer and its not possible to detect how many times the buffer
-   * wrapped. Initially the buffer is filled with zeros,as shown below
-   * so in order to get complete buffer we first copy firstpartsize, followed
-   * by any left over part from beginning to aux_head
-   *
-   * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size
-   *                 aux_head->||<- firstpartsize  ->|
-   *
-   * */
-
-  ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast<size_t>(head), offset);
-  LLDB_LOG(log, "ReadCyclic BUffer Done");
-
-  // Reenable tracing now we have read the buffer
-  ioctl(*m_fd, PERF_EVENT_IOC_ENABLE);
-  return error;
-#endif
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
-                                         size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
-  llvm_unreachable("perf event not supported");
-#else
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-  uint64_t bytes_remaining = buffer.size();
-  Status error;
-
-  uint64_t head = m_mmap_meta->data_head;
-
-  /*
-   * The data buffer and aux buffer have different implementations
-   * with respect to their definition of head pointer. In the case
-   * of Aux data buffer the head always wraps around the aux buffer
-   * and we don't need to care about it, whereas the data_head keeps
-   * increasing and needs to be wrapped by modulus operator
-   */
-
-  LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining);
-
-  auto data_buffer = GetDataBuffer();
-
-  if (head > data_buffer.size()) {
-    head = head % data_buffer.size();
-    LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head);
-
-    ReadCyclicBuffer(buffer, data_buffer, static_cast<size_t>(head), offset);
-    bytes_remaining -= buffer.size();
-  } else {
-    LLDB_LOG(log, "Head - {0}", head);
-    if (offset >= head) {
-      LLDB_LOG(log, "Invalid Offset ");
-      error.SetErrorString("invalid offset");
-      buffer = buffer.slice(buffer.size());
-      return error;
-    }
-
-    auto data = data_buffer.slice(offset, (head - offset));
-    auto remaining = std::copy(data.begin(), data.end(), buffer.begin());
-    bytes_remaining -= (remaining - buffer.begin());
-  }
-  buffer = buffer.drop_back(bytes_remaining);
-  return error;
-#endif
-}
-
-void ProcessorTraceMonitor::ReadCyclicBuffer(
-    llvm::MutableArrayRef<uint8_t> &dst, llvm::MutableArrayRef<uint8_t> src,
-    size_t src_cyc_index, size_t offset) {
-
-  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
-  if (dst.empty() || src.empty()) {
-    dst = dst.drop_back(dst.size());
-    return;
-  }
-
-  if (dst.data() == nullptr || src.data() == nullptr) {
-    dst = dst.drop_back(dst.size());
-    return;
-  }
-
-  if (src_cyc_index > src.size()) {
-    dst = dst.drop_back(dst.size());
-    return;
-  }
-
-  if (offset >= src.size()) {
-    LLDB_LOG(log, "Too Big offset ");
-    dst = dst.drop_back(dst.size());
-    return;
-  }
-
-  llvm::SmallVector<MutableArrayRef<uint8_t>, 2> parts = {
-      src.slice(src_cyc_index), src.take_front(src_cyc_index)};
-
-  if (offset > parts[0].size()) {
-    parts[1] = parts[1].slice(offset - parts[0].size());
-    parts[0] = parts[0].drop_back(parts[0].size());
-  } else if (offset == parts[0].size()) {
-    parts[0] = parts[0].drop_back(parts[0].size());
-  } else {
-    parts[0] = parts[0].slice(offset);
-  }
-  auto next = dst.begin();
-  auto bytes_left = dst.size();
-  for (auto part : parts) {
-    size_t chunk_size = std::min(part.size(), bytes_left);
-    next = std::copy_n(part.begin(), chunk_size, next);
-    bytes_left -= chunk_size;
-  }
-  dst = dst.drop_back(bytes_left);
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.h b/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.h
deleted file mode 100644
index 29f98cc..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/ProcessorTrace.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- ProcessorTrace.h -------------------------------------- -*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessorTrace_H_
-#define liblldb_ProcessorTrace_H_
-
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/TraceOptions.h"
-#include "lldb/lldb-types.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-
-#include <linux/perf_event.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-namespace lldb_private {
-
-namespace process_linux {
-
-// This class keeps track of one tracing instance of
-// Intel(R) Processor Trace on Linux OS. There is a map keeping track
-// of different tracing instances on each thread, which enables trace
-// gathering on a per thread level.
-//
-// The tracing instance is linked with a trace id. The trace id acts like
-// a key to the tracing instance and trace manipulations could be
-// performed using the trace id.
-//
-// The trace id could map to trace instances for a group of threads
-// (spanning to all the threads in the process) or a single thread.
-// The kernel interface for us is the perf_event_open.
-
-class ProcessorTraceMonitor;
-typedef std::unique_ptr<ProcessorTraceMonitor> ProcessorTraceMonitorUP;
-
-class ProcessorTraceMonitor {
-
-  class munmap_delete {
-    size_t m_length;
-
-  public:
-    munmap_delete(size_t length) : m_length(length) {}
-    void operator()(void *ptr) {
-      if (m_length)
-        munmap(ptr, m_length);
-    }
-  };
-
-  class file_close {
-
-  public:
-    file_close() = default;
-    void operator()(int *ptr) {
-      if (ptr == nullptr)
-        return;
-      if (*ptr == -1)
-        return;
-      close(*ptr);
-      std::default_delete<int>()(ptr);
-    }
-  };
-
-  std::unique_ptr<perf_event_mmap_page, munmap_delete> m_mmap_meta;
-  std::unique_ptr<uint8_t, munmap_delete> m_mmap_aux;
-  std::unique_ptr<int, file_close> m_fd;
-
-  // perf_event_mmap_page *m_mmap_base;
-  lldb::user_id_t m_traceid;
-  lldb::tid_t m_thread_id;
-
-  // Counter to track trace instances.
-  static lldb::user_id_t m_trace_num;
-
-  void SetTraceID(lldb::user_id_t traceid) { m_traceid = traceid; }
-
-  Status StartTrace(lldb::pid_t pid, lldb::tid_t tid,
-                    const TraceOptions &config);
-
-  llvm::MutableArrayRef<uint8_t> GetAuxBuffer();
-  llvm::MutableArrayRef<uint8_t> GetDataBuffer();
-
-  ProcessorTraceMonitor()
-      : m_mmap_meta(nullptr, munmap_delete(0)),
-        m_mmap_aux(nullptr, munmap_delete(0)), m_fd(nullptr, file_close()),
-        m_traceid(LLDB_INVALID_UID), m_thread_id(LLDB_INVALID_THREAD_ID){};
-
-  void SetThreadID(lldb::tid_t tid) { m_thread_id = tid; }
-
-public:
-  static llvm::Expected<uint32_t> GetOSEventType();
-
-  static bool IsSupported();
-
-  static Status GetCPUType(TraceOptions &config);
-
-  static llvm::Expected<ProcessorTraceMonitorUP>
-  Create(lldb::pid_t pid, lldb::tid_t tid, const TraceOptions &config,
-         bool useProcessSettings);
-
-  Status ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
-                          size_t offset = 0);
-
-  Status ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
-                           size_t offset = 0);
-
-  ~ProcessorTraceMonitor() = default;
-
-  lldb::tid_t GetThreadID() const { return m_thread_id; }
-
-  lldb::user_id_t GetTraceID() const { return m_traceid; }
-
-  Status GetTraceConfig(TraceOptions &config) const;
-
-  /// Read data from a cyclic buffer
-  ///
-  /// \param[in] [out] buf
-  ///     Destination buffer, the buffer will be truncated to written size.
-  ///
-  /// \param[in] src
-  ///     Source buffer which must be a cyclic buffer.
-  ///
-  /// \param[in] src_cyc_index
-  ///     The index pointer (start of the valid data in the cyclic
-  ///     buffer).
-  ///
-  /// \param[in] offset
-  ///     The offset to begin reading the data in the cyclic buffer.
-  static void ReadCyclicBuffer(llvm::MutableArrayRef<uint8_t> &dst,
-                               llvm::MutableArrayRef<uint8_t> src,
-                               size_t src_cyc_index, size_t offset);
-};
-} // namespace process_linux
-} // namespace lldb_private
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp b/src/llvm-project/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp
index f0c6bdc..5b337f1 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Linux/SingleStepCheck.cpp
@@ -8,8 +8,8 @@
 
 #include "SingleStepCheck.h"
 
+#include <csignal>
 #include <sched.h>
-#include <signal.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index fc0539a..d397d16 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -8,10 +8,9 @@
 
 #include "CommunicationKDP.h"
 
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-
+#include <cerrno>
+#include <climits>
+#include <cstring>
 
 #include "lldb/Core/DumpDataExtractor.h"
 #include "lldb/Host/Host.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 913c889..47b2f8d 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <errno.h>
-#include <stdlib.h>
+#include <cerrno>
+#include <cstdlib>
 
 #include <memory>
 #include <mutex>
@@ -73,7 +73,7 @@
     m_collection_sp->Initialize(g_processkdp_properties);
   }
 
-  virtual ~PluginProperties() {}
+  virtual ~PluginProperties() = default;
 
   uint64_t GetPacketTimeout() {
     const uint32_t idx = ePropertyKDPPacketTimeout;
@@ -902,7 +902,7 @@
     m_option_group.Finalize();
   }
 
-  ~CommandObjectProcessKDPPacketSend() {}
+  ~CommandObjectProcessKDPPacketSend() = default;
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     const size_t argc = command.GetArgumentCount();
@@ -910,7 +910,6 @@
       if (!m_command_byte.GetOptionValue().OptionWasSet()) {
         result.AppendError(
             "the --command option must be set to a valid command byte");
-        result.SetStatus(eReturnStatusFailed);
       } else {
         const uint64_t command_byte =
             m_command_byte.GetOptionValue().GetUInt64Value(0);
@@ -933,7 +932,6 @@
                                                "even number of ASCII hex "
                                                "characters: '%s'",
                                                ascii_hex_bytes_cstr);
-                  result.SetStatus(eReturnStatusFailed);
                   return false;
                 }
                 payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
@@ -943,7 +941,6 @@
                                                "ASCII hex characters (no "
                                                "spaces or hex prefixes): '%s'",
                                                ascii_hex_bytes_cstr);
-                  result.SetStatus(eReturnStatusFailed);
                   return false;
                 }
               }
@@ -970,30 +967,25 @@
                 else
                   result.AppendErrorWithFormat("unknown error 0x%8.8x",
                                                error.GetError());
-                result.SetStatus(eReturnStatusFailed);
                 return false;
               }
             } else {
               result.AppendErrorWithFormat("process must be stopped in order "
                                            "to send KDP packets, state is %s",
                                            StateAsCString(state));
-              result.SetStatus(eReturnStatusFailed);
             }
           } else {
             result.AppendError("invalid process");
-            result.SetStatus(eReturnStatusFailed);
           }
         } else {
           result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
                                        ", valid values are 1 - 255",
                                        command_byte);
-          result.SetStatus(eReturnStatusFailed);
         }
       }
     } else {
       result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
     }
     return false;
   }
@@ -1011,7 +1003,7 @@
         CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
   }
 
-  ~CommandObjectProcessKDPPacket() {}
+  ~CommandObjectProcessKDPPacket() = default;
 };
 
 class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
@@ -1025,7 +1017,7 @@
                                  interpreter)));
   }
 
-  ~CommandObjectMultiwordProcessKDP() {}
+  ~CommandObjectMultiwordProcessKDP() = default;
 };
 
 CommandObject *ProcessKDP::GetPluginCommandObject() {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index 81b602a..64f0caa 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -19,7 +19,7 @@
     : RegisterContextDarwin_arm(thread, concrete_frame_idx),
       m_kdp_thread(thread) {}
 
-RegisterContextKDP_arm::~RegisterContextKDP_arm() {}
+RegisterContextKDP_arm::~RegisterContextKDP_arm() = default;
 
 int RegisterContextKDP_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
   ProcessSP process_sp(CalculateProcess());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
index c5e7109..c56356d 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
@@ -19,7 +19,7 @@
     : RegisterContextDarwin_arm64(thread, concrete_frame_idx),
       m_kdp_thread(thread) {}
 
-RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
+RegisterContextKDP_arm64::~RegisterContextKDP_arm64() = default;
 
 int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
   ProcessSP process_sp(CalculateProcess());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index aa46e46..61dfeae 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -18,7 +18,7 @@
     : RegisterContextDarwin_i386(thread, concrete_frame_idx),
       m_kdp_thread(thread) {}
 
-RegisterContextKDP_i386::~RegisterContextKDP_i386() {}
+RegisterContextKDP_i386::~RegisterContextKDP_i386() = default;
 
 int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
   ProcessSP process_sp(CalculateProcess());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
index 565dd1c..9c47c22 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
@@ -18,7 +18,7 @@
     : RegisterContextDarwin_x86_64(thread, concrete_frame_idx),
       m_kdp_thread(thread) {}
 
-RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() {}
+RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() = default;
 
 int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
                                          GPR &gpr) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 57f0eb3..9ea1a16 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -133,13 +133,20 @@
   return std::move(process_up);
 }
 
+NativeProcessNetBSD::Extension
+NativeProcessNetBSD::Factory::GetSupportedExtensions() const {
+  return Extension::multiprocess | Extension::fork | Extension::vfork |
+         Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+}
+
 // Public Instance Methods
 
 NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
                                          NativeDelegate &delegate,
                                          const ArchSpec &arch,
                                          MainLoop &mainloop)
-    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch) {
+    : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
+      m_main_loop(mainloop) {
   if (m_terminal_fd != -1) {
     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
     assert(status.Success());
@@ -256,6 +263,33 @@
     SetState(StateType::eStateStopped, true);
     return;
   }
+  case TRAP_CHLD: {
+    ptrace_state_t pst;
+    Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
+    if (error.Fail()) {
+      SetState(StateType::eStateInvalid);
+      return;
+    }
+
+    assert(thread);
+    if (pst.pe_report_event == PTRACE_VFORK_DONE) {
+      if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
+        thread->SetStoppedByVForkDone();
+        SetState(StateType::eStateStopped, true);
+      } else {
+        Status error =
+            PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+        if (error.Fail())
+          SetState(StateType::eStateInvalid);
+      }
+    } else {
+      assert(pst.pe_report_event == PTRACE_FORK ||
+             pst.pe_report_event == PTRACE_VFORK);
+      MonitorClone(pst.pe_other_pid, pst.pe_report_event == PTRACE_VFORK,
+                   *thread);
+    }
+    return;
+  }
   case TRAP_LWP: {
     ptrace_state_t pst;
     Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
@@ -510,7 +544,7 @@
   if (GetID() == LLDB_INVALID_PROCESS_ID)
     return error;
 
-  return PtraceWrapper(PT_DETACH, GetID());
+  return PtraceWrapper(PT_DETACH, GetID(), reinterpret_cast<void *>(1));
 }
 
 Status NativeProcessNetBSD::Signal(int signo) {
@@ -738,17 +772,17 @@
 
 void NativeProcessNetBSD::SigchldHandler() {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-  // Process all pending waitpid notifications.
   int status;
   ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status,
                                                  WALLSIG | WNOHANG);
 
   if (wait_pid == 0)
-    return; // We are done.
+    return;
 
   if (wait_pid == -1) {
     Status error(errno, eErrorTypePOSIX);
     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
+    return;
   }
 
   WaitStatus wait_status = WaitStatus::Decode(status);
@@ -936,8 +970,9 @@
       PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
-  // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
-  events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
+  // TODO: PTRACE_POSIX_SPAWN?
+  events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT | PTRACE_FORK |
+                         PTRACE_VFORK | PTRACE_VFORK_DONE;
   status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
   if (status.Fail())
     return status;
@@ -974,3 +1009,67 @@
 
   return error;
 }
+
+void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
+                                       NativeThreadNetBSD &parent_thread) {
+  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+  LLDB_LOG(log, "clone, child_pid={0}", child_pid);
+
+  int status;
+  ::pid_t wait_pid =
+      llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
+  if (wait_pid != child_pid) {
+    LLDB_LOG(log,
+             "waiting for pid {0} failed. Assuming the pid has "
+             "disappeared in the meantime",
+             child_pid);
+    return;
+  }
+  if (WIFEXITED(status)) {
+    LLDB_LOG(log,
+             "waiting for pid {0} returned an 'exited' event. Not "
+             "tracking it.",
+             child_pid);
+    return;
+  }
+
+  ptrace_siginfo_t info;
+  const auto siginfo_err =
+      PtraceWrapper(PT_GET_SIGINFO, child_pid, &info, sizeof(info));
+  if (siginfo_err.Fail()) {
+    LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err);
+    return;
+  }
+  assert(info.psi_lwpid >= 0);
+  lldb::tid_t child_tid = info.psi_lwpid;
+
+  std::unique_ptr<NativeProcessNetBSD> child_process{
+      new NativeProcessNetBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
+                              m_delegate, m_arch, m_main_loop)};
+  if (!is_vfork)
+    child_process->m_software_breakpoints = m_software_breakpoints;
+
+  Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
+  if ((m_enabled_extensions & expected_ext) == expected_ext) {
+    child_process->SetupTrace();
+    for (const auto &thread : child_process->m_threads)
+      static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
+    child_process->SetState(StateType::eStateStopped, false);
+
+    m_delegate.NewSubprocess(this, std::move(child_process));
+    if (is_vfork)
+      parent_thread.SetStoppedByVFork(child_pid, child_tid);
+    else
+      parent_thread.SetStoppedByFork(child_pid, child_tid);
+    SetState(StateType::eStateStopped, true);
+  } else {
+    child_process->Detach();
+    Status pt_error =
+        PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
+    if (pt_error.Fail()) {
+      LLDB_LOG_ERROR(log, std::move(pt_error.ToError()),
+                     "unable to resume parent process {1}: {0}", GetID());
+      SetState(StateType::eStateInvalid);
+    }
+  }
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 3d59a4f..90d32aa 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -36,6 +36,8 @@
     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
            MainLoop &mainloop) const override;
+
+    Extension GetSupportedExtensions() const override;
   };
 
   // NativeProcessProtocol Interface
@@ -89,6 +91,7 @@
 private:
   MainLoop::SignalHandleUP m_sigchld_handle;
   ArchSpec m_arch;
+  MainLoop& m_main_loop;
   LazyBool m_supports_mem_region = eLazyBoolCalculate;
   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 
@@ -106,6 +109,8 @@
   void MonitorSIGSTOP(lldb::pid_t pid);
   void MonitorSIGTRAP(lldb::pid_t pid);
   void MonitorSignal(lldb::pid_t pid, int signal);
+  void MonitorClone(::pid_t child_pid, bool is_vfork,
+                    NativeThreadNetBSD &parent_thread);
 
   Status PopulateMemoryRegionCache();
   void SigchldHandler();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index ed1884c..3d164ea 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -29,8 +29,8 @@
 #include <x86/specialreg.h>
 #include <elf.h>
 #include <err.h>
-#include <stdint.h>
-#include <stdlib.h>
+#include <cstdint>
+#include <cstdlib>
 // clang-format on
 
 using namespace lldb_private;
@@ -267,7 +267,7 @@
     const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
     : NativeRegisterContextRegisterInfo(
           native_thread, CreateRegisterInfoInterface(target_arch)),
-      m_regset_offsets({0}) {
+      NativeRegisterContextDBReg_x86(native_thread), m_regset_offsets({0}) {
   assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize());
   std::array<uint32_t, MaxRegularRegSet + 1> first_regnos;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index d20fd67..3100595 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -22,7 +22,7 @@
 
 #include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h"
 #include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h"
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h"
 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 
 namespace lldb_private {
@@ -32,7 +32,7 @@
 
 class NativeRegisterContextNetBSD_x86_64
     : public NativeRegisterContextNetBSD,
-      public NativeRegisterContextWatchpoint_x86 {
+      public NativeRegisterContextDBReg_x86 {
 public:
   NativeRegisterContextNetBSD_x86_64(const ArchSpec &target_arch,
                                      NativeThreadProtocol &native_thread);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 1a3fd4d..400b89a 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -130,6 +130,30 @@
   m_stop_info.details.signal.signo = SIGTRAP;
 }
 
+void NativeThreadNetBSD::SetStoppedByFork(lldb::pid_t child_pid,
+                                           lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadNetBSD::SetStoppedByVFork(lldb::pid_t child_pid,
+                                            lldb::tid_t child_tid) {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVFork;
+  m_stop_info.details.fork.child_pid = child_pid;
+  m_stop_info.details.fork.child_tid = child_tid;
+}
+
+void NativeThreadNetBSD::SetStoppedByVForkDone() {
+  SetStopped();
+
+  m_stop_info.reason = StopReason::eStopReasonVForkDone;
+}
+
 void NativeThreadNetBSD::SetStoppedWithNoReason() {
   SetStopped();
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index d4e21bd..ee93053 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -59,6 +59,9 @@
   void SetStoppedByTrace();
   void SetStoppedByExec();
   void SetStoppedByWatchpoint(uint32_t wp_index);
+  void SetStoppedByFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVFork(lldb::pid_t child_pid, lldb::tid_t child_tid);
+  void SetStoppedByVForkDone();
   void SetStoppedWithNoReason();
   void SetStopped();
   void SetRunning();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h b/src/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
index f521389..24acdc0 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h
@@ -11,7 +11,7 @@
 
 #include "lldb/lldb-types.h"
 
-#include <signal.h>
+#include <csignal>
 
 #include <string>
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/src/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
index dcfa929..c014099 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -21,6 +21,9 @@
 class NativeProcessELF : public NativeProcessProtocol {
   using NativeProcessProtocol::NativeProcessProtocol;
 
+public:
+  llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type);
+
 protected:
   template <typename T> struct ELFLinkMap {
     T l_addr;
@@ -30,8 +33,6 @@
     T l_prev;
   };
 
-  llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type);
-
   lldb::addr_t GetSharedLibraryInfoAddress() override;
 
   template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/Utility/CMakeLists.txt
index 9965d89..1431876 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -8,9 +8,12 @@
   InferiorCallPOSIX.cpp
   LinuxProcMaps.cpp
   LinuxSignals.cpp
+  MemoryTagManagerAArch64MTE.cpp
   MipsLinuxSignals.cpp
+  NativeProcessSoftwareSingleStep.cpp
+  NativeRegisterContextDBReg_arm64.cpp
+  NativeRegisterContextDBReg_x86.cpp
   NativeRegisterContextRegisterInfo.cpp
-  NativeRegisterContextWatchpoint_x86.cpp
   NetBSDSignals.cpp
   RegisterContext_x86.cpp
   RegisterContextDarwin_arm.cpp
@@ -25,8 +28,6 @@
   RegisterContextHistory.cpp
   RegisterContextLinux_i386.cpp
   RegisterContextLinux_x86_64.cpp
-  RegisterContextLinux_mips64.cpp
-  RegisterContextLinux_mips.cpp
   RegisterContextLinux_s390x.cpp
   RegisterContextMach_arm.cpp
   RegisterContextMach_i386.cpp
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 5463a07..a85d7bd 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -697,6 +697,14 @@
   return nullptr;
 }
 
+const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind,
+                                                         uint32_t num) const {
+  uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);
+  if (reg_index != LLDB_INVALID_REGNUM)
+    return &m_regs[reg_index];
+  return nullptr;
+}
+
 const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
   if (i < m_sets.size())
     return &m_sets[i];
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index fbf9db6..7e90454 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -60,6 +60,9 @@
   uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind,
                                                uint32_t num) const;
 
+  const lldb_private::RegisterInfo *GetRegisterInfo(uint32_t kind,
+                                                    uint32_t num) const;
+
   void Dump() const;
 
   void Clear();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
index 9b95229..7749dc6 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -30,7 +30,7 @@
 
 // Destructor
 
-HistoryUnwind::~HistoryUnwind() {}
+HistoryUnwind::~HistoryUnwind() = default;
 
 void HistoryUnwind::DoClear() {
   std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
index 7f6f7cf..817dca3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/LinuxPTraceDefines_arm64sve.h
@@ -9,7 +9,7 @@
 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
 #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LINUXPTRACEDEFINES_ARM64SVE_H
 
-#include <stdint.h>
+#include <cstdint>
 
 namespace lldb_private {
 namespace sve {
@@ -65,7 +65,7 @@
  * The same convention applies when returning from a signal: a caller
  * will need to remove or resize the sve_context block if it wants to
  * make the SVE registers live when they were previously non-live or
- * vice-versa.  This may require the the caller to allocate fresh
+ * vice-versa.  This may require the caller to allocate fresh
  * memory and/or move other context blocks in the signal frame.
  *
  * Changing the vector length during signal return is not permitted:
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
new file mode 100644
index 0000000..d74b66b
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.cpp
@@ -0,0 +1,200 @@
+//===-- MemoryTagManagerAArch64MTE.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 "MemoryTagManagerAArch64MTE.h"
+
+using namespace lldb_private;
+
+static const unsigned MTE_START_BIT = 56;
+static const unsigned MTE_TAG_MAX = 0xf;
+static const unsigned MTE_GRANULE_SIZE = 16;
+
+lldb::addr_t
+MemoryTagManagerAArch64MTE::GetLogicalTag(lldb::addr_t addr) const {
+  return (addr >> MTE_START_BIT) & MTE_TAG_MAX;
+}
+
+lldb::addr_t
+MemoryTagManagerAArch64MTE::RemoveNonAddressBits(lldb::addr_t addr) const {
+  // Here we're ignoring the whole top byte. If you've got MTE
+  // you must also have TBI (top byte ignore).
+  // The other 4 bits could contain other extension bits or
+  // user metadata.
+  return addr & ~((lldb::addr_t)0xFF << MTE_START_BIT);
+}
+
+ptrdiff_t MemoryTagManagerAArch64MTE::AddressDiff(lldb::addr_t addr1,
+                                                  lldb::addr_t addr2) const {
+  return RemoveNonAddressBits(addr1) - RemoveNonAddressBits(addr2);
+}
+
+lldb::addr_t MemoryTagManagerAArch64MTE::GetGranuleSize() const {
+  return MTE_GRANULE_SIZE;
+}
+
+int32_t MemoryTagManagerAArch64MTE::GetAllocationTagType() const {
+  return eMTE_allocation;
+}
+
+size_t MemoryTagManagerAArch64MTE::GetTagSizeInBytes() const { return 1; }
+
+MemoryTagManagerAArch64MTE::TagRange
+MemoryTagManagerAArch64MTE::ExpandToGranule(TagRange range) const {
+  // Ignore reading a length of 0
+  if (!range.IsValid())
+    return range;
+
+  const size_t granule = GetGranuleSize();
+
+  // Align start down to granule start
+  lldb::addr_t new_start = range.GetRangeBase();
+  lldb::addr_t align_down_amount = new_start % granule;
+  new_start -= align_down_amount;
+
+  // Account for the distance we moved the start above
+  size_t new_len = range.GetByteSize() + align_down_amount;
+  // Then align up to the end of the granule
+  size_t align_up_amount = granule - (new_len % granule);
+  if (align_up_amount != granule)
+    new_len += align_up_amount;
+
+  return TagRange(new_start, new_len);
+}
+
+llvm::Expected<MemoryTagManager::TagRange>
+MemoryTagManagerAArch64MTE::MakeTaggedRange(
+    lldb::addr_t addr, lldb::addr_t end_addr,
+    const lldb_private::MemoryRegionInfos &memory_regions) const {
+  // First check that the range is not inverted.
+  // We must remove tags here otherwise an address with a higher
+  // tag value will always be > the other.
+  ptrdiff_t len = AddressDiff(end_addr, addr);
+  if (len <= 0) {
+    return llvm::createStringError(
+        llvm::inconvertibleErrorCode(),
+        "End address (0x%" PRIx64
+        ") must be greater than the start address (0x%" PRIx64 ")",
+        end_addr, addr);
+  }
+
+  // Region addresses will not have memory tags. So when searching
+  // we must use an untagged address.
+  MemoryRegionInfo::RangeType tag_range(RemoveNonAddressBits(addr), len);
+  tag_range = ExpandToGranule(tag_range);
+
+  // Make a copy so we can use the original for errors and the final return.
+  MemoryRegionInfo::RangeType remaining_range(tag_range);
+
+  // While there are parts of the range that don't have a matching tagged memory
+  // region
+  while (remaining_range.IsValid()) {
+    // Search for a region that contains the start of the range
+    MemoryRegionInfos::const_iterator region = std::find_if(
+        memory_regions.cbegin(), memory_regions.cend(),
+        [&remaining_range](const MemoryRegionInfo &region) {
+          return region.GetRange().Contains(remaining_range.GetRangeBase());
+        });
+
+    if (region == memory_regions.cend() ||
+        region->GetMemoryTagged() != MemoryRegionInfo::eYes) {
+      // Some part of this range is untagged (or unmapped) so error
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "Address range 0x%" PRIx64 ":0x%" PRIx64
+                                     " is not in a memory tagged region",
+                                     tag_range.GetRangeBase(),
+                                     tag_range.GetRangeEnd());
+    }
+
+    // We've found some part of the range so remove that part and continue
+    // searching for the rest. Moving the base "slides" the range so we need to
+    // save/restore the original end. If old_end is less than the new base, the
+    // range will be set to have 0 size and we'll exit the while.
+    lldb::addr_t old_end = remaining_range.GetRangeEnd();
+    remaining_range.SetRangeBase(region->GetRange().GetRangeEnd());
+    remaining_range.SetRangeEnd(old_end);
+  }
+
+  // Every part of the range is contained within a tagged memory region.
+  return tag_range;
+}
+
+llvm::Expected<std::vector<lldb::addr_t>>
+MemoryTagManagerAArch64MTE::UnpackTagsData(const std::vector<uint8_t> &tags,
+                                           size_t granules /*=0*/) const {
+  // 0 means don't check the number of tags before unpacking
+  if (granules) {
+    size_t num_tags = tags.size() / GetTagSizeInBytes();
+    if (num_tags != granules) {
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "Packed tag data size does not match expected number of tags. "
+          "Expected %zu tag(s) for %zu granule(s), got %zu tag(s).",
+          granules, granules, num_tags);
+    }
+  }
+
+  // (if bytes per tag was not 1, we would reconstruct them here)
+
+  std::vector<lldb::addr_t> unpacked;
+  unpacked.reserve(tags.size());
+  for (auto it = tags.begin(); it != tags.end(); ++it) {
+    // Check all tags are in range
+    if (*it > MTE_TAG_MAX) {
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "Found tag 0x%x which is > max MTE tag value of 0x%x.", *it,
+          MTE_TAG_MAX);
+    }
+    unpacked.push_back(*it);
+  }
+
+  return unpacked;
+}
+
+llvm::Expected<std::vector<uint8_t>> MemoryTagManagerAArch64MTE::PackTags(
+    const std::vector<lldb::addr_t> &tags) const {
+  std::vector<uint8_t> packed;
+  packed.reserve(tags.size() * GetTagSizeInBytes());
+
+  for (auto tag : tags) {
+    if (tag > MTE_TAG_MAX) {
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "Found tag 0x%" PRIx64
+                                     " which is > max MTE tag value of 0x%x.",
+                                     tag, MTE_TAG_MAX);
+    }
+    packed.push_back(static_cast<uint8_t>(tag));
+  }
+
+  return packed;
+}
+
+llvm::Expected<std::vector<lldb::addr_t>>
+MemoryTagManagerAArch64MTE::RepeatTagsForRange(
+    const std::vector<lldb::addr_t> &tags, TagRange range) const {
+  std::vector<lldb::addr_t> new_tags;
+
+  // If the range is not empty
+  if (range.IsValid()) {
+    if (tags.empty()) {
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "Expected some tags to cover given range, got zero.");
+    }
+
+    // We assume that this range has already been expanded/aligned to granules
+    size_t granules = range.GetByteSize() / GetGranuleSize();
+    new_tags.reserve(granules);
+    for (size_t to_copy = 0; granules > 0; granules -= to_copy) {
+      to_copy = granules > tags.size() ? tags.size() : granules;
+      new_tags.insert(new_tags.end(), tags.begin(), tags.begin() + to_copy);
+    }
+  }
+
+  return new_tags;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
new file mode 100644
index 0000000..d4e8249
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h
@@ -0,0 +1,53 @@
+//===-- MemoryTagManagerAArch64MTE.h ----------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
+
+#include "lldb/Target/MemoryTagManager.h"
+
+namespace lldb_private {
+
+class MemoryTagManagerAArch64MTE : public MemoryTagManager {
+public:
+  // This enum is supposed to be shared for all of AArch64 but until
+  // there are more tag types than MTE, it will live here.
+  enum MTETagTypes {
+    eMTE_logical = 0,
+    eMTE_allocation = 1,
+  };
+
+  lldb::addr_t GetGranuleSize() const override;
+  int32_t GetAllocationTagType() const override;
+  size_t GetTagSizeInBytes() const override;
+
+  lldb::addr_t GetLogicalTag(lldb::addr_t addr) const override;
+  lldb::addr_t RemoveNonAddressBits(lldb::addr_t addr) const override;
+  ptrdiff_t AddressDiff(lldb::addr_t addr1, lldb::addr_t addr2) const override;
+
+  TagRange ExpandToGranule(TagRange range) const override;
+
+  llvm::Expected<TagRange> MakeTaggedRange(
+      lldb::addr_t addr, lldb::addr_t end_addr,
+      const lldb_private::MemoryRegionInfos &memory_regions) const override;
+
+  llvm::Expected<std::vector<lldb::addr_t>>
+  UnpackTagsData(const std::vector<uint8_t> &tags,
+                 size_t granules = 0) const override;
+
+  llvm::Expected<std::vector<uint8_t>>
+  PackTags(const std::vector<lldb::addr_t> &tags) const override;
+
+  llvm::Expected<std::vector<lldb::addr_t>>
+  RepeatTagsForRange(const std::vector<lldb::addr_t> &tags,
+                     TagRange range) const override;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MEMORYTAGMANAGERAARCH64MTE_H
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
new file mode 100644
index 0000000..ee5295b
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
@@ -0,0 +1,182 @@
+//===-- NativeProcessSoftwareSingleStep.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 "NativeProcessSoftwareSingleStep.h"
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Host/common/NativeRegisterContext.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include <unordered_map>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+struct EmulatorBaton {
+  NativeProcessProtocol &m_process;
+  NativeRegisterContext &m_reg_context;
+
+  // eRegisterKindDWARF -> RegsiterValue
+  std::unordered_map<uint32_t, RegisterValue> m_register_values;
+
+  EmulatorBaton(NativeProcessProtocol &process,
+                NativeRegisterContext &reg_context)
+      : m_process(process), m_reg_context(reg_context) {}
+};
+
+} // anonymous namespace
+
+static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
+                                 const EmulateInstruction::Context &context,
+                                 lldb::addr_t addr, void *dst, size_t length) {
+  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+  size_t bytes_read;
+  emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
+  return bytes_read;
+}
+
+static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
+                                 const RegisterInfo *reg_info,
+                                 RegisterValue &reg_value) {
+  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+
+  auto it = emulator_baton->m_register_values.find(
+      reg_info->kinds[eRegisterKindDWARF]);
+  if (it != emulator_baton->m_register_values.end()) {
+    reg_value = it->second;
+    return true;
+  }
+
+  // The emulator only fill in the dwarf regsiter numbers (and in some case the
+  // generic register numbers). Get the full register info from the register
+  // context based on the dwarf register numbers.
+  const RegisterInfo *full_reg_info =
+      emulator_baton->m_reg_context.GetRegisterInfo(
+          eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
+
+  Status error =
+      emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
+  if (error.Success())
+    return true;
+
+  return false;
+}
+
+static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
+                                  const EmulateInstruction::Context &context,
+                                  const RegisterInfo *reg_info,
+                                  const RegisterValue &reg_value) {
+  EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
+  emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
+      reg_value;
+  return true;
+}
+
+static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
+                                  const EmulateInstruction::Context &context,
+                                  lldb::addr_t addr, const void *dst,
+                                  size_t length) {
+  return length;
+}
+
+static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
+  const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
+      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+  return regsiter_context.ReadRegisterAsUnsigned(flags_info,
+                                                 LLDB_INVALID_ADDRESS);
+}
+
+Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping(
+    NativeThreadProtocol &thread) {
+  Status error;
+  NativeProcessProtocol &process = thread.GetProcess();
+  NativeRegisterContext &register_context = thread.GetRegisterContext();
+  const ArchSpec &arch = process.GetArchitecture();
+
+  std::unique_ptr<EmulateInstruction> emulator_up(
+      EmulateInstruction::FindPlugin(arch, eInstructionTypePCModifying,
+                                     nullptr));
+
+  if (emulator_up == nullptr)
+    return Status("Instruction emulator not found!");
+
+  EmulatorBaton baton(process, register_context);
+  emulator_up->SetBaton(&baton);
+  emulator_up->SetReadMemCallback(&ReadMemoryCallback);
+  emulator_up->SetReadRegCallback(&ReadRegisterCallback);
+  emulator_up->SetWriteMemCallback(&WriteMemoryCallback);
+  emulator_up->SetWriteRegCallback(&WriteRegisterCallback);
+
+  if (!emulator_up->ReadInstruction())
+    return Status("Read instruction failed!");
+
+  bool emulation_result =
+      emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
+
+  const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
+      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+  const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
+      eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+
+  auto pc_it =
+      baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
+  auto flags_it =
+      baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
+
+  lldb::addr_t next_pc;
+  lldb::addr_t next_flags;
+  if (emulation_result) {
+    assert(pc_it != baton.m_register_values.end() &&
+           "Emulation was successfull but PC wasn't updated");
+    next_pc = pc_it->second.GetAsUInt64();
+
+    if (flags_it != baton.m_register_values.end())
+      next_flags = flags_it->second.GetAsUInt64();
+    else
+      next_flags = ReadFlags(register_context);
+  } else if (pc_it == baton.m_register_values.end()) {
+    // Emulate instruction failed and it haven't changed PC. Advance PC with
+    // the size of the current opcode because the emulation of all
+    // PC modifying instruction should be successful. The failure most
+    // likely caused by a not supported instruction which don't modify PC.
+    next_pc = register_context.GetPC() + emulator_up->GetOpcode().GetByteSize();
+    next_flags = ReadFlags(register_context);
+  } else {
+    // The instruction emulation failed after it modified the PC. It is an
+    // unknown error where we can't continue because the next instruction is
+    // modifying the PC but we don't  know how.
+    return Status("Instruction emulation failed unexpectedly.");
+  }
+
+  int size_hint = 0;
+  if (arch.GetMachine() == llvm::Triple::arm) {
+    if (next_flags & 0x20) {
+      // Thumb mode
+      size_hint = 2;
+    } else {
+      // Arm mode
+      size_hint = 4;
+    }
+  } else if (arch.IsMIPS() || arch.GetTriple().isPPC64())
+    size_hint = 4;
+  error = process.SetBreakpoint(next_pc, size_hint, /*hardware=*/false);
+
+  // If setting the breakpoint fails because next_pc is out of the address
+  // space, ignore it and let the debugee segfault.
+  if (error.GetError() == EIO || error.GetError() == EFAULT) {
+    return Status();
+  } else if (error.Fail())
+    return error;
+
+  m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
+
+  return Status();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
new file mode 100644
index 0000000..f9435b7
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h
@@ -0,0 +1,31 @@
+//===-- NativeProcessSoftwareSingleStep.h -----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeProcessSoftwareSingleStep_h
+#define lldb_NativeProcessSoftwareSingleStep_h
+
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
+
+#include <map>
+
+namespace lldb_private {
+
+class NativeProcessSoftwareSingleStep {
+public:
+  Status SetupSoftwareSingleStepping(NativeThreadProtocol &thread);
+
+protected:
+  // List of thread ids stepping with a breakpoint with the address of
+  // the relevan breakpoint
+  std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeProcessSoftwareSingleStep_h
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
new file mode 100644
index 0000000..feee857
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.cpp
@@ -0,0 +1,469 @@
+//===-- NativeRegisterContextDBReg_arm64.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 "NativeRegisterContextDBReg_arm64.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+
+using namespace lldb_private;
+
+// E (bit 0), used to enable breakpoint/watchpoint
+constexpr uint32_t g_enable_bit = 1;
+// PAC (bits 2:1): 0b10
+constexpr uint32_t g_pac_bits = (2 << 1);
+
+// Returns appropriate control register bits for the specified size
+static constexpr inline uint64_t GetSizeBits(int size) {
+  // BAS (bits 12:5) hold a bit-mask of addresses to watch
+  // e.g. 0b00000001 means 1 byte at address
+  //      0b00000011 means 2 bytes (addr..addr+1)
+  //      ...
+  //      0b11111111 means 8 bytes (addr..addr+7)
+  return ((1 << size) - 1) << 5;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareBreakpoints() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(log, std::move(error),
+                   "failed to read debug registers: {0}");
+    return 0;
+  }
+
+  return m_max_hbp_supported;
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
+                                                        size_t size) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to set breakpoint: failed to read debug registers: {0}");
+    return LLDB_INVALID_INDEX32;
+  }
+
+  uint32_t control_value = 0, bp_index = 0;
+
+  // Check if size has a valid hardware breakpoint length.
+  if (size != 4)
+    return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
+                                 // breakpoint
+
+  // Check 4-byte alignment for hardware breakpoint target address.
+  if (addr & 0x03)
+    return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
+
+  // Setup control value
+  control_value = g_enable_bit | g_pac_bits | GetSizeBits(size);
+
+  // Iterate over stored breakpoints and find a free bp_index
+  bp_index = LLDB_INVALID_INDEX32;
+  for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+    if (!BreakpointIsEnabled(i))
+      bp_index = i; // Mark last free slot
+    else if (m_hbp_regs[i].address == addr)
+      return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
+  }
+
+  if (bp_index == LLDB_INVALID_INDEX32)
+    return LLDB_INVALID_INDEX32;
+
+  // Update breakpoint in local cache
+  m_hbp_regs[bp_index].real_addr = addr;
+  m_hbp_regs[bp_index].address = addr;
+  m_hbp_regs[bp_index].control = control_value;
+
+  // PTRACE call to set corresponding hardware breakpoint register.
+  error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+  if (error) {
+    m_hbp_regs[bp_index].address = 0;
+    m_hbp_regs[bp_index].control &= ~1;
+
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to set breakpoint: failed to write debug registers: {0}");
+    return LLDB_INVALID_INDEX32;
+  }
+
+  return bp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareBreakpoint(
+    uint32_t hw_idx) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  LLDB_LOG(log, "hw_idx: {0}", hw_idx);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to clear breakpoint: failed to read debug registers: {0}");
+    return false;
+  }
+
+  if (hw_idx >= m_max_hbp_supported)
+    return false;
+
+  // Create a backup we can revert to in case of failure.
+  lldb::addr_t tempAddr = m_hbp_regs[hw_idx].address;
+  uint32_t tempControl = m_hbp_regs[hw_idx].control;
+
+  m_hbp_regs[hw_idx].control &= ~g_enable_bit;
+  m_hbp_regs[hw_idx].address = 0;
+
+  // PTRACE call to clear corresponding hardware breakpoint register.
+  error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+  if (error) {
+    m_hbp_regs[hw_idx].control = tempControl;
+    m_hbp_regs[hw_idx].address = tempAddr;
+
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to clear breakpoint: failed to write debug registers: {0}");
+    return false;
+  }
+
+  return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetHardwareBreakHitIndex(
+    uint32_t &bp_index, lldb::addr_t trap_addr) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+  LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+  lldb::addr_t break_addr;
+
+  for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
+    break_addr = m_hbp_regs[bp_index].address;
+
+    if (BreakpointIsEnabled(bp_index) && trap_addr == break_addr) {
+      m_hbp_regs[bp_index].hit_addr = trap_addr;
+      return Status();
+    }
+  }
+
+  bp_index = LLDB_INVALID_INDEX32;
+  return Status();
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareBreakpoints() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+  LLDB_LOGF(log, "NativeRegisterContextDBReg_arm64::%s()", __FUNCTION__);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error)
+    return Status(std::move(error));
+
+  for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+    if (BreakpointIsEnabled(i)) {
+      // Create a backup we can revert to in case of failure.
+      lldb::addr_t tempAddr = m_hbp_regs[i].address;
+      uint32_t tempControl = m_hbp_regs[i].control;
+
+      // Clear watchpoints in local cache
+      m_hbp_regs[i].control &= ~g_enable_bit;
+      m_hbp_regs[i].address = 0;
+
+      // Ptrace call to update hardware debug registers
+      error = WriteHardwareDebugRegs(eDREGTypeBREAK);
+
+      if (error) {
+        m_hbp_regs[i].control = tempControl;
+        m_hbp_regs[i].address = tempAddr;
+
+        return Status(std::move(error));
+      }
+    }
+  }
+
+  return Status();
+}
+
+bool NativeRegisterContextDBReg_arm64::BreakpointIsEnabled(uint32_t bp_index) {
+  if ((m_hbp_regs[bp_index].control & g_enable_bit) != 0)
+    return true;
+  else
+    return false;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::NumSupportedHardwareWatchpoints() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(log, std::move(error),
+                   "failed to read debug registers: {0}");
+    return 0;
+  }
+
+  return m_max_hwp_supported;
+}
+
+uint32_t NativeRegisterContextDBReg_arm64::SetHardwareWatchpoint(
+    lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
+           watch_flags);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to set watchpoint: failed to read debug registers: {0}");
+    return LLDB_INVALID_INDEX32;
+  }
+
+  uint32_t control_value = 0, wp_index = 0;
+  lldb::addr_t real_addr = addr;
+
+  // Check if we are setting watchpoint other than read/write/access Also
+  // update watchpoint flag to match AArch64 write-read bit configuration.
+  switch (watch_flags) {
+  case 1:
+    watch_flags = 2;
+    break;
+  case 2:
+    watch_flags = 1;
+    break;
+  case 3:
+    break;
+  default:
+    return LLDB_INVALID_INDEX32;
+  }
+
+  // Check if size has a valid hardware watchpoint length.
+  if (size != 1 && size != 2 && size != 4 && size != 8)
+    return LLDB_INVALID_INDEX32;
+
+  // Check 8-byte alignment for hardware watchpoint target address. Below is a
+  // hack to recalculate address and size in order to make sure we can watch
+  // non 8-byte aligned addresses as well.
+  if (addr & 0x07) {
+    uint8_t watch_mask = (addr & 0x07) + size;
+
+    if (watch_mask > 0x08)
+      return LLDB_INVALID_INDEX32;
+    else if (watch_mask <= 0x02)
+      size = 2;
+    else if (watch_mask <= 0x04)
+      size = 4;
+    else
+      size = 8;
+
+    addr = addr & (~0x07);
+  }
+
+  // Setup control value
+  control_value = g_enable_bit | g_pac_bits | GetSizeBits(size);
+  control_value |= watch_flags << 3;
+
+  // Iterate over stored watchpoints and find a free wp_index
+  wp_index = LLDB_INVALID_INDEX32;
+  for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+    if (!WatchpointIsEnabled(i))
+      wp_index = i; // Mark last free slot
+    else if (m_hwp_regs[i].address == addr) {
+      return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+    }
+  }
+
+  if (wp_index == LLDB_INVALID_INDEX32)
+    return LLDB_INVALID_INDEX32;
+
+  // Update watchpoint in local cache
+  m_hwp_regs[wp_index].real_addr = real_addr;
+  m_hwp_regs[wp_index].address = addr;
+  m_hwp_regs[wp_index].control = control_value;
+
+  // PTRACE call to set corresponding watchpoint register.
+  error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+  if (error) {
+    m_hwp_regs[wp_index].address = 0;
+    m_hwp_regs[wp_index].control &= ~g_enable_bit;
+
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to set watchpoint: failed to write debug registers: {0}");
+    return LLDB_INVALID_INDEX32;
+  }
+
+  return wp_index;
+}
+
+bool NativeRegisterContextDBReg_arm64::ClearHardwareWatchpoint(
+    uint32_t wp_index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error) {
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to clear watchpoint: failed to read debug registers: {0}");
+    return false;
+  }
+
+  if (wp_index >= m_max_hwp_supported)
+    return false;
+
+  // Create a backup we can revert to in case of failure.
+  lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+  uint32_t tempControl = m_hwp_regs[wp_index].control;
+
+  // Update watchpoint in local cache
+  m_hwp_regs[wp_index].control &= ~g_enable_bit;
+  m_hwp_regs[wp_index].address = 0;
+
+  // Ptrace call to update hardware debug registers
+  error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+  if (error) {
+    m_hwp_regs[wp_index].control = tempControl;
+    m_hwp_regs[wp_index].address = tempAddr;
+
+    LLDB_LOG_ERROR(
+        log, std::move(error),
+        "unable to clear watchpoint: failed to write debug registers: {0}");
+    return false;
+  }
+
+  return true;
+}
+
+Status NativeRegisterContextDBReg_arm64::ClearAllHardwareWatchpoints() {
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error)
+    return Status(std::move(error));
+
+  for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+    if (WatchpointIsEnabled(i)) {
+      // Create a backup we can revert to in case of failure.
+      lldb::addr_t tempAddr = m_hwp_regs[i].address;
+      uint32_t tempControl = m_hwp_regs[i].control;
+
+      // Clear watchpoints in local cache
+      m_hwp_regs[i].control &= ~g_enable_bit;
+      m_hwp_regs[i].address = 0;
+
+      // Ptrace call to update hardware debug registers
+      error = WriteHardwareDebugRegs(eDREGTypeWATCH);
+
+      if (error) {
+        m_hwp_regs[i].control = tempControl;
+        m_hwp_regs[i].address = tempAddr;
+
+        return Status(std::move(error));
+      }
+    }
+  }
+
+  return Status();
+}
+
+uint32_t
+NativeRegisterContextDBReg_arm64::GetWatchpointSize(uint32_t wp_index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
+  case 0x01:
+    return 1;
+  case 0x03:
+    return 2;
+  case 0x0f:
+    return 4;
+  case 0xff:
+    return 8;
+  default:
+    return 0;
+  }
+}
+
+bool NativeRegisterContextDBReg_arm64::WatchpointIsEnabled(uint32_t wp_index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  if ((m_hwp_regs[wp_index].control & g_enable_bit) != 0)
+    return true;
+  else
+    return false;
+}
+
+Status NativeRegisterContextDBReg_arm64::GetWatchpointHitIndex(
+    uint32_t &wp_index, lldb::addr_t trap_addr) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
+
+  // Read hardware breakpoint and watchpoint information.
+  llvm::Error error = ReadHardwareDebugInfo();
+  if (error)
+    return Status(std::move(error));
+
+  // Mask off ignored bits from watchpoint trap address.
+  trap_addr = FixWatchpointHitAddress(trap_addr);
+
+  uint32_t watch_size;
+  lldb::addr_t watch_addr;
+
+  for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+    watch_size = GetWatchpointSize(wp_index);
+    watch_addr = m_hwp_regs[wp_index].address;
+
+    if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+        trap_addr < watch_addr + watch_size) {
+      m_hwp_regs[wp_index].hit_addr = trap_addr;
+      return Status();
+    }
+  }
+
+  wp_index = LLDB_INVALID_INDEX32;
+  return Status();
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointAddress(uint32_t wp_index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  if (wp_index >= m_max_hwp_supported)
+    return LLDB_INVALID_ADDRESS;
+
+  if (WatchpointIsEnabled(wp_index))
+    return m_hwp_regs[wp_index].real_addr;
+  return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextDBReg_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+  LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+  if (wp_index >= m_max_hwp_supported)
+    return LLDB_INVALID_ADDRESS;
+
+  if (WatchpointIsEnabled(wp_index))
+    return m_hwp_regs[wp_index].hit_addr;
+  return LLDB_INVALID_ADDRESS;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
new file mode 100644
index 0000000..3da0b04
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h
@@ -0,0 +1,82 @@
+//===-- NativeRegisterContextDBReg_arm64.h ----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_NativeRegisterContextDBReg_arm64_h
+#define lldb_NativeRegisterContextDBReg_arm64_h
+
+#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+
+#include <array>
+
+namespace lldb_private {
+
+class NativeRegisterContextDBReg_arm64
+    : public virtual NativeRegisterContextRegisterInfo {
+public:
+  uint32_t NumSupportedHardwareBreakpoints() override;
+
+  uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
+
+  bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
+
+  Status ClearAllHardwareBreakpoints() override;
+
+  Status GetHardwareBreakHitIndex(uint32_t &bp_index,
+                                  lldb::addr_t trap_addr) override;
+
+  bool BreakpointIsEnabled(uint32_t bp_index);
+
+  uint32_t NumSupportedHardwareWatchpoints() override;
+
+  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+                                 uint32_t watch_flags) override;
+
+  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+  Status ClearAllHardwareWatchpoints() override;
+
+  Status GetWatchpointHitIndex(uint32_t &wp_index,
+                               lldb::addr_t trap_addr) override;
+
+  lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
+
+  lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+  uint32_t GetWatchpointSize(uint32_t wp_index);
+
+  bool WatchpointIsEnabled(uint32_t wp_index);
+
+  // Debug register type select
+  enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
+
+protected:
+  // Debug register info for hardware breakpoints and watchpoints management.
+  struct DREG {
+    lldb::addr_t address;  // Breakpoint/watchpoint address value.
+    lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
+                           // occurred.
+    lldb::addr_t real_addr; // Address value that should cause target to stop.
+    uint32_t control;       // Breakpoint/watchpoint control value.
+  };
+
+  std::array<struct DREG, 16> m_hbp_regs; // hardware breakpoints
+  std::array<struct DREG, 16> m_hwp_regs; // hardware watchpoints
+
+  uint32_t m_max_hbp_supported;
+  uint32_t m_max_hwp_supported;
+
+  virtual llvm::Error ReadHardwareDebugInfo() = 0;
+  virtual llvm::Error WriteHardwareDebugRegs(DREGType hwbType) = 0;
+  virtual lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) {
+    return hit_addr;
+  }
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextDBReg_arm64_h
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
similarity index 86%
rename from src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.cpp
rename to src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
index 0f57f2e..56c1757 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.cpp
@@ -1,4 +1,4 @@
-//===-- NativeRegisterContextWatchpoint_x86.cpp ---------------------------===//
+//===-- NativeRegisterContextDBReg_x86.cpp --------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "NativeRegisterContextWatchpoint_x86.h"
+#include "NativeRegisterContextDBReg_x86.h"
 
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/RegisterValue.h"
@@ -80,7 +80,7 @@
 // Bit mask for control bits regarding all watchpoints.
 static constexpr uint64_t watchpoint_all_control_bit_mask = 0xFFFF00FF;
 
-const RegisterInfo *NativeRegisterContextWatchpoint_x86::GetDR(int num) const {
+const RegisterInfo *NativeRegisterContextDBReg_x86::GetDR(int num) const {
   assert(num >= 0 && num <= 7);
   switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
   case llvm::Triple::x86:
@@ -92,8 +92,8 @@
   }
 }
 
-Status NativeRegisterContextWatchpoint_x86::IsWatchpointHit(uint32_t wp_index,
-                                                            bool &is_hit) {
+Status NativeRegisterContextDBReg_x86::IsWatchpointHit(uint32_t wp_index,
+                                                       bool &is_hit) {
   if (wp_index >= NumSupportedHardwareWatchpoints())
     return Status("Watchpoint index out of range");
 
@@ -107,8 +107,9 @@
   return error;
 }
 
-Status NativeRegisterContextWatchpoint_x86::GetWatchpointHitIndex(
-    uint32_t &wp_index, lldb::addr_t trap_addr) {
+Status
+NativeRegisterContextDBReg_x86::GetWatchpointHitIndex(uint32_t &wp_index,
+                                                      lldb::addr_t trap_addr) {
   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
   for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
     bool is_hit;
@@ -124,9 +125,8 @@
   return Status();
 }
 
-Status
-NativeRegisterContextWatchpoint_x86::IsWatchpointVacant(uint32_t wp_index,
-                                                        bool &is_vacant) {
+Status NativeRegisterContextDBReg_x86::IsWatchpointVacant(uint32_t wp_index,
+                                                          bool &is_vacant) {
   if (wp_index >= NumSupportedHardwareWatchpoints())
     return Status("Watchpoint index out of range");
 
@@ -140,7 +140,7 @@
   return error;
 }
 
-Status NativeRegisterContextWatchpoint_x86::SetHardwareWatchpointWithIndex(
+Status NativeRegisterContextDBReg_x86::SetHardwareWatchpointWithIndex(
     lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
 
   if (wp_index >= NumSupportedHardwareWatchpoints())
@@ -202,7 +202,7 @@
   return error;
 }
 
-bool NativeRegisterContextWatchpoint_x86::ClearHardwareWatchpoint(
+bool NativeRegisterContextDBReg_x86::ClearHardwareWatchpoint(
     uint32_t wp_index) {
   if (wp_index >= NumSupportedHardwareWatchpoints())
     return false;
@@ -217,8 +217,7 @@
       .Success();
 }
 
-Status
-NativeRegisterContextWatchpoint_x86::ClearWatchpointHit(uint32_t wp_index) {
+Status NativeRegisterContextDBReg_x86::ClearWatchpointHit(uint32_t wp_index) {
   if (wp_index >= NumSupportedHardwareWatchpoints())
     return Status("Watchpoint index out of range");
 
@@ -231,7 +230,7 @@
       GetDR(6), RegisterValue(dr6.GetAsUInt64() & ~GetStatusBit(wp_index)));
 }
 
-Status NativeRegisterContextWatchpoint_x86::ClearAllHardwareWatchpoints() {
+Status NativeRegisterContextDBReg_x86::ClearAllHardwareWatchpoints() {
   RegisterValue dr7;
   Status error = ReadRegister(GetDR(7), dr7);
   if (error.Fail())
@@ -241,7 +240,7 @@
       RegisterValue(dr7.GetAsUInt64() & ~watchpoint_all_control_bit_mask));
 }
 
-uint32_t NativeRegisterContextWatchpoint_x86::SetHardwareWatchpoint(
+uint32_t NativeRegisterContextDBReg_x86::SetHardwareWatchpoint(
     lldb::addr_t addr, size_t size, uint32_t watch_flags) {
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
   const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
@@ -254,7 +253,7 @@
         return wp_index;
     }
     if (error.Fail() && log) {
-      LLDB_LOGF(log, "NativeRegisterContextWatchpoint_x86::%s Error: %s",
+      LLDB_LOGF(log, "NativeRegisterContextDBReg_x86::%s Error: %s",
                 __FUNCTION__, error.AsCString());
     }
   }
@@ -262,7 +261,7 @@
 }
 
 lldb::addr_t
-NativeRegisterContextWatchpoint_x86::GetWatchpointAddress(uint32_t wp_index) {
+NativeRegisterContextDBReg_x86::GetWatchpointAddress(uint32_t wp_index) {
   if (wp_index >= NumSupportedHardwareWatchpoints())
     return LLDB_INVALID_ADDRESS;
   RegisterValue drN;
@@ -271,8 +270,7 @@
   return drN.GetAsUInt64();
 }
 
-uint32_t
-NativeRegisterContextWatchpoint_x86::NumSupportedHardwareWatchpoints() {
+uint32_t NativeRegisterContextDBReg_x86::NumSupportedHardwareWatchpoints() {
   // Available debug address registers: dr0, dr1, dr2, dr3
   return 4;
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
similarity index 71%
rename from src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
rename to src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
index cfb8900..a4ed8bf 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h
@@ -1,4 +1,4 @@
-//===-- NativeRegisterContextWatchpoint_x86.h -------------------*- C++ -*-===//
+//===-- NativeRegisterContextDBReg_x86.h ------------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,16 +6,22 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef lldb_NativeRegisterContextWatchpoint_x86_h
-#define lldb_NativeRegisterContextWatchpoint_x86_h
+#ifndef lldb_NativeRegisterContextDBReg_x86_h
+#define lldb_NativeRegisterContextDBReg_x86_h
 
 #include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
 
 namespace lldb_private {
 
-class NativeRegisterContextWatchpoint_x86
+class NativeRegisterContextDBReg_x86
     : public virtual NativeRegisterContextRegisterInfo {
 public:
+  // NB: This constructor is here only because gcc<=6.5 requires a virtual base
+  // class initializer on abstract class (even though it is never used). It can
+  // be deleted once we move to gcc>=7.0.
+  NativeRegisterContextDBReg_x86(NativeThreadProtocol &thread)
+      : NativeRegisterContextRegisterInfo(thread, nullptr) {}
+
   Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
 
   Status GetWatchpointHitIndex(uint32_t &wp_index,
@@ -45,4 +51,4 @@
 
 } // namespace lldb_private
 
-#endif // #ifndef lldb_NativeRegisterContextWatchpoint_x86_h
+#endif // #ifndef lldb_NativeRegisterContextDBReg_x86_h
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index eef4541..7e38091 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -922,7 +922,7 @@
   }
 }
 
-RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
+RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;
 
 void RegisterContextDarwin_arm::InvalidateAllRegisters() {
   InvalidateAllRegisterStates();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 9fc2752..b98b2f3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -104,7 +104,7 @@
   }
 }
 
-RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() {}
+RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() = default;
 
 void RegisterContextDarwin_arm64::InvalidateAllRegisters() {
   InvalidateAllRegisterStates();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index c5ebddc..95f8132 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -15,7 +15,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
 
-#include <stddef.h>
+#include <cstddef>
 
 #include <memory>
 
@@ -405,7 +405,7 @@
   }
 }
 
-RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
+RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default;
 
 void RegisterContextDarwin_i386::InvalidateAllRegisters() {
   InvalidateAllRegisterStates();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index 38cd00a..03e5ea4 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stddef.h>
+#include <cinttypes>
+#include <cstdarg>
+#include <cstddef>
 
 #include <memory>
 
@@ -467,7 +467,7 @@
   }
 }
 
-RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() {}
+RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
 
 void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
   InvalidateAllRegisterStates();
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
index 9fe6255..2991bd3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp
@@ -178,7 +178,7 @@
     const ArchSpec &target_arch)
     : RegisterInfoInterface(target_arch) {}
 
-RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() {}
+RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() = default;
 
 size_t RegisterContextFreeBSD_powerpc::GetGPRSize() const {
   // This is an 'abstract' base, so no GPR struct.
@@ -197,7 +197,7 @@
     const ArchSpec &target_arch)
     : RegisterContextFreeBSD_powerpc(target_arch) {}
 
-RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() {}
+RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() = default;
 
 size_t RegisterContextFreeBSD_powerpc32::GetGPRSize() const {
   return sizeof(GPR32);
@@ -217,7 +217,7 @@
     const ArchSpec &target_arch)
     : RegisterContextFreeBSD_powerpc(target_arch) {}
 
-RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() {}
+RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() = default;
 
 size_t RegisterContextFreeBSD_powerpc64::GetGPRSize() const {
   return sizeof(GPR64);
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
deleted file mode 100644
index 837549e..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- RegisterContextLinux_mips.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 <stddef.h>
-#include <vector>
-
-// For eh_frame and DWARF Register numbers
-#include "RegisterContextLinux_mips.h"
-
-// Internal codes for mips registers
-#include "lldb-mips-linux-register-enums.h"
-
-// For GP and FP buffers
-#include "RegisterContext_mips.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-// Include RegisterInfos_mips to declare our g_register_infos_mips structure.
-#define DECLARE_REGISTER_INFOS_MIPS_STRUCT
-#include "RegisterInfos_mips.h"
-#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-
-// mips general purpose registers.
-const uint32_t g_gp_regnums_mips[] = {
-    gpr_zero_mips,      gpr_r1_mips,    gpr_r2_mips,      gpr_r3_mips,
-    gpr_r4_mips,        gpr_r5_mips,    gpr_r6_mips,      gpr_r7_mips,
-    gpr_r8_mips,        gpr_r9_mips,    gpr_r10_mips,     gpr_r11_mips,
-    gpr_r12_mips,       gpr_r13_mips,   gpr_r14_mips,     gpr_r15_mips,
-    gpr_r16_mips,       gpr_r17_mips,   gpr_r18_mips,     gpr_r19_mips,
-    gpr_r20_mips,       gpr_r21_mips,   gpr_r22_mips,     gpr_r23_mips,
-    gpr_r24_mips,       gpr_r25_mips,   gpr_r26_mips,     gpr_r27_mips,
-    gpr_gp_mips,        gpr_sp_mips,    gpr_r30_mips,     gpr_ra_mips,
-    gpr_sr_mips,        gpr_mullo_mips, gpr_mulhi_mips,   gpr_badvaddr_mips,
-    gpr_cause_mips,     gpr_pc_mips,    gpr_config5_mips,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_gp_regnums_mips) / sizeof(g_gp_regnums_mips[0])) - 1 ==
-                  k_num_gpr_registers_mips,
-              "g_gp_regnums_mips has wrong number of register infos");
-// mips floating point registers.
-const uint32_t g_fp_regnums_mips[] = {
-    fpr_f0_mips,        fpr_f1_mips,  fpr_f2_mips,      fpr_f3_mips,
-    fpr_f4_mips,        fpr_f5_mips,  fpr_f6_mips,      fpr_f7_mips,
-    fpr_f8_mips,        fpr_f9_mips,  fpr_f10_mips,     fpr_f11_mips,
-    fpr_f12_mips,       fpr_f13_mips, fpr_f14_mips,     fpr_f15_mips,
-    fpr_f16_mips,       fpr_f17_mips, fpr_f18_mips,     fpr_f19_mips,
-    fpr_f20_mips,       fpr_f21_mips, fpr_f22_mips,     fpr_f23_mips,
-    fpr_f24_mips,       fpr_f25_mips, fpr_f26_mips,     fpr_f27_mips,
-    fpr_f28_mips,       fpr_f29_mips, fpr_f30_mips,     fpr_f31_mips,
-    fpr_fcsr_mips,      fpr_fir_mips, fpr_config5_mips,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_fp_regnums_mips) / sizeof(g_fp_regnums_mips[0])) - 1 ==
-                  k_num_fpr_registers_mips,
-              "g_fp_regnums_mips has wrong number of register infos");
-
-// mips MSA registers.
-const uint32_t g_msa_regnums_mips[] = {
-    msa_w0_mips,        msa_w1_mips,  msa_w2_mips,   msa_w3_mips,
-    msa_w4_mips,        msa_w5_mips,  msa_w6_mips,   msa_w7_mips,
-    msa_w8_mips,        msa_w9_mips,  msa_w10_mips,  msa_w11_mips,
-    msa_w12_mips,       msa_w13_mips, msa_w14_mips,  msa_w15_mips,
-    msa_w16_mips,       msa_w17_mips, msa_w18_mips,  msa_w19_mips,
-    msa_w20_mips,       msa_w21_mips, msa_w22_mips,  msa_w23_mips,
-    msa_w24_mips,       msa_w25_mips, msa_w26_mips,  msa_w27_mips,
-    msa_w28_mips,       msa_w29_mips, msa_w30_mips,  msa_w31_mips,
-    msa_fcsr_mips,      msa_fir_mips, msa_mcsr_mips, msa_mir_mips,
-    msa_config5_mips,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_msa_regnums_mips) / sizeof(g_msa_regnums_mips[0])) -
-                      1 ==
-                  k_num_msa_registers_mips,
-              "g_msa_regnums_mips has wrong number of register infos");
-
-// Number of register sets provided by this context.
-constexpr size_t k_num_register_sets = 3;
-
-// Register sets for mips.
-static const RegisterSet g_reg_sets_mips[k_num_register_sets] = {
-    {"General Purpose Registers", "gpr", k_num_gpr_registers_mips,
-     g_gp_regnums_mips},
-    {"Floating Point Registers", "fpu", k_num_fpr_registers_mips,
-     g_fp_regnums_mips},
-    {"MSA Registers", "msa", k_num_msa_registers_mips, g_msa_regnums_mips}};
-
-uint32_t GetUserRegisterInfoCount(bool msa_present) {
-  if (msa_present)
-    return static_cast<uint32_t>(k_num_user_registers_mips);
-  return static_cast<uint32_t>(k_num_user_registers_mips -
-                               k_num_msa_registers_mips);
-}
-
-RegisterContextLinux_mips::RegisterContextLinux_mips(
-    const ArchSpec &target_arch, bool msa_present)
-    : RegisterInfoInterface(target_arch),
-      m_user_register_count(GetUserRegisterInfoCount(msa_present)) {}
-
-size_t RegisterContextLinux_mips::GetGPRSize() const {
-  return sizeof(GPR_linux_mips);
-}
-
-const RegisterInfo *RegisterContextLinux_mips::GetRegisterInfo() const {
-  switch (m_target_arch.GetMachine()) {
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    return g_register_infos_mips;
-  default:
-    assert(false && "Unhandled target architecture.");
-    return nullptr;
-  }
-}
-
-const RegisterSet * 
-RegisterContextLinux_mips::GetRegisterSet(size_t set) const {
-  if (set >= k_num_register_sets)
-    return nullptr;
-  switch (m_target_arch.GetMachine()) {
-    case llvm::Triple::mips:
-    case llvm::Triple::mipsel:
-      return &g_reg_sets_mips[set];
-    default:
-      assert(false && "Unhandled target architecture.");
-      return nullptr;
-  }
-}
-
-size_t
-RegisterContextLinux_mips::GetRegisterSetCount() const {
-  return k_num_register_sets;
-}
-
-uint32_t RegisterContextLinux_mips::GetRegisterCount() const {
-  return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
-                               sizeof(g_register_infos_mips[0]));
-}
-
-uint32_t RegisterContextLinux_mips::GetUserRegisterCount() const {
-  return static_cast<uint32_t>(m_user_register_count);
-}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
deleted file mode 100644
index 9b59ab4..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- RegisterContextLinux_mips.h ---------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS_H
-
-#include "RegisterInfoInterface.h"
-#include "lldb/lldb-private.h"
-
-class RegisterContextLinux_mips : public lldb_private::RegisterInfoInterface {
-public:
-  RegisterContextLinux_mips(const lldb_private::ArchSpec &target_arch,
-                            bool msa_present = true);
-
-  size_t GetGPRSize() const override;
-
-  const lldb_private::RegisterInfo *GetRegisterInfo() const override;
-
-  const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
-
-  size_t GetRegisterSetCount() const;
-
-  uint32_t GetRegisterCount() const override;
-
-  uint32_t GetUserRegisterCount() const override;
-
-private:
-  uint32_t m_user_register_count;
-};
-
-#endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
deleted file mode 100644
index 432a781..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-//===-- RegisterContextLinux_mips64.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 <stddef.h>
-#include <vector>
-
-// For eh_frame and DWARF Register numbers
-#include "RegisterContextLinux_mips64.h"
-
-// For GP and FP buffers
-#include "RegisterContext_mips.h"
-
-// Internal codes for all mips32 and mips64 registers
-#include "lldb-mips-linux-register-enums.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-// Include RegisterInfos_mips64 to declare our g_register_infos_mips64
-// structure.
-#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-#define LINUX_MIPS64
-#include "RegisterInfos_mips64.h"
-#undef LINUX_MIPS64
-#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
-
-// Include RegisterInfos_mips to declare our g_register_infos_mips structure.
-#define DECLARE_REGISTER_INFOS_MIPS_STRUCT
-#include "RegisterInfos_mips.h"
-#undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
-
-// mips64 general purpose registers.
-const uint32_t g_gp_regnums_mips64[] = {
-    gpr_zero_mips64,    gpr_r1_mips64,    gpr_r2_mips64,
-    gpr_r3_mips64,      gpr_r4_mips64,    gpr_r5_mips64,
-    gpr_r6_mips64,      gpr_r7_mips64,    gpr_r8_mips64,
-    gpr_r9_mips64,      gpr_r10_mips64,   gpr_r11_mips64,
-    gpr_r12_mips64,     gpr_r13_mips64,   gpr_r14_mips64,
-    gpr_r15_mips64,     gpr_r16_mips64,   gpr_r17_mips64,
-    gpr_r18_mips64,     gpr_r19_mips64,   gpr_r20_mips64,
-    gpr_r21_mips64,     gpr_r22_mips64,   gpr_r23_mips64,
-    gpr_r24_mips64,     gpr_r25_mips64,   gpr_r26_mips64,
-    gpr_r27_mips64,     gpr_gp_mips64,    gpr_sp_mips64,
-    gpr_r30_mips64,     gpr_ra_mips64,    gpr_sr_mips64,
-    gpr_mullo_mips64,   gpr_mulhi_mips64, gpr_badvaddr_mips64,
-    gpr_cause_mips64,   gpr_pc_mips64,    gpr_config5_mips64,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
-                      1 ==
-                  k_num_gpr_registers_mips64,
-              "g_gp_regnums_mips64 has wrong number of register infos");
-
-// mips64 floating point registers.
-const uint32_t g_fp_regnums_mips64[] = {
-    fpr_f0_mips64,      fpr_f1_mips64,  fpr_f2_mips64,      fpr_f3_mips64,
-    fpr_f4_mips64,      fpr_f5_mips64,  fpr_f6_mips64,      fpr_f7_mips64,
-    fpr_f8_mips64,      fpr_f9_mips64,  fpr_f10_mips64,     fpr_f11_mips64,
-    fpr_f12_mips64,     fpr_f13_mips64, fpr_f14_mips64,     fpr_f15_mips64,
-    fpr_f16_mips64,     fpr_f17_mips64, fpr_f18_mips64,     fpr_f19_mips64,
-    fpr_f20_mips64,     fpr_f21_mips64, fpr_f22_mips64,     fpr_f23_mips64,
-    fpr_f24_mips64,     fpr_f25_mips64, fpr_f26_mips64,     fpr_f27_mips64,
-    fpr_f28_mips64,     fpr_f29_mips64, fpr_f30_mips64,     fpr_f31_mips64,
-    fpr_fcsr_mips64,    fpr_fir_mips64, fpr_config5_mips64,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
-                      1 ==
-                  k_num_fpr_registers_mips64,
-              "g_fp_regnums_mips64 has wrong number of register infos");
-
-// mips64 MSA registers.
-const uint32_t g_msa_regnums_mips64[] = {
-    msa_w0_mips64,      msa_w1_mips64,  msa_w2_mips64,   msa_w3_mips64,
-    msa_w4_mips64,      msa_w5_mips64,  msa_w6_mips64,   msa_w7_mips64,
-    msa_w8_mips64,      msa_w9_mips64,  msa_w10_mips64,  msa_w11_mips64,
-    msa_w12_mips64,     msa_w13_mips64, msa_w14_mips64,  msa_w15_mips64,
-    msa_w16_mips64,     msa_w17_mips64, msa_w18_mips64,  msa_w19_mips64,
-    msa_w20_mips64,     msa_w21_mips64, msa_w22_mips64,  msa_w23_mips64,
-    msa_w24_mips64,     msa_w25_mips64, msa_w26_mips64,  msa_w27_mips64,
-    msa_w28_mips64,     msa_w29_mips64, msa_w30_mips64,  msa_w31_mips64,
-    msa_fcsr_mips64,    msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
-    msa_config5_mips64,
-    LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
-                      1 ==
-                  k_num_msa_registers_mips64,
-              "g_msa_regnums_mips64 has wrong number of register infos");
-
-// Number of register sets provided by this context.
-constexpr size_t k_num_register_sets = 3;
-
-// Register sets for mips64.
-static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
-    {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
-     g_gp_regnums_mips64},
-    {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
-     g_fp_regnums_mips64},
-    {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
-};
-
-const RegisterSet *
-RegisterContextLinux_mips64::GetRegisterSet(size_t set) const {
-  if (set >= k_num_register_sets)
-    return nullptr;
-
-  switch (m_target_arch.GetMachine()) {
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    return &g_reg_sets_mips64[set];
-  default:
-    assert(false && "Unhandled target architecture.");
-    return nullptr;
-  }
-  return nullptr;
-}
-
-size_t
-RegisterContextLinux_mips64::GetRegisterSetCount() const {
-  return k_num_register_sets;
-}
-
-static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    return g_register_infos_mips64;
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    return g_register_infos_mips;
-  default:
-    assert(false && "Unhandled target architecture.");
-    return nullptr;
-  }
-}
-
-static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::mips64:
-  case llvm::Triple::mips64el:
-    return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
-                                 sizeof(g_register_infos_mips64[0]));
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
-                                 sizeof(g_register_infos_mips[0]));
-  default:
-    assert(false && "Unhandled target architecture.");
-    return 0;
-  }
-}
-
-uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
-                                  bool msa_present) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    if (msa_present)
-      return static_cast<uint32_t>(k_num_user_registers_mips);
-    return static_cast<uint32_t>(k_num_user_registers_mips -
-                                 k_num_msa_registers_mips);
-  case llvm::Triple::mips64el:
-  case llvm::Triple::mips64:
-    if (msa_present)
-      return static_cast<uint32_t>(k_num_user_registers_mips64);
-    return static_cast<uint32_t>(k_num_user_registers_mips64 -
-                                 k_num_msa_registers_mips64);
-  default:
-    assert(false && "Unhandled target architecture.");
-    return 0;
-  }
-}
-
-RegisterContextLinux_mips64::RegisterContextLinux_mips64(
-    const ArchSpec &target_arch, bool msa_present)
-    : lldb_private::RegisterInfoInterface(target_arch),
-      m_register_info_p(GetRegisterInfoPtr(target_arch)),
-      m_register_info_count(GetRegisterInfoCount(target_arch)),
-      m_user_register_count(
-          GetUserRegisterInfoCount(target_arch, msa_present)) {}
-
-size_t RegisterContextLinux_mips64::GetGPRSize() const {
-  return sizeof(GPR_linux_mips);
-}
-
-const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
-  return m_register_info_p;
-}
-
-uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
-  return m_register_info_count;
-}
-
-uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
-  return m_user_register_count;
-}
-
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
deleted file mode 100644
index 899f0a4..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_mips64.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextLinux_mips64.h ---------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_MIPS64_H
-
-#include "RegisterInfoInterface.h"
-#include "lldb/lldb-private.h"
-
-class RegisterContextLinux_mips64 : public lldb_private::RegisterInfoInterface {
-public:
-  RegisterContextLinux_mips64(const lldb_private::ArchSpec &target_arch,
-                              bool msa_present = true);
-
-  size_t GetGPRSize() const override;
-
-  const lldb_private::RegisterInfo *GetRegisterInfo() const override;
-
-  const lldb_private::RegisterSet *GetRegisterSet(size_t set) const;
-
-  size_t GetRegisterSetCount() const;
-
-  uint32_t GetRegisterCount() const override;
-
-  uint32_t GetUserRegisterCount() const override;
-
-private:
-  const lldb_private::RegisterInfo *m_register_info_p;
-  uint32_t m_register_info_count;
-  uint32_t m_user_register_count;
-};
-
-#endif
-
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index 1394cb7..067d1c3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -21,7 +21,7 @@
                                                  uint32_t concrete_frame_idx)
     : RegisterContextDarwin_arm(thread, concrete_frame_idx) {}
 
-RegisterContextMach_arm::~RegisterContextMach_arm() {}
+RegisterContextMach_arm::~RegisterContextMach_arm() = default;
 
 int RegisterContextMach_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
   mach_msg_type_number_t count = GPRWordCount;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index b97166b..fe5cece 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -19,7 +19,7 @@
                                                    uint32_t concrete_frame_idx)
     : RegisterContextDarwin_i386(thread, concrete_frame_idx) {}
 
-RegisterContextMach_i386::~RegisterContextMach_i386() {}
+RegisterContextMach_i386::~RegisterContextMach_i386() = default;
 
 int RegisterContextMach_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
   mach_msg_type_number_t count = GPRWordCount;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index 8933f13..a3d8c4f 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -19,7 +19,7 @@
     Thread &thread, uint32_t concrete_frame_idx)
     : RegisterContextDarwin_x86_64(thread, concrete_frame_idx) {}
 
-RegisterContextMach_x86_64::~RegisterContextMach_x86_64() {}
+RegisterContextMach_x86_64::~RegisterContextMach_x86_64() = default;
 
 int RegisterContextMach_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
                                           GPR &gpr) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index f2d230b..c55ffeb 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -39,7 +39,7 @@
 }
 
 // Destructor
-RegisterContextMemory::~RegisterContextMemory() {}
+RegisterContextMemory::~RegisterContextMemory() = default;
 
 void RegisterContextMemory::InvalidateAllRegisters() {
   if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 97a7603..684176b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -45,7 +45,7 @@
     : lldb_private::RegisterContext(thread, 0),
       m_register_info_up(std::move(register_info)) {}
 
-RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() {}
+RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm() = default;
 
 void RegisterContextPOSIX_arm::Invalidate() {}
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 3f52501..676e450 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -40,10 +40,11 @@
 }
 
 bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
-  if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
-      RegisterInfoPOSIX_arm64::SVERegSet)
-    return true;
-  return false;
+  return m_register_info_up->IsSVEReg(reg);
+}
+
+bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
+  return m_register_info_up->IsPAuthReg(reg);
 }
 
 RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
@@ -52,7 +53,7 @@
     : lldb_private::RegisterContext(thread, 0),
       m_register_info_up(std::move(register_info)) {}
 
-RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() {}
+RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64() = default;
 
 void RegisterContextPOSIX_arm64::Invalidate() {}
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index a3f07bb..7c30159 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -54,6 +54,7 @@
   size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
 
   bool IsSVE(unsigned reg) const;
+  bool IsPAuth(unsigned reg) const;
 
   bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
   bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index c41c4bd..9e05737 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -22,8 +22,6 @@
 
 #include "RegisterContextPOSIX_mips64.h"
 #include "RegisterContextFreeBSD_mips64.h"
-#include "RegisterContextLinux_mips64.h"
-#include "RegisterContextLinux_mips.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -60,7 +58,7 @@
                                m_registers_count[msa_registers_count]));
 }
 
-RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() {}
+RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64() = default;
 
 void RegisterContextPOSIX_mips64::Invalidate() {}
 
@@ -102,17 +100,6 @@
 size_t RegisterContextPOSIX_mips64::GetRegisterSetCount() {
   ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
   switch (target_arch.GetTriple().getOS()) {
-  case llvm::Triple::Linux: {
-    if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
-         (target_arch.GetMachine() == llvm::Triple::mips)) {
-      const auto *context = static_cast<const RegisterContextLinux_mips *>(
-          m_register_info_up.get());
-      return context->GetRegisterSetCount();
-    }
-    const auto *context = static_cast<const RegisterContextLinux_mips64 *>(
-        m_register_info_up.get());
-    return context->GetRegisterSetCount();
-  }
   default: {
     const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
         m_register_info_up.get());
@@ -125,17 +112,6 @@
 const RegisterSet *RegisterContextPOSIX_mips64::GetRegisterSet(size_t set) {
   ArchSpec target_arch = m_register_info_up->GetTargetArchitecture();
   switch (target_arch.GetTriple().getOS()) {
-  case llvm::Triple::Linux: {
-    if ((target_arch.GetMachine() == llvm::Triple::mipsel) ||
-         (target_arch.GetMachine() == llvm::Triple::mips)) {
-      const auto *context = static_cast<const RegisterContextLinux_mips *>(
-          m_register_info_up.get());
-      return context->GetRegisterSet(set);
-    }
-    const auto *context = static_cast<const RegisterContextLinux_mips64 *>(
-        m_register_info_up.get());
-    return context->GetRegisterSet(set);
-  }
   default: {
     const auto *context = static_cast<const RegisterContextFreeBSD_mips64 *>(
         m_register_info_up.get());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index cd65b96..cffd286 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -95,7 +95,7 @@
   m_register_info_up.reset(register_info);
 }
 
-RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() {}
+RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() = default;
 
 void RegisterContextPOSIX_powerpc::Invalidate() {}
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
index f670be2..f70ddeb 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index e746ec6..21c8160 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -98,7 +98,7 @@
   }
 }
 
-RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() {}
+RegisterContextPOSIX_s390x::~RegisterContextPOSIX_s390x() = default;
 
 void RegisterContextPOSIX_s390x::Invalidate() {}
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 2c7f635..67e03ff 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <cerrno>
+#include <cstdint>
 #include <cstring>
-#include <errno.h>
-#include <stdint.h>
 
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
@@ -448,7 +448,7 @@
   m_fpr_type = eNotValid;
 }
 
-RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() {}
+RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86() = default;
 
 RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
   if (m_fpr_type == eNotValid) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
index 31e2944..4866cbd 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp
@@ -22,7 +22,7 @@
     : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
       m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}
 
-RegisterContextThreadMemory::~RegisterContextThreadMemory() {}
+RegisterContextThreadMemory::~RegisterContextThreadMemory() = default;
 
 void RegisterContextThreadMemory::UpdateRegisterContext() {
   ThreadSP thread_sp(m_thread_wp.lock());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 88c2ae7..c054383 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -22,7 +22,7 @@
 public:
   RegisterInfoInterface(const lldb_private::ArchSpec &target_arch)
       : m_target_arch(target_arch) {}
-  virtual ~RegisterInfoInterface() {}
+  virtual ~RegisterInfoInterface() = default;
 
   virtual size_t GetGPRSize() const = 0;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
index 17b96f9..63461f7 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp
@@ -7,7 +7,7 @@
 //===---------------------------------------------------------------------===//
 
 #include <cassert>
-#include <stddef.h>
+#include <cstddef>
 #include <vector>
 
 #include "lldb/lldb-defines.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 515c9f4..b878534 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -7,7 +7,7 @@
 //===---------------------------------------------------------------------===//
 
 #include <cassert>
-#include <stddef.h>
+#include <cstddef>
 #include <vector>
 
 #include "lldb/lldb-defines.h"
@@ -72,23 +72,14 @@
 #include "RegisterInfos_arm64_sve.h"
 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
 
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_32:
-    return g_register_infos_arm64_le;
-  default:
-    assert(false && "Unhandled target architecture.");
-    return nullptr;
-  }
-}
-
 // Number of register sets provided by this context.
 enum {
   k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
   k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
   k_num_sve_registers = sve_ffr - sve_vg + 1,
+  k_num_mte_register = 1,
+  k_num_pauth_register = 2,
+  k_num_register_sets_default = 2,
   k_num_register_sets = 3
 };
 
@@ -186,31 +177,66 @@
     {"Scalable Vector Extension Registers", "sve", k_num_sve_registers,
      g_sve_regnums_arm64}};
 
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = {
+    "Pointer Authentication Registers", "pauth", k_num_pauth_register, NULL};
+
+static const lldb_private::RegisterSet g_reg_set_mte_arm64 = {
+    "MTE Control Register", "mte", k_num_mte_register, NULL};
+
+RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
+    const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
+    : lldb_private::RegisterInfoAndSetInterface(target_arch),
+      m_opt_regsets(opt_regsets) {
   switch (target_arch.GetMachine()) {
   case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_32:
-    return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
-                                 sizeof(g_register_infos_arm64_le[0]));
+  case llvm::Triple::aarch64_32: {
+    m_register_set_p = g_reg_sets_arm64;
+    m_register_set_count = k_num_register_sets_default;
+    m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28 + 1);
+    m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr + 1);
+
+    // Now configure register sets supported by current target. If we have a
+    // dynamic register set like MTE, Pointer Authentication regset then we need
+    // to create dynamic register infos and regset array. Push back all optional
+    // register infos and regset and calculate register offsets accordingly.
+    if (m_opt_regsets.AllSet(eRegsetMaskSVE)) {
+      m_register_info_p = g_register_infos_arm64_sve_le;
+      m_register_info_count = sve_ffr + 1;
+      m_per_regset_regnum_range[m_register_set_count++] =
+          std::make_pair(sve_vg, sve_ffr + 1);
+    } else {
+      m_register_info_p = g_register_infos_arm64_le;
+      m_register_info_count = fpu_fpcr + 1;
+    }
+
+    if (m_opt_regsets.AnySet(eRegsetMaskDynamic)) {
+      llvm::ArrayRef<lldb_private::RegisterInfo> reg_infos_ref =
+          llvm::makeArrayRef(m_register_info_p, m_register_info_count);
+      llvm::ArrayRef<lldb_private::RegisterSet> reg_sets_ref =
+          llvm::makeArrayRef(m_register_set_p, m_register_set_count);
+      llvm::copy(reg_infos_ref, std::back_inserter(m_dynamic_reg_infos));
+      llvm::copy(reg_sets_ref, std::back_inserter(m_dynamic_reg_sets));
+
+      if (m_opt_regsets.AllSet(eRegsetMaskPAuth))
+        AddRegSetPAuth();
+
+      if (m_opt_regsets.AllSet(eRegsetMaskMTE))
+        AddRegSetMTE();
+
+      m_register_info_count = m_dynamic_reg_infos.size();
+      m_register_info_p = m_dynamic_reg_infos.data();
+      m_register_set_p = m_dynamic_reg_sets.data();
+      m_register_set_count = m_dynamic_reg_sets.size();
+    }
+    break;
+  }
   default:
     assert(false && "Unhandled target architecture.");
-    return 0;
   }
 }
 
-RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
-    const lldb_private::ArchSpec &target_arch)
-    : lldb_private::RegisterInfoAndSetInterface(target_arch),
-      m_register_info_p(GetRegisterInfoPtr(target_arch)),
-      m_register_info_count(GetRegisterInfoCount(target_arch)) {
-}
-
 uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
-  if (IsSVEEnabled())
-    return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
-
-  return k_num_gpr_registers + k_num_fpr_registers;
+  return m_register_info_count;
 }
 
 size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
@@ -227,31 +253,60 @@
 }
 
 size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
-  if (IsSVEEnabled())
-    return k_num_register_sets;
-  return k_num_register_sets - 1;
+  return m_register_set_count;
 }
 
 size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
     uint32_t reg_index) const {
-  if (reg_index <= gpr_w28)
-    return GPRegSet;
-  if (reg_index <= fpu_fpcr)
-    return FPRegSet;
-  if (reg_index <= sve_ffr)
-    return SVERegSet;
+  for (const auto &regset_range : m_per_regset_regnum_range) {
+    if (reg_index >= regset_range.second.first &&
+        reg_index < regset_range.second.second)
+      return regset_range.first;
+  }
   return LLDB_INVALID_REGNUM;
 }
 
 const lldb_private::RegisterSet *
 RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
   if (set_index < GetRegisterSetCount())
-    return &g_reg_sets_arm64[set_index];
+    return &m_register_set_p[set_index];
   return nullptr;
 }
 
-uint32_t
-RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
+void RegisterInfoPOSIX_arm64::AddRegSetPAuth() {
+  uint32_t pa_regnum = m_dynamic_reg_infos.size();
+  for (uint32_t i = 0; i < k_num_pauth_register; i++) {
+    pauth_regnum_collection.push_back(pa_regnum + i);
+    m_dynamic_reg_infos.push_back(g_register_infos_pauth[i]);
+    m_dynamic_reg_infos[pa_regnum + i].byte_offset =
+        m_dynamic_reg_infos[pa_regnum + i - 1].byte_offset +
+        m_dynamic_reg_infos[pa_regnum + i - 1].byte_size;
+    m_dynamic_reg_infos[pa_regnum + i].kinds[lldb::eRegisterKindLLDB] =
+        pa_regnum + i;
+  }
+
+  m_per_regset_regnum_range[m_register_set_count] =
+      std::make_pair(pa_regnum, m_dynamic_reg_infos.size());
+  m_dynamic_reg_sets.push_back(g_reg_set_pauth_arm64);
+  m_dynamic_reg_sets.back().registers = pauth_regnum_collection.data();
+}
+
+void RegisterInfoPOSIX_arm64::AddRegSetMTE() {
+  uint32_t mte_regnum = m_dynamic_reg_infos.size();
+  m_mte_regnum_collection.push_back(mte_regnum);
+  m_dynamic_reg_infos.push_back(g_register_infos_mte[0]);
+  m_dynamic_reg_infos[mte_regnum].byte_offset =
+      m_dynamic_reg_infos[mte_regnum - 1].byte_offset +
+      m_dynamic_reg_infos[mte_regnum - 1].byte_size;
+  m_dynamic_reg_infos[mte_regnum].kinds[lldb::eRegisterKindLLDB] = mte_regnum;
+
+  m_per_regset_regnum_range[m_register_set_count] =
+      std::make_pair(mte_regnum, mte_regnum + 1);
+  m_dynamic_reg_sets.push_back(g_reg_set_mte_arm64);
+  m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data();
+}
+
+uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) {
   // sve_vq contains SVE Quad vector length in context of AArch64 SVE.
   // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0.
   // Also if an invalid or previously set vector length is passed to this
@@ -266,28 +321,15 @@
 
   m_vector_reg_vq = sve_vq;
 
-  if (sve_vq == eVectorQuadwordAArch64) {
-    m_register_info_count =
-        static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
-                              sizeof(g_register_infos_arm64_le[0]));
-    m_register_info_p = g_register_infos_arm64_le;
-
+  if (sve_vq == eVectorQuadwordAArch64)
     return m_vector_reg_vq;
-  }
-
-  m_register_info_count =
-      static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
-                            sizeof(g_register_infos_arm64_sve_le[0]));
-
   std::vector<lldb_private::RegisterInfo> &reg_info_ref =
       m_per_vq_reg_infos[sve_vq];
 
   if (reg_info_ref.empty()) {
-    reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le,
-                                      m_register_info_count);
+    reg_info_ref = llvm::makeArrayRef(m_register_info_p, m_register_info_count);
 
     uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX;
-
     reg_info_ref[fpu_fpsr].byte_offset = offset;
     reg_info_ref[fpu_fpcr].byte_offset = offset + 4;
     reg_info_ref[sve_vg].byte_offset = offset + 8;
@@ -316,13 +358,25 @@
       offset += reg_info_ref[it].byte_size;
     }
 
+    for (uint32_t it = sve_ffr + 1; it < m_register_info_count; it++) {
+      reg_info_ref[it].byte_offset = offset;
+      offset += reg_info_ref[it].byte_size;
+    }
+
     m_per_vq_reg_infos[sve_vq] = reg_info_ref;
   }
 
-  m_register_info_p = reg_info_ref.data();
+  m_register_info_p = m_per_vq_reg_infos[sve_vq].data();
   return m_vector_reg_vq;
 }
 
+bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const {
+  if (m_vector_reg_vq > eVectorQuadwordAArch64)
+    return (sve_vg <= reg && reg <= sve_ffr);
+  else
+    return false;
+}
+
 bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const {
   return (sve_z0 <= reg && reg <= sve_z31);
 }
@@ -335,6 +389,18 @@
   return sve_vg == reg;
 }
 
+bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const {
+  return std::find(pauth_regnum_collection.begin(),
+                   pauth_regnum_collection.end(),
+                   reg) != pauth_regnum_collection.end();
+}
+
+bool RegisterInfoPOSIX_arm64::IsMTEReg(unsigned reg) const {
+  return std::find(m_mte_regnum_collection.begin(),
+                   m_mte_regnum_collection.end(),
+                   reg) != m_mte_regnum_collection.end();
+}
+
 uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; }
 
 uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; }
@@ -344,3 +410,11 @@
 uint32_t RegisterInfoPOSIX_arm64::GetRegNumFPSR() const { return fpu_fpsr; }
 
 uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
+
+uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const {
+  return m_register_info_p[pauth_regnum_collection[0]].byte_offset;
+}
+
+uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const {
+  return m_register_info_p[m_mte_regnum_collection[0]].byte_offset;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 2929f20..ba873ba 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -11,6 +11,7 @@
 
 #include "RegisterInfoAndSetInterface.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Flags.h"
 #include "lldb/lldb-private.h"
 #include <map>
 
@@ -19,7 +20,16 @@
 class RegisterInfoPOSIX_arm64
     : public lldb_private::RegisterInfoAndSetInterface {
 public:
-  enum { GPRegSet = 0, FPRegSet, SVERegSet };
+  enum { GPRegSet = 0, FPRegSet };
+
+  // AArch64 register set mask value
+  enum {
+    eRegsetMaskDefault = 0,
+    eRegsetMaskSVE = 1,
+    eRegsetMaskPAuth = 2,
+    eRegsetMaskMTE = 4,
+    eRegsetMaskDynamic = ~1,
+  };
 
   // AArch64 Register set FP/SIMD feature configuration
   enum {
@@ -68,7 +78,8 @@
     uint64_t mdscr_el1;
   };
 
-  RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch);
+  RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch,
+                          lldb_private::Flags opt_regsets);
 
   size_t GetGPRSize() const override;
 
@@ -85,7 +96,11 @@
 
   size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
 
-  uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+  void AddRegSetPAuth();
+
+  void AddRegSetMTE();
+
+  uint32_t ConfigureVectorLength(uint32_t sve_vq);
 
   bool VectorSizeIsValid(uint32_t vq) {
     if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
@@ -93,17 +108,23 @@
     return false;
   }
 
-  bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+  bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
+  bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
 
+  bool IsSVEReg(unsigned reg) const;
   bool IsSVEZReg(unsigned reg) const;
   bool IsSVEPReg(unsigned reg) const;
   bool IsSVERegVG(unsigned reg) const;
+  bool IsPAuthReg(unsigned reg) const;
+  bool IsMTEReg(unsigned reg) const;
 
   uint32_t GetRegNumSVEZ0() const;
   uint32_t GetRegNumSVEFFR() const;
   uint32_t GetRegNumFPCR() const;
   uint32_t GetRegNumFPSR() const;
   uint32_t GetRegNumSVEVG() const;
+  uint32_t GetPAuthOffset() const;
+  uint32_t GetMTEOffset() const;
 
 private:
   typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>>
@@ -115,6 +136,21 @@
 
   const lldb_private::RegisterInfo *m_register_info_p;
   uint32_t m_register_info_count;
+
+  const lldb_private::RegisterSet *m_register_set_p;
+  uint32_t m_register_set_count;
+
+  // Contains pair of [start, end] register numbers of a register set with start
+  // and end included.
+  std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range;
+
+  lldb_private::Flags m_opt_regsets;
+
+  std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos;
+  std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets;
+
+  std::vector<uint32_t> pauth_regnum_collection;
+  std::vector<uint32_t> m_mte_regnum_collection;
 };
 
 #endif
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
index 3461d38..159fd28 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -7,7 +7,7 @@
 //===---------------------------------------------------------------------===//
 
 #include <cassert>
-#include <stddef.h>
+#include <cstddef>
 #include <vector>
 
 #include "lldb/lldb-defines.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
index 74b9e3b..4af0069 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -8,7 +8,7 @@
 
 #ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index 4aee55e..47cedc3 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -8,7 +8,7 @@
 
 #ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "lldb/lldb-defines.h"
 #include "lldb/lldb-enumerations.h"
@@ -470,6 +470,13 @@
         LLDB_INVALID_REGNUM, lldb_kind                                         \
   }
 
+// Generates register kinds array for registers with only lldb kind
+#define KIND_ALL_INVALID                                                       \
+  {                                                                            \
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,             \
+        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM                               \
+  }
+
 // Generates register kinds array for vector registers
 #define GPR64_KIND(reg, generic_kind) MISC_KIND(reg, gpr, generic_kind)
 #define VREG_KIND(reg) MISC_KIND(reg, fpu, LLDB_INVALID_REGNUM)
@@ -526,6 +533,13 @@
         nullptr, 0                                                             \
   }
 
+// Defines pointer authentication mask registers
+#define DEFINE_EXTENSION_REG(reg)                                              \
+  {                                                                            \
+    #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex,                \
+        KIND_ALL_INVALID, nullptr, nullptr, nullptr, 0                         \
+  }
+
 static lldb_private::RegisterInfo g_register_infos_arm64_le[] = {
     // DEFINE_GPR64(name, GENERIC KIND)
     DEFINE_GPR64(x0, LLDB_REGNUM_GENERIC_ARG1),
@@ -772,7 +786,12 @@
     {DEFINE_DBG(wcr, 13)},
     {DEFINE_DBG(wcr, 14)},
     {DEFINE_DBG(wcr, 15)}
-    // clang-format on
 };
+// clang-format on
+static lldb_private::RegisterInfo g_register_infos_pauth[] = {
+    DEFINE_EXTENSION_REG(data_mask), DEFINE_EXTENSION_REG(code_mask)};
+
+static lldb_private::RegisterInfo g_register_infos_mte[] = {
+    DEFINE_EXTENSION_REG(mte_ctrl)};
 
 #endif // DECLARE_REGISTER_INFOS_ARM64_STRUCT
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
index 08201fd..93f93d5 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -6,7 +6,7 @@
 //
 //===---------------------------------------------------------------------===//
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "lldb/Core/dwarf.h"
 #include "llvm/Support/Compiler.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index b6e218e..b28b918 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "lldb/Core/dwarf.h"
 #include "llvm/Support/Compiler.h"
@@ -15,37 +15,11 @@
 #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
 
 // Computes the offset of the given GPR in the user data area.
-#ifdef LINUX_MIPS64
-#define GPR_OFFSET(regname)                                                    \
-  (LLVM_EXTENSION offsetof(UserArea, gpr) +                                    \
-   LLVM_EXTENSION offsetof(GPR_linux_mips, regname))
-#else
 #define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
-#endif
-
-// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname)                                                    \
-  (LLVM_EXTENSION offsetof(UserArea, fpr) +                                    \
-   LLVM_EXTENSION offsetof(FPR_linux_mips, regname))
-
-// Computes the offset of the given MSA in the extended data area.
-#define MSA_OFFSET(regname)                                                    \
-  (LLVM_EXTENSION offsetof(UserArea, msa) +                                    \
-   LLVM_EXTENSION offsetof(MSA_linux_mips, regname))
 
 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
 
 // Note that the size and offset will be updated by platform-specific classes.
-#ifdef LINUX_MIPS64
-#define DEFINE_GPR(reg, alt, kind1, kind2, kind3)                              \
-  {                                                                            \
-    #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg),                            \
-                      GPR_OFFSET(reg), eEncodingUint, eFormatHex,              \
-                                 {kind1, kind2, kind3, ptrace_##reg##_mips,    \
-                                  gpr_##reg##_mips64 },                        \
-                                  NULL, NULL, NULL, 0                          \
-  }
-#else
 #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)                       \
   {                                                                            \
     #reg, alt, sizeof(((GPR_freebsd_mips *) 0)->reg),                          \
@@ -54,63 +28,10 @@
                                   gpr_##reg##_mips64 },                        \
                                   NULL, NULL, NULL, 0                          \
   }
-#endif
-
-#define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3)                         \
-  {                                                                            \
-    #reg, alt, sizeof(((GPR_linux_mips *) 0)->reg) / 2,                        \
-                      GPR_OFFSET(reg), eEncodingUint, eFormatHex,              \
-                                 {kind1, kind2, kind3, ptrace_##reg##_mips,    \
-                                  gpr_##reg##_mips64 },                        \
-                                  NULL, NULL, NULL, 0                          \
-  }
-
-const uint8_t dwarf_opcode_mips64[] = {
-    llvm::dwarf::DW_OP_regx,  dwarf_sr_mips64,        llvm::dwarf::DW_OP_lit1,
-    llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
-    llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
-
-#define DEFINE_FPR(reg, alt, kind1, kind2, kind3)                              \
-  {                                                                            \
-    #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg),                            \
-                      FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat,         \
-                                 {kind1, kind2, kind3, ptrace_##reg##_mips,    \
-                                  fpr_##reg##_mips64 },                        \
-                                  NULL, NULL, dwarf_opcode_mips64,             \
-                                  sizeof(dwarf_opcode_mips64)                  \
-  }
-
-#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3)                         \
-  {                                                                            \
-    #reg, alt, sizeof(((FPR_linux_mips *) 0)->reg),                            \
-                      FPR_OFFSET(reg), eEncodingUint, eFormatHex,              \
-                                 {kind1, kind2, kind3, ptrace_##reg##_mips,    \
-                                  fpr_##reg##_mips64 },                        \
-                                  NULL, NULL, NULL, 0                          \
-  }
-
-#define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4)                       \
-  {                                                                            \
-    #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg),                            \
-                      MSA_OFFSET(reg), eEncodingVector, eFormatVectorOfUInt8,  \
-                                 {kind1, kind2, kind3, kind4,                  \
-                                  msa_##reg##_mips64 },                        \
-                                  NULL, NULL, NULL, 0                          \
-  }
-
-#define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4)                  \
-  {                                                                            \
-    #reg, alt, sizeof(((MSA_linux_mips *) 0)->reg),                            \
-                      MSA_OFFSET(reg), eEncodingUint, eFormatHex,              \
-                                 {kind1, kind2, kind3, kind4,                  \
-                                  msa_##reg##_mips64 },                        \
-                                  NULL, NULL, NULL, 0                          \
-  }
 
 static RegisterInfo g_register_infos_mips64[] = {
 // General purpose registers.            EH_Frame,                  DWARF,
 // Generic,    Process Plugin
-#ifndef LINUX_MIPS64
     DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
@@ -191,231 +112,6 @@
                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64,
                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-#else
-    DEFINE_GPR(zero, "r0", dwarf_zero_mips64, dwarf_zero_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r1, nullptr, dwarf_r1_mips64, dwarf_r1_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r2, nullptr, dwarf_r2_mips64, dwarf_r2_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r3, nullptr, dwarf_r3_mips64, dwarf_r3_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r4, nullptr, dwarf_r4_mips64, dwarf_r4_mips64,
-               LLDB_REGNUM_GENERIC_ARG1),
-    DEFINE_GPR(r5, nullptr, dwarf_r5_mips64, dwarf_r5_mips64,
-               LLDB_REGNUM_GENERIC_ARG2),
-    DEFINE_GPR(r6, nullptr, dwarf_r6_mips64, dwarf_r6_mips64,
-               LLDB_REGNUM_GENERIC_ARG3),
-    DEFINE_GPR(r7, nullptr, dwarf_r7_mips64, dwarf_r7_mips64,
-               LLDB_REGNUM_GENERIC_ARG4),
-    DEFINE_GPR(r8, nullptr, dwarf_r8_mips64, dwarf_r8_mips64,
-               LLDB_REGNUM_GENERIC_ARG5),
-    DEFINE_GPR(r9, nullptr, dwarf_r9_mips64, dwarf_r9_mips64,
-               LLDB_REGNUM_GENERIC_ARG6),
-    DEFINE_GPR(r10, nullptr, dwarf_r10_mips64, dwarf_r10_mips64,
-               LLDB_REGNUM_GENERIC_ARG7),
-    DEFINE_GPR(r11, nullptr, dwarf_r11_mips64, dwarf_r11_mips64,
-               LLDB_REGNUM_GENERIC_ARG8),
-    DEFINE_GPR(r12, nullptr, dwarf_r12_mips64, dwarf_r12_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r13, nullptr, dwarf_r13_mips64, dwarf_r13_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r14, nullptr, dwarf_r14_mips64, dwarf_r14_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r15, nullptr, dwarf_r15_mips64, dwarf_r15_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r16, nullptr, dwarf_r16_mips64, dwarf_r16_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r17, nullptr, dwarf_r17_mips64, dwarf_r17_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r18, nullptr, dwarf_r18_mips64, dwarf_r18_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r19, nullptr, dwarf_r19_mips64, dwarf_r19_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r20, nullptr, dwarf_r20_mips64, dwarf_r20_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r21, nullptr, dwarf_r21_mips64, dwarf_r21_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r22, nullptr, dwarf_r22_mips64, dwarf_r22_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r23, nullptr, dwarf_r23_mips64, dwarf_r23_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r24, nullptr, dwarf_r24_mips64, dwarf_r24_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r25, nullptr, dwarf_r25_mips64, dwarf_r25_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r26, nullptr, dwarf_r26_mips64, dwarf_r26_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(r27, nullptr, dwarf_r27_mips64, dwarf_r27_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(gp, "r28", dwarf_gp_mips64, dwarf_gp_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(sp, "r29", dwarf_sp_mips64, dwarf_sp_mips64,
-               LLDB_REGNUM_GENERIC_SP),
-    DEFINE_GPR(r30, nullptr, dwarf_r30_mips64, dwarf_r30_mips64,
-               LLDB_REGNUM_GENERIC_FP),
-    DEFINE_GPR(ra, "r31", dwarf_ra_mips64, dwarf_ra_mips64,
-               LLDB_REGNUM_GENERIC_RA),
-    DEFINE_GPR_INFO(sr, nullptr, dwarf_sr_mips64, dwarf_sr_mips64,
-                    LLDB_REGNUM_GENERIC_FLAGS),
-    DEFINE_GPR(mullo, nullptr, dwarf_lo_mips64, dwarf_lo_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(mulhi, nullptr, dwarf_hi_mips64, dwarf_hi_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR(badvaddr, nullptr, dwarf_bad_mips64, dwarf_bad_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_GPR_INFO(cause, nullptr, dwarf_cause_mips64, dwarf_cause_mips64,
-                    LLDB_INVALID_REGNUM),
-    DEFINE_GPR(pc, "pc", dwarf_pc_mips64, dwarf_pc_mips64,
-               LLDB_REGNUM_GENERIC_PC),
-    DEFINE_GPR_INFO(config5, nullptr, dwarf_config5_mips64,
-                    dwarf_config5_mips64, LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64,
-               LLDB_INVALID_REGNUM),
-    DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64,
-                    LLDB_INVALID_REGNUM),
-    DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64,
-                    LLDB_INVALID_REGNUM),
-    DEFINE_FPR_INFO(config5, nullptr, dwarf_config5_mips64,
-                    dwarf_config5_mips64, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w0, nullptr, dwarf_w0_mips64, dwarf_w0_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w1, nullptr, dwarf_w1_mips64, dwarf_w1_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w2, nullptr, dwarf_w2_mips64, dwarf_w2_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w3, nullptr, dwarf_w3_mips64, dwarf_w3_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w4, nullptr, dwarf_w4_mips64, dwarf_w4_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w5, nullptr, dwarf_w5_mips64, dwarf_w5_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w6, nullptr, dwarf_w6_mips64, dwarf_w6_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w7, nullptr, dwarf_w7_mips64, dwarf_w7_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w8, nullptr, dwarf_w8_mips64, dwarf_w8_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w9, nullptr, dwarf_w9_mips64, dwarf_w9_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w10, nullptr, dwarf_w10_mips64, dwarf_w10_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w11, nullptr, dwarf_w11_mips64, dwarf_w11_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w12, nullptr, dwarf_w12_mips64, dwarf_w12_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w13, nullptr, dwarf_w13_mips64, dwarf_w13_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w14, nullptr, dwarf_w14_mips64, dwarf_w14_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w15, nullptr, dwarf_w15_mips64, dwarf_w15_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w16, nullptr, dwarf_w16_mips64, dwarf_w16_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w17, nullptr, dwarf_w17_mips64, dwarf_w17_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w18, nullptr, dwarf_w18_mips64, dwarf_w18_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w19, nullptr, dwarf_w19_mips64, dwarf_w19_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w20, nullptr, dwarf_w10_mips64, dwarf_w20_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w21, nullptr, dwarf_w21_mips64, dwarf_w21_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w22, nullptr, dwarf_w22_mips64, dwarf_w22_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w23, nullptr, dwarf_w23_mips64, dwarf_w23_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w24, nullptr, dwarf_w24_mips64, dwarf_w24_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w25, nullptr, dwarf_w25_mips64, dwarf_w25_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w26, nullptr, dwarf_w26_mips64, dwarf_w26_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w27, nullptr, dwarf_w27_mips64, dwarf_w27_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w28, nullptr, dwarf_w28_mips64, dwarf_w28_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w29, nullptr, dwarf_w29_mips64, dwarf_w29_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w30, nullptr, dwarf_w30_mips64, dwarf_w30_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA(w31, nullptr, dwarf_w31_mips64, dwarf_w31_mips64,
-               LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA_INFO(mcsr, nullptr, dwarf_mcsr_mips64, dwarf_mcsr_mips64,
-                    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA_INFO(mir, nullptr, dwarf_mir_mips64, dwarf_mir_mips64,
-                    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64,
-                    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64,
-                    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-    DEFINE_MSA_INFO(config5, nullptr, dwarf_config5_mips64,
-                    dwarf_config5_mips64, LLDB_INVALID_REGNUM,
-                    LLDB_INVALID_REGNUM)
-#endif
 };
 
 static_assert((sizeof(g_register_infos_mips64) /
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 51be31f..04b4171 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -6,12 +6,12 @@
 //
 //===---------------------------------------------------------------------===//
 
-#include <stddef.h>
+#include <cstddef>
 
 // Computes the offset of the given GPR in the user data area.
 #define GPR_OFFSET(regname) (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define FPR_OFFSET(regname) (sizeof(GPR) + offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (sizeof(GPR) + sizeof(FPR) + offsetof(VMX, regname))
 #define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
 
 #ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
index 1086d3d..059dba4 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
@@ -8,7 +8,7 @@
 
 #ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT
 
-#include <stddef.h>
+#include <cstddef>
 
 // Computes the offset of the given GPR_PPC64 in the user data area.
 #define GPR_PPC64_OFFSET(regname) (offsetof(GPR_PPC64, regname))
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
index 0b099a5..9937da2 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -8,7 +8,7 @@
 
 #ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
 
-#include <stddef.h>
+#include <cstddef>
 
 // Computes the offset of the given GPR in the user data area.
 #define GPR_OFFSET(regname) (offsetof(GPR, regname))
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
index 11344ff..d1df7c6 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stddef.h>
+#include <cstddef>
 
 #include "llvm/Support/Compiler.h"
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/src/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 2d8e8ef..85785a2 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -509,7 +509,7 @@
         // operating system thread ID, so we can't make any assumptions about
         // the thread ID so we must always report the breakpoint regardless
         // of the thread.
-        if (bp_site_sp->ValidForThisThread(&thread) ||
+        if (bp_site_sp->ValidForThisThread(thread) ||
             thread.GetProcess()->GetOperatingSystem() != nullptr)
           return StopInfo::CreateStopReasonWithBreakpointSiteID(
               thread, bp_site_sp->GetID());
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h b/src/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
deleted file mode 100644
index 348af27..0000000
--- a/src/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-linux-register-enums.h
+++ /dev/null
@@ -1,360 +0,0 @@
-//===-- lldb-mips-linux-register-enums.h -------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
-#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
-
-namespace lldb_private {
-// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
-
-// Internal codes for all mips registers.
-enum {
-  k_first_gpr_mips,
-  gpr_zero_mips = k_first_gpr_mips,
-  gpr_r1_mips,
-  gpr_r2_mips,
-  gpr_r3_mips,
-  gpr_r4_mips,
-  gpr_r5_mips,
-  gpr_r6_mips,
-  gpr_r7_mips,
-  gpr_r8_mips,
-  gpr_r9_mips,
-  gpr_r10_mips,
-  gpr_r11_mips,
-  gpr_r12_mips,
-  gpr_r13_mips,
-  gpr_r14_mips,
-  gpr_r15_mips,
-  gpr_r16_mips,
-  gpr_r17_mips,
-  gpr_r18_mips,
-  gpr_r19_mips,
-  gpr_r20_mips,
-  gpr_r21_mips,
-  gpr_r22_mips,
-  gpr_r23_mips,
-  gpr_r24_mips,
-  gpr_r25_mips,
-  gpr_r26_mips,
-  gpr_r27_mips,
-  gpr_gp_mips,
-  gpr_sp_mips,
-  gpr_r30_mips,
-  gpr_ra_mips,
-  gpr_sr_mips,
-  gpr_mullo_mips,
-  gpr_mulhi_mips,
-  gpr_badvaddr_mips,
-  gpr_cause_mips,
-  gpr_pc_mips,
-  gpr_config5_mips,
-
-  k_last_gpr_mips = gpr_config5_mips,
-
-  k_first_fpr_mips,
-  fpr_f0_mips = k_first_fpr_mips,
-  fpr_f1_mips,
-  fpr_f2_mips,
-  fpr_f3_mips,
-  fpr_f4_mips,
-  fpr_f5_mips,
-  fpr_f6_mips,
-  fpr_f7_mips,
-  fpr_f8_mips,
-  fpr_f9_mips,
-  fpr_f10_mips,
-  fpr_f11_mips,
-  fpr_f12_mips,
-  fpr_f13_mips,
-  fpr_f14_mips,
-  fpr_f15_mips,
-  fpr_f16_mips,
-  fpr_f17_mips,
-  fpr_f18_mips,
-  fpr_f19_mips,
-  fpr_f20_mips,
-  fpr_f21_mips,
-  fpr_f22_mips,
-  fpr_f23_mips,
-  fpr_f24_mips,
-  fpr_f25_mips,
-  fpr_f26_mips,
-  fpr_f27_mips,
-  fpr_f28_mips,
-  fpr_f29_mips,
-  fpr_f30_mips,
-  fpr_f31_mips,
-  fpr_fcsr_mips,
-  fpr_fir_mips,
-  fpr_config5_mips,
-  k_last_fpr_mips = fpr_config5_mips,
-
-  k_first_msa_mips,
-  msa_w0_mips = k_first_msa_mips,
-  msa_w1_mips,
-  msa_w2_mips,
-  msa_w3_mips,
-  msa_w4_mips,
-  msa_w5_mips,
-  msa_w6_mips,
-  msa_w7_mips,
-  msa_w8_mips,
-  msa_w9_mips,
-  msa_w10_mips,
-  msa_w11_mips,
-  msa_w12_mips,
-  msa_w13_mips,
-  msa_w14_mips,
-  msa_w15_mips,
-  msa_w16_mips,
-  msa_w17_mips,
-  msa_w18_mips,
-  msa_w19_mips,
-  msa_w20_mips,
-  msa_w21_mips,
-  msa_w22_mips,
-  msa_w23_mips,
-  msa_w24_mips,
-  msa_w25_mips,
-  msa_w26_mips,
-  msa_w27_mips,
-  msa_w28_mips,
-  msa_w29_mips,
-  msa_w30_mips,
-  msa_w31_mips,
-  msa_fcsr_mips,
-  msa_fir_mips,
-  msa_mcsr_mips,
-  msa_mir_mips,
-  msa_config5_mips,
-  k_last_msa_mips = msa_config5_mips,
-
-  k_num_registers_mips,
-
-  k_num_gpr_registers_mips = k_last_gpr_mips - k_first_gpr_mips + 1,
-  k_num_fpr_registers_mips = k_last_fpr_mips - k_first_fpr_mips + 1,
-  k_num_msa_registers_mips = k_last_msa_mips - k_first_msa_mips + 1,
-  k_num_user_registers_mips = k_num_gpr_registers_mips +
-                              k_num_fpr_registers_mips +
-                              k_num_msa_registers_mips
-};
-
-// Internal codes for all mips64 registers.
-enum {
-  k_first_gpr_mips64,
-  gpr_zero_mips64 = k_first_gpr_mips64,
-  gpr_r1_mips64,
-  gpr_r2_mips64,
-  gpr_r3_mips64,
-  gpr_r4_mips64,
-  gpr_r5_mips64,
-  gpr_r6_mips64,
-  gpr_r7_mips64,
-  gpr_r8_mips64,
-  gpr_r9_mips64,
-  gpr_r10_mips64,
-  gpr_r11_mips64,
-  gpr_r12_mips64,
-  gpr_r13_mips64,
-  gpr_r14_mips64,
-  gpr_r15_mips64,
-  gpr_r16_mips64,
-  gpr_r17_mips64,
-  gpr_r18_mips64,
-  gpr_r19_mips64,
-  gpr_r20_mips64,
-  gpr_r21_mips64,
-  gpr_r22_mips64,
-  gpr_r23_mips64,
-  gpr_r24_mips64,
-  gpr_r25_mips64,
-  gpr_r26_mips64,
-  gpr_r27_mips64,
-  gpr_gp_mips64,
-  gpr_sp_mips64,
-  gpr_r30_mips64,
-  gpr_ra_mips64,
-  gpr_sr_mips64,
-  gpr_mullo_mips64,
-  gpr_mulhi_mips64,
-  gpr_badvaddr_mips64,
-  gpr_cause_mips64,
-  gpr_pc_mips64,
-  gpr_config5_mips64,
-  k_last_gpr_mips64 = gpr_config5_mips64,
-
-  k_first_fpr_mips64,
-  fpr_f0_mips64 = k_first_fpr_mips64,
-  fpr_f1_mips64,
-  fpr_f2_mips64,
-  fpr_f3_mips64,
-  fpr_f4_mips64,
-  fpr_f5_mips64,
-  fpr_f6_mips64,
-  fpr_f7_mips64,
-  fpr_f8_mips64,
-  fpr_f9_mips64,
-  fpr_f10_mips64,
-  fpr_f11_mips64,
-  fpr_f12_mips64,
-  fpr_f13_mips64,
-  fpr_f14_mips64,
-  fpr_f15_mips64,
-  fpr_f16_mips64,
-  fpr_f17_mips64,
-  fpr_f18_mips64,
-  fpr_f19_mips64,
-  fpr_f20_mips64,
-  fpr_f21_mips64,
-  fpr_f22_mips64,
-  fpr_f23_mips64,
-  fpr_f24_mips64,
-  fpr_f25_mips64,
-  fpr_f26_mips64,
-  fpr_f27_mips64,
-  fpr_f28_mips64,
-  fpr_f29_mips64,
-  fpr_f30_mips64,
-  fpr_f31_mips64,
-  fpr_fcsr_mips64,
-  fpr_fir_mips64,
-  fpr_config5_mips64,
-  k_last_fpr_mips64 = fpr_config5_mips64,
-
-  k_first_msa_mips64,
-  msa_w0_mips64 = k_first_msa_mips64,
-  msa_w1_mips64,
-  msa_w2_mips64,
-  msa_w3_mips64,
-  msa_w4_mips64,
-  msa_w5_mips64,
-  msa_w6_mips64,
-  msa_w7_mips64,
-  msa_w8_mips64,
-  msa_w9_mips64,
-  msa_w10_mips64,
-  msa_w11_mips64,
-  msa_w12_mips64,
-  msa_w13_mips64,
-  msa_w14_mips64,
-  msa_w15_mips64,
-  msa_w16_mips64,
-  msa_w17_mips64,
-  msa_w18_mips64,
-  msa_w19_mips64,
-  msa_w20_mips64,
-  msa_w21_mips64,
-  msa_w22_mips64,
-  msa_w23_mips64,
-  msa_w24_mips64,
-  msa_w25_mips64,
-  msa_w26_mips64,
-  msa_w27_mips64,
-  msa_w28_mips64,
-  msa_w29_mips64,
-  msa_w30_mips64,
-  msa_w31_mips64,
-  msa_fcsr_mips64,
-  msa_fir_mips64,
-  msa_mcsr_mips64,
-  msa_mir_mips64,
-  msa_config5_mips64,
-  k_last_msa_mips64 = msa_config5_mips64,
-
-  k_num_registers_mips64,
-
-  k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
-  k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
-  k_num_msa_registers_mips64 = k_last_msa_mips64 - k_first_msa_mips64 + 1,
-  k_num_user_registers_mips64 = k_num_gpr_registers_mips64 +
-                                k_num_fpr_registers_mips64 +
-                                k_num_msa_registers_mips64
-};
-
-// Register no. for RegisterKind = eRegisterKindProcessPlugin
-// The ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER used this number
-enum {
-  ptrace_zero_mips,
-  ptrace_r1_mips,
-  ptrace_r2_mips,
-  ptrace_r3_mips,
-  ptrace_r4_mips,
-  ptrace_r5_mips,
-  ptrace_r6_mips,
-  ptrace_r7_mips,
-  ptrace_r8_mips,
-  ptrace_r9_mips,
-  ptrace_r10_mips,
-  ptrace_r11_mips,
-  ptrace_r12_mips,
-  ptrace_r13_mips,
-  ptrace_r14_mips,
-  ptrace_r15_mips,
-  ptrace_r16_mips,
-  ptrace_r17_mips,
-  ptrace_r18_mips,
-  ptrace_r19_mips,
-  ptrace_r20_mips,
-  ptrace_r21_mips,
-  ptrace_r22_mips,
-  ptrace_r23_mips,
-  ptrace_r24_mips,
-  ptrace_r25_mips,
-  ptrace_r26_mips,
-  ptrace_r27_mips,
-  ptrace_gp_mips,
-  ptrace_sp_mips,
-  ptrace_r30_mips,
-  ptrace_ra_mips,
-  ptrace_f0_mips,
-  ptrace_f1_mips,
-  ptrace_f2_mips,
-  ptrace_f3_mips,
-  ptrace_f4_mips,
-  ptrace_f5_mips,
-  ptrace_f6_mips,
-  ptrace_f7_mips,
-  ptrace_f8_mips,
-  ptrace_f9_mips,
-  ptrace_f10_mips,
-  ptrace_f11_mips,
-  ptrace_f12_mips,
-  ptrace_f13_mips,
-  ptrace_f14_mips,
-  ptrace_f15_mips,
-  ptrace_f16_mips,
-  ptrace_f17_mips,
-  ptrace_f18_mips,
-  ptrace_f19_mips,
-  ptrace_f20_mips,
-  ptrace_f21_mips,
-  ptrace_f22_mips,
-  ptrace_f23_mips,
-  ptrace_f24_mips,
-  ptrace_f25_mips,
-  ptrace_f26_mips,
-  ptrace_f27_mips,
-  ptrace_f28_mips,
-  ptrace_f29_mips,
-  ptrace_f30_mips,
-  ptrace_f31_mips,
-  ptrace_pc_mips,
-  ptrace_cause_mips,
-  ptrace_badvaddr_mips,
-  ptrace_mulhi_mips,
-  ptrace_mullo_mips,
-  ptrace_fcsr_mips,
-  ptrace_fir_mips,
-  ptrace_sr_mips,
-  ptrace_config5_mips
-};
-}
-
-#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_LINUX_REGISTER_ENUMS_H
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
index 8205c8e..1294928 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
@@ -98,7 +98,8 @@
 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
   assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
          "Register setting path assumes this is a 64-bit host");
-  return new RegisterInfoPOSIX_arm64(target_arch);
+  return new RegisterInfoPOSIX_arm64(
+      target_arch, RegisterInfoPOSIX_arm64::eRegsetMaskDefault);
 }
 
 static Status GetThreadContextHelper(lldb::thread_t thread_handle,
diff --git a/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 899d090..379496b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -86,10 +86,10 @@
 
 static bool ShouldUseLLDBServer() {
   llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER");
-  return use_lldb_server.equals_lower("on") ||
-         use_lldb_server.equals_lower("yes") ||
-         use_lldb_server.equals_lower("1") ||
-         use_lldb_server.equals_lower("true");
+  return use_lldb_server.equals_insensitive("on") ||
+         use_lldb_server.equals_insensitive("yes") ||
+         use_lldb_server.equals_insensitive("1") ||
+         use_lldb_server.equals_insensitive("true");
 }
 
 void ProcessWindows::Initialize() {
@@ -394,7 +394,7 @@
     RegisterContextSP register_context = stop_thread->GetRegisterContext();
     const uint64_t pc = register_context->GetPC();
     BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
-    if (site && site->ValidForThisThread(stop_thread.get())) {
+    if (site && site->ValidForThisThread(*stop_thread)) {
       LLDB_LOG(log,
                "Single-stepped onto a breakpoint in process {0} at "
                "address {1:x} with breakpoint site {2}",
@@ -449,7 +449,7 @@
                m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
                site->GetID());
 
-      if (site->ValidForThisThread(stop_thread.get())) {
+      if (site->ValidForThisThread(*stop_thread)) {
         LLDB_LOG(log,
                  "Breakpoint site {0} is valid for this thread ({1:x}), "
                  "creating stop info.",
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index ae19367..12bc739 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include <memory>
 #include <mutex>
@@ -353,7 +353,6 @@
   const lldb::addr_t file_end = address_range->data.GetRangeEnd();
   size_t bytes_to_read = size; // Number of bytes to read from the core file
   size_t bytes_copied = 0;   // Number of bytes actually read from the core file
-  size_t zero_fill_size = 0; // Padding
   lldb::addr_t bytes_left =
       0; // Number of bytes available in the core file from the given address
 
@@ -367,24 +366,15 @@
   if (file_end > file_start + offset)
     bytes_left = file_end - (file_start + offset);
 
-  // Figure out how many bytes we need to zero-fill if we are reading more
-  // bytes than available in the on-disk segment
-  if (bytes_to_read > bytes_left) {
-    zero_fill_size = bytes_to_read - bytes_left;
+  if (bytes_to_read > bytes_left)
     bytes_to_read = bytes_left;
-  }
 
   // If there is data available on the core file read it
   if (bytes_to_read)
     bytes_copied =
         core_objfile->CopyData(offset + file_start, bytes_to_read, buf);
 
-  assert(zero_fill_size <= size);
-  // Pad remaining bytes
-  if (zero_fill_size)
-    memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
-
-  return bytes_copied + zero_fill_size;
+  return bytes_copied;
 }
 
 void ProcessElfCore::Clear() {
@@ -414,12 +404,8 @@
 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
 static void ParseFreeBSDPrStatus(ThreadData &thread_data,
                                  const DataExtractor &data,
-                                 const ArchSpec &arch) {
+                                 bool lp64) {
   lldb::offset_t offset = 0;
-  bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
-               arch.GetMachine() == llvm::Triple::mips64 ||
-               arch.GetMachine() == llvm::Triple::ppc64 ||
-               arch.GetMachine() == llvm::Triple::x86_64);
   int pr_version = data.GetU32(&offset);
 
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
@@ -443,6 +429,27 @@
   thread_data.gpregset = DataExtractor(data, offset, len);
 }
 
+// Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
+static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
+                                 const DataExtractor &data,
+                                 bool lp64) {
+  lldb::offset_t offset = 0;
+  int pr_version = data.GetU32(&offset);
+
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log) {
+    if (pr_version > 1)
+      LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version);
+  }
+
+  // Skip pr_psinfosz, pr_fname, pr_psargs
+  offset += 108;
+  if (lp64)
+    offset += 4;
+
+  process.SetID(data.GetU32(&offset)); // pr_pid
+}
+
 static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
                                        uint32_t &cpi_nlwps,
                                        uint32_t &cpi_signo,
@@ -522,6 +529,11 @@
 }
 
 llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
+  ArchSpec arch = GetArchitecture();
+  bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
+               arch.GetMachine() == llvm::Triple::mips64 ||
+               arch.GetMachine() == llvm::Triple::ppc64 ||
+               arch.GetMachine() == llvm::Triple::x86_64);
   bool have_prstatus = false;
   bool have_prpsinfo = false;
   ThreadData thread_data;
@@ -542,10 +554,11 @@
     switch (note.info.n_type) {
     case ELF::NT_PRSTATUS:
       have_prstatus = true;
-      ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
+      ParseFreeBSDPrStatus(thread_data, note.data, lp64);
       break;
     case ELF::NT_PRPSINFO:
       have_prpsinfo = true;
+      ParseFreeBSDPrPsInfo(*this, note.data, lp64);
       break;
     case ELF::NT_FREEBSD_THRMISC: {
       lldb::offset_t offset = 0;
@@ -651,6 +664,32 @@
           thread_data.notes.push_back(note);
         }
       } break;
+      case llvm::Triple::x86: {
+        // Assume order PT_GETREGS, PT_GETFPREGS
+        if (note.info.n_type == NETBSD::I386::NT_REGS) {
+          // If this is the next thread, push the previous one first.
+          if (had_nt_regs) {
+            m_thread_data.push_back(thread_data);
+            thread_data = ThreadData();
+            had_nt_regs = false;
+          }
+
+          thread_data.gpregset = note.data;
+          thread_data.tid = tid;
+          if (thread_data.gpregset.GetByteSize() == 0)
+            return llvm::make_error<llvm::StringError>(
+                "Could not find general purpose registers note in core file.",
+                llvm::inconvertibleErrorCode());
+          had_nt_regs = true;
+        } else if (note.info.n_type == NETBSD::I386::NT_FPREGS) {
+          if (!had_nt_regs || tid != thread_data.tid)
+            return llvm::make_error<llvm::StringError>(
+                "Error parsing NetBSD core(5) notes: Unexpected order "
+                "of NOTEs PT_GETFPREG before PT_GETREG",
+                llvm::inconvertibleErrorCode());
+          thread_data.notes.push_back(note);
+        }
+      } break;
       case llvm::Triple::x86_64: {
         // Assume order PT_GETREGS, PT_GETFPREGS
         if (note.info.n_type == NETBSD::AMD64::NT_REGS) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 2f71f17..f0aee04 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -25,7 +25,7 @@
   m_gpr.SetByteOrder(gpregset.GetByteOrder());
 }
 
-RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() {}
+RegisterContextCorePOSIX_arm::~RegisterContextCorePOSIX_arm() = default;
 
 bool RegisterContextCorePOSIX_arm::ReadGPR() { return true; }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 129a887..e56aa88 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -17,26 +17,52 @@
 
 using namespace lldb_private;
 
+std::unique_ptr<RegisterContextCorePOSIX_arm64>
+RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
+                                       const DataExtractor &gpregset,
+                                       llvm::ArrayRef<CoreNote> notes) {
+  Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault;
+
+  DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
+  if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+  // Pointer Authentication register set data is based on struct
+  // user_pac_mask declared in ptrace.h. See reference implementation
+  // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h.
+  DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc);
+  if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2)
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
+
+  auto register_info_up =
+      std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
+  return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
+      new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up),
+                                         gpregset, notes));
+}
+
 RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
     Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
     const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
     : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
-  m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
-                                                  gpregset.GetByteSize());
-  m_gpr.SetData(m_gpr_buffer);
-  m_gpr.SetByteOrder(gpregset.GetByteOrder());
+  m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+                                                      gpregset.GetByteSize()));
+  m_gpr_data.SetByteOrder(gpregset.GetByteOrder());
 
-  m_fpregset = getRegset(
-      notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
+  const llvm::Triple &target_triple =
+      m_register_info_up->GetTargetArchitecture().GetTriple();
+  m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
 
-  m_sveregset =
-      getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(),
-                AARCH64_SVE_Desc);
+  if (m_register_info_up->IsSVEEnabled())
+    m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
+
+  if (m_register_info_up->IsPAuthEnabled())
+    m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
 
   ConfigureRegisterContext();
 }
 
-RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
+RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() = default;
 
 bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; }
 
@@ -53,16 +79,16 @@
 }
 
 const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
-  return m_sveregset.GetDataStart() + offset;
+  return m_sve_data.GetDataStart() + offset;
 }
 
 void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
-  if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) {
+  if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) {
     uint64_t sve_header_field_offset = 8;
-    m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset);
+    m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
     sve_header_field_offset = 12;
     uint16_t sve_header_flags_field =
-        m_sveregset.GetU16(&sve_header_field_offset);
+        m_sve_data.GetU16(&sve_header_field_offset);
     if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
         sve::ptrace_regs_fpsimd)
       m_sve_state = SVEState::FPSIMD;
@@ -70,15 +96,16 @@
              sve::ptrace_regs_sve)
       m_sve_state = SVEState::Full;
 
-    if (sve::vl_valid(m_sve_vector_length))
-      m_register_info_up->ConfigureVectorRegisterInfos(
-          sve::vq_from_vl(m_sve_vector_length));
-    else {
+    if (!sve::vl_valid(m_sve_vector_length)) {
       m_sve_state = SVEState::Disabled;
       m_sve_vector_length = 0;
     }
   } else
     m_sve_state = SVEState::Disabled;
+
+  if (m_sve_state != SVEState::Disabled)
+    m_register_info_up->ConfigureVectorLength(
+        sve::vq_from_vl(m_sve_vector_length));
 }
 
 uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
@@ -104,7 +131,7 @@
 
   offset = reg_info->byte_offset;
   if (offset + reg_info->byte_size <= GetGPRSize()) {
-    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+    uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size);
     if (offset == reg_info->byte_offset + reg_info->byte_size) {
       value = v;
       return true;
@@ -119,8 +146,8 @@
     if (m_sve_state == SVEState::Disabled) {
       // SVE is disabled take legacy route for FPU register access
       offset -= GetGPRSize();
-      if (offset < m_fpregset.GetByteSize()) {
-        value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+      if (offset < m_fpr_data.GetByteSize()) {
+        value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset,
                                 reg_info->byte_size, lldb::eByteOrderLittle,
                                 error);
         return error.Success();
@@ -152,7 +179,7 @@
       }
 
       assert(sve_reg_num != LLDB_INVALID_REGNUM);
-      assert(offset < m_sveregset.GetByteSize());
+      assert(offset < m_sve_data.GetByteSize());
       value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
                               reg_info->byte_size, lldb::eByteOrderLittle,
                               error);
@@ -174,7 +201,7 @@
       if (IsSVEZ(reg)) {
         byte_size = 16;
         offset = CalculateSVEOffset(reg_info);
-        assert(offset < m_sveregset.GetByteSize());
+        assert(offset < m_sve_data.GetByteSize());
         src = GetSVEBuffer(offset);
       }
       value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
@@ -182,7 +209,7 @@
     } break;
     case SVEState::Full:
       offset = CalculateSVEOffset(reg_info);
-      assert(offset < m_sveregset.GetByteSize());
+      assert(offset < m_sve_data.GetByteSize());
       value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
                               reg_info->byte_size, lldb::eByteOrderLittle,
                               error);
@@ -191,6 +218,11 @@
     default:
       return false;
     }
+  } else if (IsPAuth(reg)) {
+    offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset();
+    assert(offset < m_pac_data.GetByteSize());
+    value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset,
+                            reg_info->byte_size, lldb::eByteOrderLittle, error);
   } else
     return false;
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index a4fdc4f..3988e35 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -18,11 +18,10 @@
 
 class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
 public:
-  RegisterContextCorePOSIX_arm64(
-      lldb_private::Thread &thread,
-      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
-      const lldb_private::DataExtractor &gpregset,
-      llvm::ArrayRef<lldb_private::CoreNote> notes);
+  static std::unique_ptr<RegisterContextCorePOSIX_arm64>
+  Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch,
+         const lldb_private::DataExtractor &gpregset,
+         llvm::ArrayRef<lldb_private::CoreNote> notes);
 
   ~RegisterContextCorePOSIX_arm64() override;
 
@@ -39,6 +38,12 @@
   bool HardwareSingleStep(bool enable) override;
 
 protected:
+  RegisterContextCorePOSIX_arm64(
+      lldb_private::Thread &thread,
+      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
+      const lldb_private::DataExtractor &gpregset,
+      llvm::ArrayRef<lldb_private::CoreNote> notes);
+
   bool ReadGPR() override;
 
   bool ReadFPR() override;
@@ -48,10 +53,10 @@
   bool WriteFPR() override;
 
 private:
-  lldb::DataBufferSP m_gpr_buffer;
-  lldb_private::DataExtractor m_gpr;
-  lldb_private::DataExtractor m_fpregset;
-  lldb_private::DataExtractor m_sveregset;
+  lldb_private::DataExtractor m_gpr_data;
+  lldb_private::DataExtractor m_fpr_data;
+  lldb_private::DataExtractor m_sve_data;
+  lldb_private::DataExtractor m_pac_data;
 
   SVEState m_sve_state;
   uint16_t m_sve_vector_length = 0;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index b5b83d8..5b1eb8b 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -32,7 +32,7 @@
   m_fpr.SetByteOrder(fpregset.GetByteOrder());
 }
 
-RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() {}
+RegisterContextCorePOSIX_mips64::~RegisterContextCorePOSIX_mips64() = default;
 
 bool RegisterContextCorePOSIX_mips64::ReadGPR() { return true; }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index e15cd47..8380731 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -39,7 +39,7 @@
   m_vec.SetByteOrder(vregset.GetByteOrder());
 }
 
-RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() {}
+RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() = default;
 
 bool RegisterContextCorePOSIX_powerpc::ReadGPR() { return true; }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index c3aa92c..f1cd689 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -33,7 +33,7 @@
   m_fpr.SetByteOrder(fpregset.GetByteOrder());
 }
 
-RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() {}
+RegisterContextCorePOSIX_s390x::~RegisterContextCorePOSIX_s390x() = default;
 
 bool RegisterContextCorePOSIX_s390x::ReadGPR() { return true; }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index 25abd7e..f6a2fbd 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -55,6 +55,10 @@
 enum { NT_REGS = 33, NT_FPREGS = 35 };
 }
 
+namespace I386 {
+enum { NT_REGS = 33, NT_FPREGS = 35 };
+}
+
 } // namespace NETBSD
 
 namespace OPENBSD {
@@ -96,6 +100,9 @@
                         llvm::ArrayRef<RegsetDesc> RegsetDescs);
 
 constexpr RegsetDesc FPR_Desc[] = {
+    // FreeBSD/i386 core NT_FPREGSET is x87 FSAVE result but the XSAVE dump
+    // starts with FXSAVE struct, so use that instead if available.
+    {llvm::Triple::FreeBSD, llvm::Triple::x86, llvm::ELF::NT_X86_XSTATE},
     {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
     // In a i386 core file NT_FPREGSET is present, but it's not the result
     // of the FXSAVE instruction like in 64 bit files.
@@ -103,6 +110,7 @@
     {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
     {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
     {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
+    {llvm::Triple::NetBSD, llvm::Triple::x86, NETBSD::I386::NT_FPREGS},
     {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
     {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
 };
@@ -111,6 +119,10 @@
     {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
 };
 
+constexpr RegsetDesc AARCH64_PAC_Desc[] = {
+    {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
+};
+
 constexpr RegsetDesc PPC_VMX_Desc[] = {
     {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
     {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
diff --git a/src/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/src/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 76c0c28..937d074 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -18,10 +18,9 @@
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include "Plugins/Process/Utility/RegisterContextNetBSD_i386.h"
 #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
 #include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h"
 #include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
@@ -109,6 +108,9 @@
       switch (arch.GetMachine()) {
       case llvm::Triple::aarch64:
         break;
+      case llvm::Triple::x86:
+        reg_interface = new RegisterContextNetBSD_i386(arch);
+        break;
       case llvm::Triple::x86_64:
         reg_interface = new RegisterContextNetBSD_x86_64(arch);
         break;
@@ -122,14 +124,6 @@
       switch (arch.GetMachine()) {
       case llvm::Triple::aarch64:
         break;
-      case llvm::Triple::mipsel:
-      case llvm::Triple::mips:
-        reg_interface = new RegisterContextLinux_mips(arch);
-        break;
-      case llvm::Triple::mips64el:
-      case llvm::Triple::mips64:
-        reg_interface = new RegisterContextLinux_mips64(arch);
-        break;
       case llvm::Triple::ppc64le:
         reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
         break;
@@ -177,9 +171,8 @@
 
     switch (arch.GetMachine()) {
     case llvm::Triple::aarch64:
-      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>(
-          *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch),
-          m_gpregset_data, m_notes);
+      m_thread_reg_ctx_sp = RegisterContextCorePOSIX_arm64::Create(
+          *this, arch, m_gpregset_data, m_notes);
       break;
     case llvm::Triple::arm:
       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index fdaa60e..a4c71e8 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -20,7 +20,10 @@
 using namespace lldb_private::process_gdb_remote;
 using namespace std::chrono;
 
-static const seconds kInterruptTimeout(5);
+// When we've sent a continue packet and are waiting for the target to stop,
+// we wake up the wait with this interval to make sure the stub hasn't gone
+// away while we were waiting.
+static const seconds kWakeupInterval(5);
 
 /////////////////////////
 // GDBRemoteClientBase //
@@ -35,7 +38,8 @@
 
 StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
     ContinueDelegate &delegate, const UnixSignals &signals,
-    llvm::StringRef payload, StringExtractorGDBRemote &response) {
+    llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+    StringExtractorGDBRemote &response) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
   response.Clear();
 
@@ -48,16 +52,37 @@
   if (!cont_lock)
     return eStateInvalid;
   OnRunPacketSent(true);
-
+  // The main ReadPacket loop wakes up at computed_timeout intervals, just to 
+  // check that the connection hasn't dropped.  When we wake up we also check
+  // whether there is an interrupt request that has reached its endpoint.
+  // If we want a shorter interrupt timeout that kWakeupInterval, we need to 
+  // choose the shorter interval for the wake up as well.
+  std::chrono::seconds computed_timeout = std::min(interrupt_timeout, 
+                                                   kWakeupInterval);
   for (;;) {
-    PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
+    PacketResult read_result = ReadPacket(response, computed_timeout, false);
+    // Reset the computed_timeout to the default value in case we are going
+    // round again.
+    computed_timeout = std::min(interrupt_timeout, kWakeupInterval);
     switch (read_result) {
     case PacketResult::ErrorReplyTimeout: {
       std::lock_guard<std::mutex> lock(m_mutex);
-      if (m_async_count == 0)
+      if (m_async_count == 0) {
         continue;
-      if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
+      }
+      auto cur_time = steady_clock::now();
+      if (cur_time >= m_interrupt_endpoint)
         return eStateInvalid;
+      else {
+        // We woke up and found an interrupt is in flight, but we haven't
+        // exceeded the interrupt wait time.  So reset the wait time to the
+        // time left till the interrupt timeout.  But don't wait longer
+        // than our wakeup timeout.
+        auto new_wait = m_interrupt_endpoint - cur_time;
+        computed_timeout = std::min(kWakeupInterval,
+            std::chrono::duration_cast<std::chrono::seconds>(new_wait));
+        continue;
+      }
       break;
     }
     case PacketResult::Success:
@@ -133,8 +158,9 @@
   }
 }
 
-bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
-  Lock lock(*this, true);
+bool GDBRemoteClientBase::SendAsyncSignal(
+    int signo, std::chrono::seconds interrupt_timeout) {
+  Lock lock(*this, interrupt_timeout);
   if (!lock || !lock.DidInterrupt())
     return false;
 
@@ -144,25 +170,26 @@
   return true;
 }
 
-bool GDBRemoteClientBase::Interrupt() {
-  Lock lock(*this, true);
+bool GDBRemoteClientBase::Interrupt(std::chrono::seconds interrupt_timeout) {
+  Lock lock(*this, interrupt_timeout);
   if (!lock.DidInterrupt())
     return false;
   m_should_stop = true;
   return true;
 }
+
 GDBRemoteCommunication::PacketResult
 GDBRemoteClientBase::SendPacketAndWaitForResponse(
     llvm::StringRef payload, StringExtractorGDBRemote &response,
-    bool send_async) {
-  Lock lock(*this, send_async);
+    std::chrono::seconds interrupt_timeout) {
+  Lock lock(*this, interrupt_timeout);
   if (!lock) {
     if (Log *log =
             ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
       LLDB_LOGF(log,
                 "GDBRemoteClientBase::%s failed to get mutex, not sending "
-                "packet '%.*s' (send_async=%d)",
-                __FUNCTION__, int(payload.size()), payload.data(), send_async);
+                "packet '%.*s'",
+                __FUNCTION__, int(payload.size()), payload.data());
     return PacketResult::ErrorSendFailed;
   }
 
@@ -172,16 +199,16 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
     llvm::StringRef payload, StringExtractorGDBRemote &response,
-    bool send_async,
+    std::chrono::seconds interrupt_timeout,
     llvm::function_ref<void(llvm::StringRef)> output_callback) {
-  Lock lock(*this, send_async);
+  Lock lock(*this, interrupt_timeout);
   if (!lock) {
     if (Log *log =
             ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
       LLDB_LOGF(log,
                 "GDBRemoteClientBase::%s failed to get mutex, not sending "
-                "packet '%.*s' (send_async=%d)",
-                __FUNCTION__, int(payload.size()), payload.data(), send_async);
+                "packet '%.*s'",
+                __FUNCTION__, int(payload.size()), payload.data());
     return PacketResult::ErrorSendFailed;
   }
 
@@ -222,13 +249,14 @@
   return packet_result;
 }
 
-bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
-                                          StringExtractorGDBRemote &response) {
+bool GDBRemoteClientBase::SendvContPacket(
+    llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+    StringExtractorGDBRemote &response) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
   LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
 
   // we want to lock down packet sending while we continue
-  Lock lock(*this, true);
+  Lock lock(*this, interrupt_timeout);
 
   LLDB_LOGF(log,
             "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
@@ -336,18 +364,20 @@
 // GDBRemoteClientBase::Lock //
 ///////////////////////////////
 
-GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
+GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm,
+                                std::chrono::seconds interrupt_timeout)
     : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
-      m_acquired(false), m_did_interrupt(false) {
-  SyncWithContinueThread(interrupt);
+      m_interrupt_timeout(interrupt_timeout), m_acquired(false),
+      m_did_interrupt(false) {
+  SyncWithContinueThread();
   if (m_acquired)
     m_async_lock.lock();
 }
 
-void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
+void GDBRemoteClientBase::Lock::SyncWithContinueThread() {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
   std::unique_lock<std::mutex> lock(m_comm.m_mutex);
-  if (m_comm.m_is_running && !interrupt)
+  if (m_comm.m_is_running && m_interrupt_timeout == std::chrono::seconds(0))
     return; // We were asked to avoid interrupting the sender. Lock is not
             // acquired.
 
@@ -365,9 +395,9 @@
                        "interrupt packet");
         return;
       }
+      m_comm.m_interrupt_endpoint = steady_clock::now() + m_interrupt_timeout;
       if (log)
         log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
-      m_comm.m_interrupt_time = steady_clock::now();
     }
     m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
     m_did_interrupt = true;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index cd9f6eb..518b813 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -33,29 +33,46 @@
 
   GDBRemoteClientBase(const char *comm_name, const char *listener_name);
 
-  bool SendAsyncSignal(int signo);
+  bool SendAsyncSignal(int signo, std::chrono::seconds interrupt_timeout);
 
-  bool Interrupt();
+  bool Interrupt(std::chrono::seconds interrupt_timeout);
 
   lldb::StateType SendContinuePacketAndWaitForResponse(
       ContinueDelegate &delegate, const UnixSignals &signals,
-      llvm::StringRef payload, StringExtractorGDBRemote &response);
+      llvm::StringRef payload, std::chrono::seconds interrupt_timeout,
+      StringExtractorGDBRemote &response);
 
-  PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
-                                            StringExtractorGDBRemote &response,
-                                            bool send_async);
+  // If interrupt_timeout == 0 seconds, don't interrupt the target.
+  // Only send the packet if the target is stopped.
+  // If you want to use this mode, use the fact that the timeout is defaulted
+  // so it's clear from the call-site that you are using no-interrupt.
+  // If it is non-zero, interrupt the target if it is running, and
+  // send the packet.
+  // It the target doesn't respond within the given timeout, it returns
+  // ErrorReplyTimeout.
+  PacketResult SendPacketAndWaitForResponse(
+      llvm::StringRef payload, StringExtractorGDBRemote &response,
+      std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
 
   PacketResult SendPacketAndReceiveResponseWithOutputSupport(
       llvm::StringRef payload, StringExtractorGDBRemote &response,
-      bool send_async,
+      std::chrono::seconds interrupt_timeout,
       llvm::function_ref<void(llvm::StringRef)> output_callback);
 
   bool SendvContPacket(llvm::StringRef payload,
+                       std::chrono::seconds interrupt_timeout,
                        StringExtractorGDBRemote &response);
 
   class Lock {
   public:
-    Lock(GDBRemoteClientBase &comm, bool interrupt);
+    // If interrupt_timeout == 0 seconds, only take the lock if the target is
+    // not running. If using this option, use the fact that the
+    // interrupt_timeout is defaulted so it will be obvious at the call site
+    // that you are choosing this mode. If it is non-zero, interrupt the target
+    // if it is running, waiting for the given timeout for the interrupt to
+    // succeed.
+    Lock(GDBRemoteClientBase &comm,
+         std::chrono::seconds interrupt_timeout = std::chrono::seconds(0));
     ~Lock();
 
     explicit operator bool() { return m_acquired; }
@@ -67,10 +84,11 @@
   private:
     std::unique_lock<std::recursive_mutex> m_async_lock;
     GDBRemoteClientBase &m_comm;
+    std::chrono::seconds m_interrupt_timeout;
     bool m_acquired;
     bool m_did_interrupt;
 
-    void SyncWithContinueThread(bool interrupt);
+    void SyncWithContinueThread();
   };
 
 protected:
@@ -109,7 +127,7 @@
 
   /// When was the interrupt packet sent. Used to make sure we time out if the
   /// stub does not respond to interrupt requests.
-  std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+  std::chrono::time_point<std::chrono::steady_clock> m_interrupt_endpoint;
 
   /// Number of threads interested in sending.
   uint32_t m_async_count;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 4981345..013d407 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -8,9 +8,9 @@
 
 #include "GDBRemoteCommunication.h"
 
+#include <climits>
+#include <cstring>
 #include <future>
-#include <limits.h>
-#include <string.h>
 #include <sys/stat.h>
 
 #include "lldb/Core/StreamFile.h"
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d375a31..b16aed4 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -8,7 +8,7 @@
 
 #include "GDBRemoteCommunicationClient.h"
 
-#include <math.h>
+#include <cmath>
 #include <sys/stat.h>
 
 #include <numeric>
@@ -16,6 +16,7 @@
 
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
 #include "lldb/Host/XML.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/MemoryRegionInfo.h"
@@ -55,40 +56,7 @@
 // GDBRemoteCommunicationClient constructor
 GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
     : GDBRemoteClientBase("gdb-remote.client", "gdb-remote.client.rx_packet"),
-      m_supports_not_sending_acks(eLazyBoolCalculate),
-      m_supports_thread_suffix(eLazyBoolCalculate),
-      m_supports_threads_in_stop_reply(eLazyBoolCalculate),
-      m_supports_vCont_all(eLazyBoolCalculate),
-      m_supports_vCont_any(eLazyBoolCalculate),
-      m_supports_vCont_c(eLazyBoolCalculate),
-      m_supports_vCont_C(eLazyBoolCalculate),
-      m_supports_vCont_s(eLazyBoolCalculate),
-      m_supports_vCont_S(eLazyBoolCalculate),
-      m_qHostInfo_is_valid(eLazyBoolCalculate),
-      m_curr_pid_is_valid(eLazyBoolCalculate),
-      m_qProcessInfo_is_valid(eLazyBoolCalculate),
-      m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
-      m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
-      m_supports_memory_region_info(eLazyBoolCalculate),
-      m_supports_watchpoint_support_info(eLazyBoolCalculate),
-      m_supports_detach_stay_stopped(eLazyBoolCalculate),
-      m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
-      m_attach_or_wait_reply(eLazyBoolCalculate),
-      m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
-      m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
-      m_avoid_g_packets(eLazyBoolCalculate),
-      m_supports_QSaveRegisterState(eLazyBoolCalculate),
-      m_supports_qXfer_auxv_read(eLazyBoolCalculate),
-      m_supports_qXfer_libraries_read(eLazyBoolCalculate),
-      m_supports_qXfer_libraries_svr4_read(eLazyBoolCalculate),
-      m_supports_qXfer_features_read(eLazyBoolCalculate),
-      m_supports_qXfer_memory_map_read(eLazyBoolCalculate),
-      m_supports_augmented_libraries_svr4_read(eLazyBoolCalculate),
-      m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
-      m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
-      m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
-      m_supports_QPassSignals(eLazyBoolCalculate),
-      m_supports_error_string_reply(eLazyBoolCalculate),
+
       m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
       m_supports_qUserName(true), m_supports_qGroupName(true),
       m_supports_qThreadStopInfo(true), m_supports_z0(true),
@@ -97,15 +65,11 @@
       m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
       m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
       m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
-      m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
-      m_curr_tid_run(LLDB_INVALID_THREAD_ID),
-      m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
-      m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
-      m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
-      m_max_packet_size(0), m_qSupported_response(),
-      m_supported_async_json_packets_is_valid(false),
-      m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
-      m_qXfer_memory_map_loaded(false) {}
+
+      m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(),
+      m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0),
+      m_qSupported_response(), m_supported_async_json_packets_sp(),
+      m_qXfer_memory_map() {}
 
 // Destructor
 GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
@@ -218,7 +182,7 @@
     ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
+    if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
         PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_send_acks = false;
@@ -235,8 +199,8 @@
     m_supports_threads_in_stop_reply = eLazyBoolNo;
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==
+        PacketResult::Success) {
       if (response.IsOKResponse())
         m_supports_threads_in_stop_reply = eLazyBoolYes;
     }
@@ -248,8 +212,8 @@
     m_attach_or_wait_reply = eLazyBoolNo;
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==
+        PacketResult::Success) {
       if (response.IsOKResponse())
         m_attach_or_wait_reply = eLazyBoolYes;
     }
@@ -262,8 +226,8 @@
     m_prepare_for_reg_writing_reply = eLazyBoolNo;
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==
+        PacketResult::Success) {
       if (response.IsOKResponse())
         m_prepare_for_reg_writing_reply = eLazyBoolYes;
     }
@@ -292,6 +256,7 @@
     m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
     m_attach_or_wait_reply = eLazyBoolCalculate;
     m_avoid_g_packets = eLazyBoolCalculate;
+    m_supports_multiprocess = eLazyBoolCalculate;
     m_supports_qXfer_auxv_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
@@ -321,6 +286,7 @@
     m_gdb_server_name.clear();
     m_gdb_server_version = UINT32_MAX;
     m_default_packet_timeout = seconds(0);
+    m_target_vm_page_size = 0;
     m_max_packet_size = 0;
     m_qSupported_response.clear();
     m_supported_async_json_packets_is_valid = false;
@@ -342,11 +308,17 @@
   m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
   m_supports_qXfer_features_read = eLazyBoolNo;
   m_supports_qXfer_memory_map_read = eLazyBoolNo;
+  m_supports_multiprocess = eLazyBoolNo;
+  m_supports_qEcho = eLazyBoolNo;
+  m_supports_QPassSignals = eLazyBoolNo;
+  m_supports_memory_tagging = eLazyBoolNo;
+
   m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
                                   // not, we assume no limit
 
   // build the qSupported packet
-  std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
+  std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
+                                       "multiprocess+"};
   StreamString packet;
   packet.PutCString("qSupported");
   for (uint32_t i = 0; i < features.size(); ++i) {
@@ -355,95 +327,55 @@
   }
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet.GetString(), response,
-                                   /*send_async=*/false) ==
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
       PacketResult::Success) {
-    const char *response_cstr = response.GetStringRef().data();
-
     // Hang on to the qSupported packet, so that platforms can do custom
     // configuration of the transport before attaching/launching the process.
-    m_qSupported_response = response_cstr;
+    m_qSupported_response = response.GetStringRef().str();
 
-    if (::strstr(response_cstr, "qXfer:auxv:read+"))
-      m_supports_qXfer_auxv_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
-      m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
-      m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
-      m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
-    }
-    if (::strstr(response_cstr, "qXfer:libraries:read+"))
-      m_supports_qXfer_libraries_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:features:read+"))
-      m_supports_qXfer_features_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:memory-map:read+"))
-      m_supports_qXfer_memory_map_read = eLazyBoolYes;
+    llvm::SmallVector<llvm::StringRef, 16> server_features;
+    response.GetStringRef().split(server_features, ';');
 
-    // Look for a list of compressions in the features list e.g.
-    // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
-    // deflate,lzma
-    const char *features_list = ::strstr(response_cstr, "qXfer:features:");
-    if (features_list) {
-      const char *compressions =
-          ::strstr(features_list, "SupportedCompressions=");
-      if (compressions) {
-        std::vector<std::string> supported_compressions;
-        compressions += sizeof("SupportedCompressions=") - 1;
-        const char *end_of_compressions = strchr(compressions, ';');
-        if (end_of_compressions == nullptr) {
-          end_of_compressions = strchr(compressions, '\0');
+    for (llvm::StringRef x : server_features) {
+      if (x == "qXfer:auxv:read+")
+        m_supports_qXfer_auxv_read = eLazyBoolYes;
+      else if (x == "qXfer:libraries-svr4:read+")
+        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+      else if (x == "augmented-libraries-svr4-read") {
+        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+        m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+      } else if (x == "qXfer:libraries:read+")
+        m_supports_qXfer_libraries_read = eLazyBoolYes;
+      else if (x == "qXfer:features:read+")
+        m_supports_qXfer_features_read = eLazyBoolYes;
+      else if (x == "qXfer:memory-map:read+")
+        m_supports_qXfer_memory_map_read = eLazyBoolYes;
+      else if (x == "qEcho")
+        m_supports_qEcho = eLazyBoolYes;
+      else if (x == "QPassSignals+")
+        m_supports_QPassSignals = eLazyBoolYes;
+      else if (x == "multiprocess+")
+        m_supports_multiprocess = eLazyBoolYes;
+      else if (x == "memory-tagging+")
+        m_supports_memory_tagging = eLazyBoolYes;
+      // Look for a list of compressions in the features list e.g.
+      // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
+      // deflate,lzma
+      else if (x.consume_front("SupportedCompressions=")) {
+        llvm::SmallVector<llvm::StringRef, 4> compressions;
+        x.split(compressions, ',');
+        if (!compressions.empty())
+          MaybeEnableCompression(compressions);
+      } else if (x.consume_front("PacketSize=")) {
+        StringExtractorGDBRemote packet_response(x);
+        m_max_packet_size =
+            packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+        if (m_max_packet_size == 0) {
+          m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+          Log *log(
+              ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+          LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
         }
-        const char *current_compression = compressions;
-        while (current_compression < end_of_compressions) {
-          const char *next_compression_name = strchr(current_compression, ',');
-          const char *end_of_this_word = next_compression_name;
-          if (next_compression_name == nullptr ||
-              end_of_compressions < next_compression_name) {
-            end_of_this_word = end_of_compressions;
-          }
-
-          if (end_of_this_word) {
-            if (end_of_this_word == current_compression) {
-              current_compression++;
-            } else {
-              std::string this_compression(
-                  current_compression, end_of_this_word - current_compression);
-              supported_compressions.push_back(this_compression);
-              current_compression = end_of_this_word + 1;
-            }
-          } else {
-            supported_compressions.push_back(current_compression);
-            current_compression = end_of_compressions;
-          }
-        }
-
-        if (supported_compressions.size() > 0) {
-          MaybeEnableCompression(supported_compressions);
-        }
-      }
-    }
-
-    if (::strstr(response_cstr, "qEcho"))
-      m_supports_qEcho = eLazyBoolYes;
-    else
-      m_supports_qEcho = eLazyBoolNo;
-
-    if (::strstr(response_cstr, "QPassSignals+"))
-      m_supports_QPassSignals = eLazyBoolYes;
-    else
-      m_supports_QPassSignals = eLazyBoolNo;
-
-    const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
-    if (packet_size_str) {
-      StringExtractorGDBRemote packet_response(packet_size_str +
-                                               strlen("PacketSize="));
-      m_max_packet_size =
-          packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
-      if (m_max_packet_size == 0) {
-        m_max_packet_size = UINT64_MAX; // Must have been a garbled response
-        Log *log(
-            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-        LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
       }
     }
   }
@@ -453,8 +385,8 @@
   if (m_supports_thread_suffix == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_thread_suffix = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==
+        PacketResult::Success) {
       if (response.IsOKResponse())
         m_supports_thread_suffix = eLazyBoolYes;
     }
@@ -470,7 +402,7 @@
     m_supports_vCont_C = eLazyBoolNo;
     m_supports_vCont_s = eLazyBoolNo;
     m_supports_vCont_S = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("vCont?", response, false) ==
+    if (SendPacketAndWaitForResponse("vCont?", response) ==
         PacketResult::Success) {
       const char *response_cstr = response.GetStringRef().data();
       if (::strstr(response_cstr, ";c"))
@@ -522,9 +454,9 @@
 
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
-    lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
-    bool send_async) {
-  Lock lock(*this, send_async);
+    lldb::tid_t tid, StreamString &&payload,
+    StringExtractorGDBRemote &response) {
+  Lock lock(*this);
   if (!lock) {
     if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
             GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
@@ -561,7 +493,7 @@
   payload.PutCString(packetStr);
   StringExtractorGDBRemote response;
   if (SendThreadSpecificPacketAndWaitForResponse(
-          tid, std::move(payload), response, false) == PacketResult::Success &&
+          tid, std::move(payload), response) == PacketResult::Success &&
       response.IsNormalResponse()) {
     return eLazyBoolYes;
   }
@@ -575,7 +507,7 @@
   if (m_supports_jThreadsInfo) {
     StringExtractorGDBRemote response;
     response.SetResponseValidatorToJSON();
-    if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
+    if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
         PacketResult::Success) {
       if (response.IsUnsupportedResponse()) {
         m_supports_jThreadsInfo = false;
@@ -592,7 +524,7 @@
   if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_jThreadExtendedInfo = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
+    if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==
         PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_supports_jThreadExtendedInfo = eLazyBoolYes;
@@ -608,7 +540,7 @@
     // We try to enable error strings in remote packets but if we fail, we just
     // work in the older way.
     m_supports_error_string_reply = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
+    if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
         PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_supports_error_string_reply = eLazyBoolYes;
@@ -622,8 +554,7 @@
     StringExtractorGDBRemote response;
     m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
     if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
-                                     response,
-                                     false) == PacketResult::Success) {
+                                     response) == PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
       }
@@ -636,7 +567,7 @@
   if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_jGetSharedCacheInfo = eLazyBoolNo;
-    if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
+    if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==
         PacketResult::Success) {
       if (response.IsOKResponse()) {
         m_supports_jGetSharedCacheInfo = eLazyBoolYes;
@@ -646,13 +577,82 @@
   return m_supports_jGetSharedCacheInfo;
 }
 
+bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
+  if (m_supports_memory_tagging == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_memory_tagging == eLazyBoolYes;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
+                                                          size_t len,
+                                                          int32_t type) {
+  StreamString packet;
+  packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
+  StringExtractorGDBRemote response;
+
+  Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_MEMORY);
+
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
+          PacketResult::Success ||
+      !response.IsNormalResponse()) {
+    LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
+              __FUNCTION__);
+    return nullptr;
+  }
+
+  // We are expecting
+  // m<hex encoded bytes>
+
+  if (response.GetChar() != 'm') {
+    LLDB_LOGF(log,
+              "GDBRemoteCommunicationClient::%s: qMemTags response did not "
+              "begin with \"m\"",
+              __FUNCTION__);
+    return nullptr;
+  }
+
+  size_t expected_bytes = response.GetBytesLeft() / 2;
+  DataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
+  size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
+  // Check both because in some situations chars are consumed even
+  // if the decoding fails.
+  if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
+    LLDB_LOGF(
+        log,
+        "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
+        __FUNCTION__);
+    return nullptr;
+  }
+
+  return buffer_sp;
+}
+
+Status GDBRemoteCommunicationClient::WriteMemoryTags(
+    lldb::addr_t addr, size_t len, int32_t type,
+    const std::vector<uint8_t> &tags) {
+  // Format QMemTags:address,length:type:tags
+  StreamString packet;
+  packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
+  packet.PutBytesAsRawHex8(tags.data(), tags.size());
+
+  Status status;
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
+          PacketResult::Success ||
+      !response.IsOKResponse()) {
+    status.SetErrorString("QMemTags packet failed");
+  }
+  return status;
+}
+
 bool GDBRemoteCommunicationClient::GetxPacketSupported() {
   if (m_supports_x == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_x = eLazyBoolNo;
     char packet[256];
     snprintf(packet, sizeof(packet), "x0,0");
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         m_supports_x = eLazyBoolYes;
@@ -664,7 +664,7 @@
 GDBRemoteCommunicationClient::PacketResult
 GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
     const char *payload_prefix, std::string &response_string) {
-  Lock lock(*this, false);
+  Lock lock(*this);
   if (!lock) {
     Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
                                                            GDBR_LOG_PACKETS));
@@ -725,11 +725,11 @@
     // the thread id, which newer debugserver and lldb-gdbserver stubs return
     // correctly.
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qC", response, false) ==
-        PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {
       if (response.GetChar() == 'Q') {
         if (response.GetChar() == 'C') {
-          m_curr_pid = response.GetHexMaxU32(false, LLDB_INVALID_PROCESS_ID);
+          m_curr_pid_run = m_curr_pid =
+              response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
           if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
             m_curr_pid_is_valid = eLazyBoolYes;
             return m_curr_pid;
@@ -741,12 +741,14 @@
     // If we don't get a response for $qC, check if $qfThreadID gives us a
     // result.
     if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
-      std::vector<lldb::tid_t> thread_ids;
       bool sequence_mutex_unavailable;
-      size_t size;
-      size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
-      if (size && !sequence_mutex_unavailable) {
-        m_curr_pid = thread_ids.front();
+      auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
+      if (!ids.empty() && !sequence_mutex_unavailable) {
+        // If server returned an explicit PID, use that.
+        m_curr_pid_run = m_curr_pid = ids.front().first;
+        // Otherwise, use the TID of the first thread (Linux hack).
+        if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
+          m_curr_pid_run = m_curr_pid = ids.front().second;
         m_curr_pid_is_valid = eLazyBoolYes;
         return m_curr_pid;
       }
@@ -759,7 +761,7 @@
 bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
   error_str.clear();
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
+  if (SendPacketAndWaitForResponse("qLaunchSuccess", response) ==
       PacketResult::Success) {
     if (response.IsOKResponse())
       return true;
@@ -813,7 +815,7 @@
     }
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -863,7 +865,7 @@
       if (m_supports_QEnvironmentHexEncoded) {
         packet.PutCString("QEnvironmentHexEncoded:");
         packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
-        if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+        if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
             PacketResult::Success) {
           if (response.IsOKResponse())
             return 0;
@@ -877,7 +879,7 @@
 
     } else if (m_supports_QEnvironment) {
       packet.Printf("QEnvironment:%s", name_equal_value);
-      if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+      if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
           PacketResult::Success) {
         if (response.IsOKResponse())
           return 0;
@@ -897,7 +899,7 @@
     StreamString packet;
     packet.Printf("QLaunchArch:%s", arch);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -915,7 +917,7 @@
     StreamString packet;
     packet.Printf("QSetProcessEvent:%s", data);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse()) {
         if (was_supported)
@@ -1000,7 +1002,7 @@
     m_qGDBServerVersion_is_valid = eLazyBoolNo;
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+    if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
         PacketResult::Success) {
       if (response.IsNormalResponse()) {
         llvm::StringRef name, value;
@@ -1025,9 +1027,9 @@
 }
 
 void GDBRemoteCommunicationClient::MaybeEnableCompression(
-    std::vector<std::string> supported_compressions) {
+    llvm::ArrayRef<llvm::StringRef> supported_compressions) {
   CompressionType avail_type = CompressionType::None;
-  std::string avail_name;
+  llvm::StringRef avail_name;
 
 #if defined(HAVE_LIBCOMPRESSION)
   if (avail_type == CompressionType::None) {
@@ -1091,8 +1093,8 @@
 
   if (avail_type != CompressionType::None) {
     StringExtractorGDBRemote response;
-    std::string packet = "QEnableCompression:type:" + avail_name + ";";
-    if (SendPacketAndWaitForResponse(packet, response, false) !=
+    llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";";
+    if (SendPacketAndWaitForResponse(packet.str(), response) !=
         PacketResult::Success)
       return;
 
@@ -1118,15 +1120,29 @@
 
 bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qC", response, false) !=
-      PacketResult::Success)
+  if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)
     return false;
 
   if (!response.IsNormalResponse())
     return false;
 
-  if (response.GetChar() == 'Q' && response.GetChar() == 'C')
-    tid = response.GetHexMaxU32(true, -1);
+  if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
+    auto pid_tid = response.GetPidTid(0);
+    if (!pid_tid)
+      return false;
+
+    lldb::pid_t pid = pid_tid->first;
+    // invalid
+    if (pid == StringExtractorGDBRemote::AllProcesses)
+      return false;
+
+    // if we get pid as well, update m_curr_pid
+    if (pid != 0) {
+      m_curr_pid_run = m_curr_pid = pid;
+      m_curr_pid_is_valid = eLazyBoolYes;
+    }
+    tid = pid_tid->second;
+  }
 
   return true;
 }
@@ -1154,7 +1170,7 @@
     ScopedTimeout timeout(*this, seconds(10));
     m_qHostInfo_is_valid = eLazyBoolNo;
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
+    if (SendPacketAndWaitForResponse("qHostInfo", response) ==
         PacketResult::Success) {
       if (response.IsNormalResponse()) {
         llvm::StringRef name;
@@ -1219,11 +1235,13 @@
           } else if (name.equals("ptrsize")) {
             if (!value.getAsInteger(0, pointer_byte_size))
               ++num_keys_decoded;
+          } else if (name.equals("addressing_bits")) {
+            if (!value.getAsInteger(0, m_addressing_bits))
+              ++num_keys_decoded;
           } else if (name.equals("os_version") ||
-                     name.equals(
-                         "version")) // Older debugserver binaries used the
-                                     // "version" key instead of
-                                     // "os_version"...
+                     name.equals("version")) // Older debugserver binaries used
+                                             // the "version" key instead of
+                                             // "os_version"...
           {
             if (!m_os_version.tryParse(value))
               ++num_keys_decoded;
@@ -1245,6 +1263,12 @@
               SetPacketTimeout(m_default_packet_timeout);
               ++num_keys_decoded;
             }
+          } else if (name.equals("vm-page-size")) {
+            int page_size;
+            if (!value.getAsInteger(0, page_size)) {
+              m_target_vm_page_size = page_size;
+              ++num_keys_decoded;
+            }
           }
         }
 
@@ -1344,7 +1368,7 @@
         ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     assert(packet_len < (int)sizeof(packet));
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsErrorResponse())
         return response.GetError();
@@ -1360,7 +1384,7 @@
   packet.PutCString("I");
   packet.PutBytesAsRawHex8(data, data_len);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
       PacketResult::Success) {
     return 0;
   }
@@ -1374,6 +1398,11 @@
   return m_host_arch;
 }
 
+uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
+  if (m_qHostInfo_is_valid == eLazyBoolCalculate)
+    GetHostInfo();
+  return m_addressing_bits;
+}
 seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
   if (m_qHostInfo_is_valid == eLazyBoolCalculate)
     GetHostInfo();
@@ -1393,7 +1422,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsUnsupportedResponse())
         m_supports_alloc_dealloc_memory = eLazyBoolNo;
@@ -1415,7 +1444,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsUnsupportedResponse())
         m_supports_alloc_dealloc_memory = eLazyBoolNo;
@@ -1439,7 +1468,7 @@
       assert(packet_len < (int)sizeof(packet));
       UNUSED_IF_ASSERT_DISABLED(packet_len);
       StringExtractorGDBRemote response;
-      if (SendPacketAndWaitForResponse(packet, response, false) ==
+      if (SendPacketAndWaitForResponse(packet, response) ==
               PacketResult::Success &&
           response.IsOKResponse()) {
         m_supports_detach_stay_stopped = eLazyBoolYes;
@@ -1453,15 +1482,13 @@
       return error;
     } else {
       StringExtractorGDBRemote response;
-      PacketResult packet_result =
-          SendPacketAndWaitForResponse("D1", response, false);
+      PacketResult packet_result = SendPacketAndWaitForResponse("D1", response);
       if (packet_result != PacketResult::Success)
         error.SetErrorString("Sending extended disconnect packet failed.");
     }
   } else {
     StringExtractorGDBRemote response;
-    PacketResult packet_result =
-        SendPacketAndWaitForResponse("D", response, false);
+    PacketResult packet_result = SendPacketAndWaitForResponse("D", response);
     if (packet_result != PacketResult::Success)
       error.SetErrorString("Sending disconnect packet failed.");
   }
@@ -1481,7 +1508,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
             PacketResult::Success &&
         response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
       llvm::StringRef name;
@@ -1551,9 +1578,30 @@
           // Now convert the HEX bytes into a string value
           error_extractor.GetHexByteString(error_string);
           error.SetErrorString(error_string.c_str());
+        } else if (name.equals("dirty-pages")) {
+          std::vector<addr_t> dirty_page_list;
+          std::string comma_sep_str = value.str();
+          size_t comma_pos;
+          addr_t page;
+          while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
+            comma_sep_str[comma_pos] = '\0';
+            page = StringConvert::ToUInt64(comma_sep_str.c_str(),
+                                           LLDB_INVALID_ADDRESS, 16);
+            if (page != LLDB_INVALID_ADDRESS)
+              dirty_page_list.push_back(page);
+            comma_sep_str.erase(0, comma_pos + 1);
+          }
+          page = StringConvert::ToUInt64(comma_sep_str.c_str(),
+                                         LLDB_INVALID_ADDRESS, 16);
+          if (page != LLDB_INVALID_ADDRESS)
+            dirty_page_list.push_back(page);
+          region_info.SetDirtyPageList(dirty_page_list);
         }
       }
 
+      if (m_target_vm_page_size != 0)
+        region_info.SetPageSize(m_target_vm_page_size);
+
       if (region_info.GetRange().IsValid()) {
         // We got a valid address range back but no permissions -- which means
         // this is an unmapped page
@@ -1718,8 +1766,8 @@
   num = 0;
   if (m_supports_watchpoint_support_info != eLazyBoolNo) {
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response,
-                                     false) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
+        PacketResult::Success) {
       m_supports_watchpoint_support_info = eLazyBoolYes;
       llvm::StringRef name;
       llvm::StringRef value;
@@ -1787,7 +1835,7 @@
     packet.PutStringAsRawHex8(path);
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -1807,7 +1855,7 @@
     packet.PutStringAsRawHex8(path);
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -1827,7 +1875,7 @@
     packet.PutStringAsRawHex8(path);
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -1841,7 +1889,7 @@
 
 bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
+  if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
       PacketResult::Success) {
     if (response.IsUnsupportedResponse())
       return false;
@@ -1863,7 +1911,7 @@
     packet.PutStringAsRawHex8(path);
 
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       if (response.IsOKResponse())
         return 0;
@@ -1882,8 +1930,7 @@
   assert(packet_len < (int)sizeof(packet));
   UNUSED_IF_ASSERT_DISABLED(packet_len);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet, response, false) ==
-      PacketResult::Success) {
+  if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
     if (response.IsOKResponse())
       return 0;
     uint8_t error = response.GetError();
@@ -1900,8 +1947,7 @@
   assert(packet_len < (int)sizeof(packet));
   UNUSED_IF_ASSERT_DISABLED(packet_len);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet, response, false) ==
-      PacketResult::Success) {
+  if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
     if (response.IsOKResponse())
       return 0;
     uint8_t error = response.GetError();
@@ -2019,7 +2065,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       return DecodeProcessInfoResponse(response, process_info);
     } else {
@@ -2044,7 +2090,7 @@
   GetHostInfo();
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qProcessInfo", response, false) ==
+  if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
       PacketResult::Success) {
     if (response.IsNormalResponse()) {
       llvm::StringRef name;
@@ -2102,7 +2148,7 @@
         m_qProcessInfo_is_valid = eLazyBoolYes;
       if (pid != LLDB_INVALID_PROCESS_ID) {
         m_curr_pid_is_valid = eLazyBoolYes;
-        m_curr_pid = pid;
+        m_curr_pid_run = m_curr_pid = pid;
       }
 
       // Set the ArchSpec from the triple if we have it.
@@ -2240,7 +2286,7 @@
     // Increase timeout as the first qfProcessInfo packet takes a long time on
     // Android. The value of 1min was arrived at empirically.
     ScopedTimeout timeout(*this, minutes(1));
-    if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success) {
       do {
         ProcessInstanceInfo process_info;
@@ -2248,7 +2294,7 @@
           break;
         process_infos.push_back(process_info);
         response = StringExtractorGDBRemote();
-      } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
+      } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
                PacketResult::Success);
     } else {
       m_supports_qfProcessInfo = false;
@@ -2267,7 +2313,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsNormalResponse()) {
         // Make sure we parsed the right number of characters. The response is
@@ -2294,7 +2340,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsNormalResponse()) {
         // Make sure we parsed the right number of characters. The response is
@@ -2322,8 +2368,7 @@
 
   StringExtractorGDBRemote response;
   // Send to target
-  if (SendPacketAndWaitForResponse(packet, response, false) ==
-      PacketResult::Success)
+  if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success)
     if (response.IsOKResponse())
       return true;
 
@@ -2395,7 +2440,7 @@
         for (i = 0; i < num_packets; ++i) {
           const auto packet_start_time = steady_clock::now();
           StringExtractorGDBRemote response;
-          SendPacketAndWaitForResponse(packet.GetString(), response, false);
+          SendPacketAndWaitForResponse(packet.GetString(), response);
           const auto packet_end_time = steady_clock::now();
           packet_times.push_back(packet_end_time - packet_start_time);
         }
@@ -2449,7 +2494,7 @@
         uint32_t packet_count = 0;
         while (bytes_read < recv_amount) {
           StringExtractorGDBRemote response;
-          SendPacketAndWaitForResponse(packet.GetString(), response, false);
+          SendPacketAndWaitForResponse(packet.GetString(), response);
           bytes_read += recv_size;
           ++packet_count;
         }
@@ -2503,7 +2548,7 @@
   }
 
   StringExtractorGDBRemote response;
-  return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+  return SendPacketAndWaitForResponse(packet.GetString(), response) ==
          PacketResult::Success;
 }
 
@@ -2533,7 +2578,7 @@
   // give the process a few seconds to startup
   ScopedTimeout timeout(*this, seconds(10));
 
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     llvm::StringRef name;
     llvm::StringRef value;
@@ -2557,7 +2602,7 @@
   connection_urls.clear();
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
+  if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
       PacketResult::Success)
     return 0;
 
@@ -2596,7 +2641,7 @@
   stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.IsOKResponse())
       return true;
@@ -2604,25 +2649,27 @@
   return false;
 }
 
-bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
-  if (m_curr_tid == tid)
-    return true;
+llvm::Optional<PidTid>
+GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(uint64_t tid,
+                                                         uint64_t pid,
+                                                         char op) {
+  lldb_private::StreamString packet;
+  packet.PutChar('H');
+  packet.PutChar(op);
 
-  char packet[32];
-  int packet_len;
+  if (pid != LLDB_INVALID_PROCESS_ID)
+    packet.Printf("p%" PRIx64 ".", pid);
+
   if (tid == UINT64_MAX)
-    packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
+    packet.PutCString("-1");
   else
-    packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
-  assert(packet_len + 1 < (int)sizeof(packet));
-  UNUSED_IF_ASSERT_DISABLED(packet_len);
+    packet.Printf("%" PRIx64, tid);
+
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet, response, false) ==
-      PacketResult::Success) {
-    if (response.IsOKResponse()) {
-      m_curr_tid = tid;
-      return true;
-    }
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) 
+      == PacketResult::Success) {
+    if (response.IsOKResponse())
+      return {{pid, tid}};
 
     /*
      * Connected bare-iron target (like YAMON gdb-stub) may not have support for
@@ -2630,55 +2677,46 @@
      * The reply from '?' packet could be as simple as 'S05'. There is no packet
      * which can
      * give us pid and/or tid. Assume pid=tid=1 in such cases.
-    */
-    if (response.IsUnsupportedResponse() && IsConnected()) {
-      m_curr_tid = 1;
-      return true;
-    }
+     */
+    if (response.IsUnsupportedResponse() && IsConnected())
+      return {{1, 1}};
   }
-  return false;
+  return llvm::None;
 }
 
-bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
-  if (m_curr_tid_run == tid)
+bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
+                                                    uint64_t pid) {
+  if (m_curr_tid == tid &&
+      (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
     return true;
 
-  char packet[32];
-  int packet_len;
-  if (tid == UINT64_MAX)
-    packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
-  else
-    packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
-
-  assert(packet_len + 1 < (int)sizeof(packet));
-  UNUSED_IF_ASSERT_DISABLED(packet_len);
-  StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet, response, false) ==
-      PacketResult::Success) {
-    if (response.IsOKResponse()) {
-      m_curr_tid_run = tid;
-      return true;
-    }
-
-    /*
-     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
-     * Hc packet.
-     * The reply from '?' packet could be as simple as 'S05'. There is no packet
-     * which can
-     * give us pid and/or tid. Assume pid=tid=1 in such cases.
-    */
-    if (response.IsUnsupportedResponse() && IsConnected()) {
-      m_curr_tid_run = 1;
-      return true;
-    }
+  llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
+  if (ret.hasValue()) {
+    if (ret->pid != LLDB_INVALID_PROCESS_ID)
+      m_curr_pid = ret->pid;
+    m_curr_tid = ret->tid;
   }
-  return false;
+  return ret.hasValue();
+}
+
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
+                                                          uint64_t pid) {
+  if (m_curr_tid_run == tid &&
+      (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
+    return true;
+
+  llvm::Optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
+  if (ret.hasValue()) {
+    if (ret->pid != LLDB_INVALID_PROCESS_ID)
+      m_curr_pid_run = ret->pid;
+    m_curr_tid_run = ret->tid;
+  }
+  return ret.hasValue();
 }
 
 bool GDBRemoteCommunicationClient::GetStopReply(
     StringExtractorGDBRemote &response) {
-  if (SendPacketAndWaitForResponse("?", response, false) ==
-      PacketResult::Success)
+  if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)
     return response.IsNormalResponse();
   return false;
 }
@@ -2691,7 +2729,7 @@
         ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
-    if (SendPacketAndWaitForResponse(packet, response, false) ==
+    if (SendPacketAndWaitForResponse(packet, response) ==
         PacketResult::Success) {
       if (response.IsUnsupportedResponse())
         m_supports_qThreadStopInfo = false;
@@ -2707,7 +2745,8 @@
 }
 
 uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
-    GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
+    GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
+    std::chrono::seconds timeout) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
   LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
             __FUNCTION__, insert ? "add" : "remove", addr);
@@ -2728,7 +2767,7 @@
   // or "" (unsupported)
   response.SetResponseValidatorToOKErrorNotSupported();
   // Try to send the breakpoint packet, and check that it was correctly sent
-  if (SendPacketAndWaitForResponse(packet, response, true) ==
+  if (SendPacketAndWaitForResponse(packet, response, timeout) ==
       PacketResult::Success) {
     // Receive and OK packet when the breakpoint successfully placed
     if (response.IsOKResponse())
@@ -2766,11 +2805,12 @@
   return UINT8_MAX;
 }
 
-size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
-    std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
-  thread_ids.clear();
+std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
+GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
+    bool &sequence_mutex_unavailable) {
+  std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;
 
-  Lock lock(*this, false);
+  Lock lock(*this);
   if (lock) {
     sequence_mutex_unavailable = false;
     StringExtractorGDBRemote response;
@@ -2786,11 +2826,11 @@
         break;
       if (ch == 'm') {
         do {
-          tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
+          auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
+          if (!pid_tid)
+            return {};
 
-          if (tid != LLDB_INVALID_THREAD_ID) {
-            thread_ids.push_back(tid);
-          }
+          ids.push_back(pid_tid.getValue());
           ch = response.GetChar(); // Skip the command separator
         } while (ch == ',');       // Make sure we got a comma separator
       }
@@ -2803,10 +2843,10 @@
      * be as simple as 'S05'. There is no packet which can give us pid and/or
      * tid.
      * Assume pid=tid=1 in such cases.
-    */
+     */
     if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
-        thread_ids.size() == 0 && IsConnected()) {
-      thread_ids.push_back(1);
+        ids.size() == 0 && IsConnected()) {
+      ids.emplace_back(1, 1);
     }
   } else {
     Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
@@ -2815,12 +2855,34 @@
                   "packet 'qfThreadInfo'");
     sequence_mutex_unavailable = true;
   }
+
+  return ids;
+}
+
+size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
+    std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
+  lldb::pid_t pid = GetCurrentProcessID();
+  thread_ids.clear();
+
+  auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
+  if (ids.empty() || sequence_mutex_unavailable)
+    return 0;
+
+  for (auto id : ids) {
+    // skip threads that do not belong to the current process
+    if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
+      continue;
+    if (id.second != LLDB_INVALID_THREAD_ID &&
+        id.second != StringExtractorGDBRemote::AllThreads)
+      thread_ids.push_back(id.second);
+  }
+
   return thread_ids.size();
 }
 
 lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+  if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
           PacketResult::Success ||
       !response.IsNormalResponse())
     return LLDB_INVALID_ADDRESS;
@@ -2853,7 +2915,7 @@
     stream.PutStringAsRawHex8(path);
   }
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F')
       return Status("malformed reply");
@@ -2891,8 +2953,7 @@
   llvm::StringRef packet = stream.GetString();
   StringExtractorGDBRemote response;
 
-  if (SendPacketAndWaitForResponse(packet, response, false) !=
-      PacketResult::Success)
+  if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
     return Status("failed to send '%s' packet", packet.str().c_str());
 
   if (response.GetChar() != 'F')
@@ -2913,8 +2974,7 @@
   llvm::StringRef packet = stream.GetString();
   StringExtractorGDBRemote response;
 
-  if (SendPacketAndWaitForResponse(packet, response, false) !=
-      PacketResult::Success)
+  if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
     return Status("failed to send '%s' packet", stream.GetData());
 
   if (response.GetChar() != 'F')
@@ -2956,7 +3016,7 @@
   stream.PutChar(',');
   stream.PutHex32(mode);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     return ParseHostIOPacketResponse(response, UINT64_MAX, error);
   }
@@ -2968,7 +3028,7 @@
   lldb_private::StreamString stream;
   stream.Printf("vFile:close:%i", (int)fd);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     return ParseHostIOPacketResponse(response, -1, error) == 0;
   }
@@ -2983,7 +3043,7 @@
   stream.PutCString("vFile:size:");
   stream.PutStringAsRawHex8(path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F')
       return UINT64_MAX;
@@ -3001,7 +3061,7 @@
   stream.PutChar(',');
   stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     StreamString strm;
     char ch = response.GetChar();
@@ -3027,7 +3087,7 @@
   stream.PutCString("vFile:mode:");
   stream.PutStringAsRawHex8(path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F') {
       error.SetErrorStringWithFormat("invalid response to '%s' packet",
@@ -3062,7 +3122,7 @@
   stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
                 offset);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F')
       return 0;
@@ -3096,7 +3156,7 @@
   stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
   stream.PutEscapedBytes(src, src_len);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F') {
       error.SetErrorStringWithFormat("write file failed");
@@ -3131,7 +3191,7 @@
   stream.PutChar(',');
   stream.PutStringAsRawHex8(src_path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() == 'F') {
       uint32_t result = response.GetU32(UINT32_MAX);
@@ -3162,7 +3222,7 @@
   // so we follow suit here
   stream.PutStringAsRawHex8(path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() == 'F') {
       uint32_t result = response.GetU32(UINT32_MAX);
@@ -3192,7 +3252,7 @@
   stream.PutCString("vFile:exists:");
   stream.PutStringAsRawHex8(path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F')
       return false;
@@ -3211,7 +3271,7 @@
   stream.PutCString("vFile:MD5:");
   stream.PutStringAsRawHex8(path);
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
       PacketResult::Success) {
     if (response.GetChar() != 'F')
       return false;
@@ -3258,7 +3318,7 @@
   payload.Printf("p%x", reg);
   StringExtractorGDBRemote response;
   if (SendThreadSpecificPacketAndWaitForResponse(
-          tid, std::move(payload), response, false) != PacketResult::Success ||
+          tid, std::move(payload), response) != PacketResult::Success ||
       !response.IsNormalResponse())
     return nullptr;
 
@@ -3273,7 +3333,7 @@
   payload.PutChar('g');
   StringExtractorGDBRemote response;
   if (SendThreadSpecificPacketAndWaitForResponse(
-          tid, std::move(payload), response, false) != PacketResult::Success ||
+          tid, std::move(payload), response) != PacketResult::Success ||
       !response.IsNormalResponse())
     return nullptr;
 
@@ -3292,9 +3352,8 @@
                             endian::InlHostByteOrder(),
                             endian::InlHostByteOrder());
   StringExtractorGDBRemote response;
-  return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
-                                                    response, false) ==
-             PacketResult::Success &&
+  return SendThreadSpecificPacketAndWaitForResponse(
+             tid, std::move(payload), response) == PacketResult::Success &&
          response.IsOKResponse();
 }
 
@@ -3306,9 +3365,8 @@
                             endian::InlHostByteOrder(),
                             endian::InlHostByteOrder());
   StringExtractorGDBRemote response;
-  return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
-                                                    response, false) ==
-             PacketResult::Success &&
+  return SendThreadSpecificPacketAndWaitForResponse(
+             tid, std::move(payload), response) == PacketResult::Success &&
          response.IsOKResponse();
 }
 
@@ -3323,7 +3381,7 @@
   payload.PutCString("QSaveRegisterState");
   StringExtractorGDBRemote response;
   if (SendThreadSpecificPacketAndWaitForResponse(
-          tid, std::move(payload), response, false) != PacketResult::Success)
+          tid, std::move(payload), response) != PacketResult::Success)
     return false;
 
   if (response.IsUnsupportedResponse())
@@ -3349,7 +3407,7 @@
   payload.Printf("QRestoreRegisterState:%u", save_id);
   StringExtractorGDBRemote response;
   if (SendThreadSpecificPacketAndWaitForResponse(
-          tid, std::move(payload), response, false) != PacketResult::Success)
+          tid, std::move(payload), response) != PacketResult::Success)
     return false;
 
   if (response.IsOKResponse())
@@ -3367,251 +3425,179 @@
   StreamString packet;
   StringExtractorGDBRemote response;
   packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
-  return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+  return SendPacketAndWaitForResponse(packet.GetString(), response) ==
              GDBRemoteCommunication::PacketResult::Success &&
          response.IsOKResponse();
 }
 
-lldb::user_id_t
-GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
-                                                   Status &error) {
-  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-  lldb::user_id_t ret_uid = LLDB_INVALID_UID;
-
-  StreamGDBRemote escaped_packet;
-  escaped_packet.PutCString("jTraceStart:");
-
-  StructuredData::Dictionary json_packet;
-  json_packet.AddIntegerItem("type", options.getType());
-  json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
-  json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
-
-  if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
-    json_packet.AddIntegerItem("threadid", options.getThreadID());
-
-  StructuredData::DictionarySP custom_params = options.getTraceParams();
-  if (custom_params)
-    json_packet.AddItem("params", custom_params);
-
-  StreamString json_string;
-  json_packet.Dump(json_string, false);
-  escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
-
-  StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
-                                   true) ==
-      GDBRemoteCommunication::PacketResult::Success) {
-    if (!response.IsNormalResponse()) {
-      error = response.GetStatus();
-      LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
-    } else {
-      ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
-    }
-  } else {
-    LLDB_LOG(log, "failed to send packet");
-    error.SetErrorStringWithFormat("failed to send packet: '%s'",
-                                   escaped_packet.GetData());
-  }
-  return ret_uid;
-}
-
-Status
-GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
-                                                  lldb::tid_t thread_id) {
-  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-  StringExtractorGDBRemote response;
-  Status error;
-
-  StructuredData::Dictionary json_packet;
-  StreamGDBRemote escaped_packet;
-  StreamString json_string;
-  escaped_packet.PutCString("jTraceStop:");
-
-  json_packet.AddIntegerItem("traceid", uid);
-
-  if (thread_id != LLDB_INVALID_THREAD_ID)
-    json_packet.AddIntegerItem("threadid", thread_id);
-
-  json_packet.Dump(json_string, false);
-
-  escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
-
-  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
-                                   true) ==
-      GDBRemoteCommunication::PacketResult::Success) {
-    if (!response.IsOKResponse()) {
-      error = response.GetStatus();
-      LLDB_LOG(log, "stop tracing failed");
-    }
-  } else {
-    LLDB_LOG(log, "failed to send packet");
-    error.SetErrorStringWithFormat(
-        "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
-        response.GetError());
-  }
-  return error;
-}
-
-Status GDBRemoteCommunicationClient::SendGetDataPacket(
-    lldb::user_id_t uid, lldb::tid_t thread_id,
-    llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
-
-  StreamGDBRemote escaped_packet;
-  escaped_packet.PutCString("jTraceBufferRead:");
-  return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
-}
-
-Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
-    lldb::user_id_t uid, lldb::tid_t thread_id,
-    llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
-
-  StreamGDBRemote escaped_packet;
-  escaped_packet.PutCString("jTraceMetaRead:");
-  return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
-}
-
-llvm::Expected<TraceTypeInfo>
-GDBRemoteCommunicationClient::SendGetSupportedTraceType() {
+llvm::Expected<TraceSupportedResponse>
+GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 
   StreamGDBRemote escaped_packet;
-  escaped_packet.PutCString("jLLDBTraceSupportedType");
+  escaped_packet.PutCString("jLLDBTraceSupported");
 
   StringExtractorGDBRemote response;
   if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
-                                   true) ==
+                                   timeout) ==
       GDBRemoteCommunication::PacketResult::Success) {
     if (response.IsErrorResponse())
       return response.GetStatus().ToError();
     if (response.IsUnsupportedResponse())
       return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "jLLDBTraceSupportedType is unsupported");
+                                     "jLLDBTraceSupported is unsupported");
 
-    if (llvm::Expected<TraceTypeInfo> type =
-            llvm::json::parse<TraceTypeInfo>(response.Peek()))
-      return *type;
-    else
-      return type.takeError();
+    return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
+                                                     "TraceSupportedResponse");
   }
-  LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType");
+  LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "failed to send packet: jLLDBTraceSupported");
+}
+
+llvm::Error
+GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,
+                                            std::chrono::seconds timeout) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  StreamGDBRemote escaped_packet;
+  escaped_packet.PutCString("jLLDBTraceStop:");
+
+  std::string json_string;
+  llvm::raw_string_ostream os(json_string);
+  os << toJSON(request);
+  os.flush();
+
+  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+                                   timeout) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsErrorResponse())
+      return response.GetStatus().ToError();
+    if (response.IsUnsupportedResponse())
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "jLLDBTraceStop is unsupported");
+    if (response.IsOKResponse())
+      return llvm::Error::success();
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Invalid jLLDBTraceStart response");
+  }
+  LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "failed to send packet: jLLDBTraceStop '%s'",
+                                 escaped_packet.GetData());
+}
+
+llvm::Error
+GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
+                                             std::chrono::seconds timeout) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  StreamGDBRemote escaped_packet;
+  escaped_packet.PutCString("jLLDBTraceStart:");
+
+  std::string json_string;
+  llvm::raw_string_ostream os(json_string);
+  os << params;
+  os.flush();
+
+  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+                                   timeout) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsErrorResponse())
+      return response.GetStatus().ToError();
+    if (response.IsUnsupportedResponse())
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "jLLDBTraceStart is unsupported");
+    if (response.IsOKResponse())
+      return llvm::Error::success();
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Invalid jLLDBTraceStart response");
+  }
+  LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "failed to send packet: jLLDBTraceStart '%s'",
+                                 escaped_packet.GetData());
+}
+
+llvm::Expected<std::string>
+GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,
+                                                std::chrono::seconds timeout) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  StreamGDBRemote escaped_packet;
+  escaped_packet.PutCString("jLLDBTraceGetState:");
+
+  std::string json_string;
+  llvm::raw_string_ostream os(json_string);
+  os << toJSON(TraceGetStateRequest{type.str()});
+  os.flush();
+
+  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+                                   timeout) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsErrorResponse())
+      return response.GetStatus().ToError();
+    if (response.IsUnsupportedResponse())
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "jLLDBTraceGetState is unsupported");
+    return std::string(response.Peek());
+  }
+
+  LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
   return llvm::createStringError(
       llvm::inconvertibleErrorCode(),
-      "failed to send packet: jLLDBTraceSupportedType");
+      "failed to send packet: jLLDBTraceGetState '%s'",
+      escaped_packet.GetData());
 }
 
-Status
-GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
-                                                       TraceOptions &options) {
+llvm::Expected<std::vector<uint8_t>>
+GDBRemoteCommunicationClient::SendTraceGetBinaryData(
+    const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-  StringExtractorGDBRemote response;
-  Status error;
 
-  StreamString json_string;
   StreamGDBRemote escaped_packet;
-  escaped_packet.PutCString("jTraceConfigRead:");
+  escaped_packet.PutCString("jLLDBTraceGetBinaryData:");
 
-  StructuredData::Dictionary json_packet;
-  json_packet.AddIntegerItem("traceid", uid);
+  std::string json_string;
+  llvm::raw_string_ostream os(json_string);
+  os << toJSON(request);
+  os.flush();
 
-  if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
-    json_packet.AddIntegerItem("threadid", options.getThreadID());
+  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());
 
-  json_packet.Dump(json_string, false);
-  escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
-
-  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
-                                   true) ==
-      GDBRemoteCommunication::PacketResult::Success) {
-    if (response.IsNormalResponse()) {
-      uint64_t type = std::numeric_limits<uint64_t>::max();
-      uint64_t buffersize = std::numeric_limits<uint64_t>::max();
-      uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
-
-      auto json_object = StructuredData::ParseJSON(response.Peek());
-
-      if (!json_object ||
-          json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
-        error.SetErrorString("Invalid Configuration obtained");
-        return error;
-      }
-
-      auto json_dict = json_object->GetAsDictionary();
-
-      json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
-                                                   metabuffersize);
-      options.setMetaDataBufferSize(metabuffersize);
-
-      json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
-      options.setTraceBufferSize(buffersize);
-
-      json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
-      options.setType(static_cast<lldb::TraceType>(type));
-
-      StructuredData::ObjectSP custom_params_sp =
-          json_dict->GetValueForKey("params");
-      if (custom_params_sp) {
-        if (custom_params_sp->GetType() !=
-            lldb::eStructuredDataTypeDictionary) {
-          error.SetErrorString("Invalid Configuration obtained");
-          return error;
-        } else
-          options.setTraceParams(
-              std::static_pointer_cast<StructuredData::Dictionary>(
-                  custom_params_sp));
-      }
-    } else {
-      error = response.GetStatus();
-    }
-  } else {
-    LLDB_LOG(log, "failed to send packet");
-    error.SetErrorStringWithFormat("failed to send packet: '%s'",
-                                   escaped_packet.GetData());
-  }
-  return error;
-}
-
-Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
-    StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
-    llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
-  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-  Status error;
-
-  StructuredData::Dictionary json_packet;
-
-  json_packet.AddIntegerItem("traceid", uid);
-  json_packet.AddIntegerItem("offset", offset);
-  json_packet.AddIntegerItem("buffersize", buffer.size());
-
-  if (thread_id != LLDB_INVALID_THREAD_ID)
-    json_packet.AddIntegerItem("threadid", thread_id);
-
-  StreamString json_string;
-  json_packet.Dump(json_string, false);
-
-  packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
+  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+                                   timeout) ==
       GDBRemoteCommunication::PacketResult::Success) {
-    if (response.IsNormalResponse()) {
-      size_t filled_size = response.GetHexBytesAvail(buffer);
-      buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
-    } else {
-      error = response.GetStatus();
-      buffer = buffer.slice(buffer.size());
-    }
-  } else {
-    LLDB_LOG(log, "failed to send packet");
-    error.SetErrorStringWithFormat("failed to send packet: '%s'",
-                                   packet.GetData());
-    buffer = buffer.slice(buffer.size());
+    if (response.IsErrorResponse())
+      return response.GetStatus().ToError();
+    if (response.IsUnsupportedResponse())
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "jLLDBTraceGetBinaryData is unsupported");
+    std::string data;
+    response.GetEscapedBinaryData(data);
+    return std::vector<uint8_t>(data.begin(), data.end());
   }
-  return error;
+  LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
+  return llvm::createStringError(
+      llvm::inconvertibleErrorCode(),
+      "failed to send packet: jLLDBTraceGetBinaryData '%s'",
+      escaped_packet.GetData());
 }
 
 llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(
-          "qOffsets", response, /*send_async=*/false) != PacketResult::Success)
+  if (SendPacketAndWaitForResponse("qOffsets", response) !=
+      PacketResult::Success)
     return llvm::None;
   if (!response.IsNormalResponse())
     return llvm::None;
@@ -3666,7 +3652,7 @@
   packet.PutStringAsRawHex8(triple);
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(packet.GetString(), response, false) !=
+  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
       PacketResult::Success)
     return false;
 
@@ -3773,7 +3759,7 @@
   ScopedTimeout timeout(*this, std::chrono::seconds(10));
 
   StringExtractorGDBRemote response;
-  if (SendPacketAndWaitForResponse(payload.GetString(), response, false) !=
+  if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
           PacketResult::Success ||
       response.IsErrorResponse())
     return llvm::None;
@@ -3832,7 +3818,7 @@
            << "," << std::hex << size;
 
     GDBRemoteCommunication::PacketResult res =
-        SendPacketAndWaitForResponse(packet.str(), chunk, false);
+        SendPacketAndWaitForResponse(packet.str(), chunk);
 
     if (res != GDBRemoteCommunication::PacketResult::Success) {
       err.SetErrorString("Error sending $qXfer packet");
@@ -3921,7 +3907,7 @@
   bool first_qsymbol_query = true;
 
   if (m_supports_qSymbol && !m_qSymbol_requests_done) {
-    Lock lock(*this, false);
+    Lock lock(*this);
     if (lock) {
       StreamString packet;
       packet.PutCString("qSymbol::");
@@ -4049,9 +4035,8 @@
 
     // Poll it now.
     StringExtractorGDBRemote response;
-    const bool send_async = false;
-    if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
-                                     send_async) == PacketResult::Success) {
+    if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
+        PacketResult::Success) {
       m_supported_async_json_packets_sp =
           StructuredData::ParseJSON(std::string(response.GetStringRef()));
       if (m_supported_async_json_packets_sp &&
@@ -4095,7 +4080,7 @@
   std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
 
   StringExtractorGDBRemote response;
-  auto send_status = SendPacketAndWaitForResponse(packet, response, false);
+  auto send_status = SendPacketAndWaitForResponse(packet, response);
 
   if (send_status != GDBRemoteCommunication::PacketResult::Success)
     return Status("Sending QPassSignals packet failed");
@@ -4134,10 +4119,8 @@
   stream.Flush();
 
   // Send the packet.
-  const bool send_async = false;
   StringExtractorGDBRemote response;
-  auto result =
-      SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
+  auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
   if (result == PacketResult::Success) {
     // We failed if the config result comes back other than OK.
     if (strcmp(response.GetStringRef().data(), "OK") == 0) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index af3755f..1e1797c 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -22,7 +22,7 @@
 #include "lldb/Utility/GDBRemote.h"
 #include "lldb/Utility/ProcessInfo.h"
 #include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/TraceOptions.h"
+#include "lldb/Utility/TraceGDBRemotePackets.h"
 #if defined(_WIN32)
 #include "lldb/Host/windows/PosixApi.h"
 #endif
@@ -49,6 +49,12 @@
 }
 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QOffsets &offsets);
 
+// A trivial struct used to return a pair of PID and TID.
+struct PidTid {
+  uint64_t pid;
+  uint64_t tid;
+};
+
 class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
 public:
   GDBRemoteCommunicationClient();
@@ -275,6 +281,8 @@
 
   ArchSpec GetSystemArchitecture();
 
+  uint32_t GetAddressingBits();
+
   bool GetHostname(std::string &s);
 
   lldb::addr_t GetShlibInfoAddr();
@@ -319,7 +327,8 @@
       GDBStoppointType type, // Type of breakpoint or watchpoint
       bool insert,           // Insert or remove?
       lldb::addr_t addr,     // Address of breakpoint or watchpoint
-      uint32_t length);      // Byte Size of breakpoint or watchpoint
+      uint32_t length,       // Byte Size of breakpoint or watchpoint
+      std::chrono::seconds interrupt_timeout); // Time to wait for an interrupt
 
   bool SetNonStopMode(const bool enable);
 
@@ -334,9 +343,14 @@
   // and response times.
   bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
 
-  bool SetCurrentThread(uint64_t tid);
+  llvm::Optional<PidTid>
+  SendSetCurrentThreadPacket(uint64_t tid, uint64_t pid, char op);
 
-  bool SetCurrentThreadForRun(uint64_t tid);
+  bool SetCurrentThread(uint64_t tid,
+                        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
+
+  bool SetCurrentThreadForRun(uint64_t tid,
+                              lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);
 
   bool GetQXferAuxvReadSupported();
 
@@ -366,6 +380,9 @@
     return m_supports_alloc_dealloc_memory;
   }
 
+  std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
+  GetCurrentProcessAndThreadIDs(bool &sequence_mutex_unavailable);
+
   size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
                              bool &sequence_mutex_unavailable);
 
@@ -446,6 +463,14 @@
 
   bool GetSharedCacheInfoSupported();
 
+  bool GetMemoryTaggingSupported();
+
+  lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len,
+                                    int32_t type);
+
+  Status WriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
+                         const std::vector<uint8_t> &tags);
+
   /// Use qOffsets to query the offset used when relocating the target
   /// executable. If successful, the returned structure will contain at least
   /// one value in the offsets field.
@@ -505,59 +530,61 @@
   ConfigureRemoteStructuredData(ConstString type_name,
                                 const StructuredData::ObjectSP &config_sp);
 
-  lldb::user_id_t SendStartTracePacket(const TraceOptions &options,
-                                       Status &error);
+  llvm::Expected<TraceSupportedResponse>
+  SendTraceSupported(std::chrono::seconds interrupt_timeout);
 
-  Status SendStopTracePacket(lldb::user_id_t uid, lldb::tid_t thread_id);
+  llvm::Error SendTraceStart(const llvm::json::Value &request,
+                             std::chrono::seconds interrupt_timeout);
 
-  Status SendGetDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
-                           llvm::MutableArrayRef<uint8_t> &buffer,
-                           size_t offset = 0);
+  llvm::Error SendTraceStop(const TraceStopRequest &request,
+                            std::chrono::seconds interrupt_timeout);
 
-  Status SendGetMetaDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
-                               llvm::MutableArrayRef<uint8_t> &buffer,
-                               size_t offset = 0);
+  llvm::Expected<std::string>
+  SendTraceGetState(llvm::StringRef type,
+                    std::chrono::seconds interrupt_timeout);
 
-  Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options);
-
-  llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType();
+  llvm::Expected<std::vector<uint8_t>>
+  SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request,
+                         std::chrono::seconds interrupt_timeout);
 
 protected:
-  LazyBool m_supports_not_sending_acks;
-  LazyBool m_supports_thread_suffix;
-  LazyBool m_supports_threads_in_stop_reply;
-  LazyBool m_supports_vCont_all;
-  LazyBool m_supports_vCont_any;
-  LazyBool m_supports_vCont_c;
-  LazyBool m_supports_vCont_C;
-  LazyBool m_supports_vCont_s;
-  LazyBool m_supports_vCont_S;
-  LazyBool m_qHostInfo_is_valid;
-  LazyBool m_curr_pid_is_valid;
-  LazyBool m_qProcessInfo_is_valid;
-  LazyBool m_qGDBServerVersion_is_valid;
-  LazyBool m_supports_alloc_dealloc_memory;
-  LazyBool m_supports_memory_region_info;
-  LazyBool m_supports_watchpoint_support_info;
-  LazyBool m_supports_detach_stay_stopped;
-  LazyBool m_watchpoints_trigger_after_instruction;
-  LazyBool m_attach_or_wait_reply;
-  LazyBool m_prepare_for_reg_writing_reply;
-  LazyBool m_supports_p;
-  LazyBool m_supports_x;
-  LazyBool m_avoid_g_packets;
-  LazyBool m_supports_QSaveRegisterState;
-  LazyBool m_supports_qXfer_auxv_read;
-  LazyBool m_supports_qXfer_libraries_read;
-  LazyBool m_supports_qXfer_libraries_svr4_read;
-  LazyBool m_supports_qXfer_features_read;
-  LazyBool m_supports_qXfer_memory_map_read;
-  LazyBool m_supports_augmented_libraries_svr4_read;
-  LazyBool m_supports_jThreadExtendedInfo;
-  LazyBool m_supports_jLoadedDynamicLibrariesInfos;
-  LazyBool m_supports_jGetSharedCacheInfo;
-  LazyBool m_supports_QPassSignals;
-  LazyBool m_supports_error_string_reply;
+  LazyBool m_supports_not_sending_acks = eLazyBoolCalculate;
+  LazyBool m_supports_thread_suffix = eLazyBoolCalculate;
+  LazyBool m_supports_threads_in_stop_reply = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_all = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_any = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_c = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_C = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_s = eLazyBoolCalculate;
+  LazyBool m_supports_vCont_S = eLazyBoolCalculate;
+  LazyBool m_qHostInfo_is_valid = eLazyBoolCalculate;
+  LazyBool m_curr_pid_is_valid = eLazyBoolCalculate;
+  LazyBool m_qProcessInfo_is_valid = eLazyBoolCalculate;
+  LazyBool m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+  LazyBool m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+  LazyBool m_supports_memory_region_info = eLazyBoolCalculate;
+  LazyBool m_supports_watchpoint_support_info = eLazyBoolCalculate;
+  LazyBool m_supports_detach_stay_stopped = eLazyBoolCalculate;
+  LazyBool m_watchpoints_trigger_after_instruction = eLazyBoolCalculate;
+  LazyBool m_attach_or_wait_reply = eLazyBoolCalculate;
+  LazyBool m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+  LazyBool m_supports_p = eLazyBoolCalculate;
+  LazyBool m_supports_x = eLazyBoolCalculate;
+  LazyBool m_avoid_g_packets = eLazyBoolCalculate;
+  LazyBool m_supports_QSaveRegisterState = eLazyBoolCalculate;
+  LazyBool m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+  LazyBool m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+  LazyBool m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+  LazyBool m_supports_qXfer_features_read = eLazyBoolCalculate;
+  LazyBool m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
+  LazyBool m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+  LazyBool m_supports_jThreadExtendedInfo = eLazyBoolCalculate;
+  LazyBool m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolCalculate;
+  LazyBool m_supports_jGetSharedCacheInfo = eLazyBoolCalculate;
+  LazyBool m_supports_QPassSignals = eLazyBoolCalculate;
+  LazyBool m_supports_error_string_reply = eLazyBoolCalculate;
+  LazyBool m_supports_multiprocess = eLazyBoolCalculate;
+  LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
 
   bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
       m_supports_qUserName : 1, m_supports_qGroupName : 1,
@@ -568,13 +595,17 @@
       m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1,
       m_supports_jModulesInfo : 1;
 
-  lldb::pid_t m_curr_pid;
-  lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
-                          // other operations
-  lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
-                              // continue, step, etc
+  /// Current gdb remote protocol process identifier for all other operations
+  lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID;
+  /// Current gdb remote protocol process identifier for continue, step, etc
+  lldb::pid_t m_curr_pid_run = LLDB_INVALID_PROCESS_ID;
+  /// Current gdb remote protocol thread identifier for all other operations
+  lldb::tid_t m_curr_tid = LLDB_INVALID_THREAD_ID;
+  /// Current gdb remote protocol thread identifier for continue, step, etc
+  lldb::tid_t m_curr_tid_run = LLDB_INVALID_THREAD_ID;
 
-  uint32_t m_num_supported_hardware_watchpoints;
+  uint32_t m_num_supported_hardware_watchpoints = 0;
+  uint32_t m_addressing_bits = 0;
 
   ArchSpec m_host_arch;
   ArchSpec m_process_arch;
@@ -585,17 +616,19 @@
   std::string m_hostname;
   std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
                                  // qGDBServerVersion is not supported
-  uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
-                                 // qGDBServerVersion is not supported
+  uint32_t m_gdb_server_version =
+      UINT32_MAX; // from reply to qGDBServerVersion, zero if
+                  // qGDBServerVersion is not supported
   std::chrono::seconds m_default_packet_timeout;
-  uint64_t m_max_packet_size;        // as returned by qSupported
+  int m_target_vm_page_size = 0; // target system VM page size; 0 unspecified
+  uint64_t m_max_packet_size = 0;    // as returned by qSupported
   std::string m_qSupported_response; // the complete response to qSupported
 
-  bool m_supported_async_json_packets_is_valid;
+  bool m_supported_async_json_packets_is_valid = false;
   lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
 
   std::vector<MemoryRegionInfo> m_qXfer_memory_map;
-  bool m_qXfer_memory_map_loaded;
+  bool m_qXfer_memory_map_loaded = false;
 
   bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
 
@@ -603,7 +636,8 @@
 
   // Given the list of compression types that the remote debug stub can support,
   // possibly enable compression if we find an encoding we can handle.
-  void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+  void MaybeEnableCompression(
+      llvm::ArrayRef<llvm::StringRef> supported_compressions);
 
   bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
                                  ProcessInstanceInfo &process_info);
@@ -612,7 +646,7 @@
 
   PacketResult SendThreadSpecificPacketAndWaitForResponse(
       lldb::tid_t tid, StreamString &&payload,
-      StringExtractorGDBRemote &response, bool send_async);
+      StringExtractorGDBRemote &response);
 
   Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid,
                                 lldb::tid_t thread_id,
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
index 3984a45..d92c97e 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -19,13 +19,12 @@
 using namespace lldb_private::process_gdb_remote;
 
 GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
-    : m_packets(), m_curr_idx(0), m_total_packet_count(0),
-      m_dumped_to_log(false) {
+    : m_packets() {
   if (size)
     m_packets.resize(size);
 }
 
-GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
+GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() = default;
 
 void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
                                               GDBRemotePacket::Type type,
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
index e783e59..eda464a 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -74,9 +74,9 @@
   }
 
   std::vector<GDBRemotePacket> m_packets;
-  uint32_t m_curr_idx;
-  uint32_t m_total_packet_count;
-  mutable bool m_dumped_to_log;
+  uint32_t m_curr_idx = 0;
+  uint32_t m_total_packet_count = 0;
+  mutable bool m_dumped_to_log = false;
   repro::PacketRecorder *m_recorder = nullptr;
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
index 920327e..c91d7cb 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <errno.h>
+#include <cerrno>
 
 #include "lldb/Host/Config.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -74,7 +74,7 @@
       m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"),
       m_async_listener_sp(
           Listener::MakeListener("lldb.gdb-replay.async-listener")),
-      m_async_thread_state_mutex(), m_skip_acks(false) {
+      m_async_thread_state_mutex() {
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
                                    "async thread continue");
   m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
index c13e5ee..2f8770d 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -73,7 +73,7 @@
   HostThread m_async_thread;
   std::recursive_mutex m_async_thread_state_mutex;
 
-  bool m_skip_acks;
+  bool m_skip_acks = false;
 
 private:
   GDBRemoteCommunicationReplayServer(
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 60548ef..11cac9f 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <errno.h>
+#include <cerrno>
 
 #include "lldb/Host/Config.h"
 
@@ -16,11 +16,13 @@
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StringExtractorGDBRemote.h"
 #include "lldb/Utility/UnimplementedError.h"
+#include "llvm/Support/JSON.h"
 #include <cstring>
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
+using namespace llvm;
 
 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
     const char *comm_name, const char *listener_name)
@@ -31,7 +33,7 @@
              bool &quit) { return this->Handle_QErrorStringEnable(packet); });
 }
 
-GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() = default;
 
 void GDBRemoteCommunicationServer::RegisterPacketHandler(
     StringExtractorGDBRemote::ServerPacketType packet_type,
@@ -151,3 +153,21 @@
 bool GDBRemoteCommunicationServer::HandshakeWithClient() {
   return GetAck() == PacketResult::Success;
 }
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
+  std::string json_string;
+  raw_string_ostream os(json_string);
+  os << value;
+  os.flush();
+  StreamGDBRemote escaped_response;
+  escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
+  return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) {
+  if (!value)
+    return SendErrorResponse(value.takeError());
+  return SendJSONResponse(*value);
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index a1cf70f..68448ea 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -72,6 +72,13 @@
 
   PacketResult SendOKResponse();
 
+  /// Serialize and send a JSON object response.
+  PacketResult SendJSONResponse(const llvm::json::Value &value);
+
+  /// Serialize and send a JSON object response, or respond with an error if the
+  /// input object is an \a llvm::Error.
+  PacketResult SendJSONResponse(llvm::Expected<llvm::json::Value> value);
+
 private:
   GDBRemoteCommunicationServer(const GDBRemoteCommunicationServer &) = delete;
   const GDBRemoteCommunicationServer &
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 1ca0290..b2b8025 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -8,7 +8,7 @@
 
 #include "GDBRemoteCommunicationServerCommon.h"
 
-#include <errno.h>
+#include <cerrno>
 
 #ifdef __APPLE__
 #include <TargetConditionals.h>
@@ -60,8 +60,7 @@
     const char *comm_name, const char *listener_name)
     : GDBRemoteCommunicationServer(comm_name, listener_name),
       m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
-      m_proc_infos_index(0), m_thread_suffix_supported(false),
-      m_list_threads_in_stop_reply(false) {
+      m_proc_infos_index(0) {
   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
                                 &GDBRemoteCommunicationServerCommon::Handle_A);
   RegisterMemberFunctionHandler(
@@ -86,9 +85,6 @@
       StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
       &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
-      &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
-  RegisterMemberFunctionHandler(
       StringExtractorGDBRemote::eServerPacketType_qEcho,
       &GDBRemoteCommunicationServerCommon::Handle_qEcho);
   RegisterMemberFunctionHandler(
@@ -134,9 +130,6 @@
       StringExtractorGDBRemote::eServerPacketType_qSupported,
       &GDBRemoteCommunicationServerCommon::Handle_qSupported);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
-      &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
-  RegisterMemberFunctionHandler(
       StringExtractorGDBRemote::eServerPacketType_qUserName,
       &GDBRemoteCommunicationServerCommon::Handle_qUserName);
   RegisterMemberFunctionHandler(
@@ -175,7 +168,8 @@
 }
 
 // Destructor
-GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
+GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() =
+    default;
 
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
@@ -831,39 +825,10 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerCommon::Handle_qSupported(
     StringExtractorGDBRemote &packet) {
-  StreamGDBRemote response;
-
-  // Features common to lldb-platform and llgs.
-  uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
-                                         // size--debugger can always use less
-  response.Printf("PacketSize=%x", max_packet_size);
-
-  response.PutCString(";QStartNoAckMode+");
-  response.PutCString(";QThreadSuffixSupported+");
-  response.PutCString(";QListThreadsInStopReply+");
-  response.PutCString(";qEcho+");
-  response.PutCString(";qXfer:features:read+");
-#if defined(__linux__) || defined(__NetBSD__) || defined(__FreeBSD__)
-  response.PutCString(";QPassSignals+");
-  response.PutCString(";qXfer:auxv:read+");
-  response.PutCString(";qXfer:libraries-svr4:read+");
-#endif
-
-  return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
-    StringExtractorGDBRemote &packet) {
-  m_thread_suffix_supported = true;
-  return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
-    StringExtractorGDBRemote &packet) {
-  m_list_threads_in_stop_reply = true;
-  return SendOKResponse();
+  // Parse client-indicated features.
+  llvm::SmallVector<llvm::StringRef, 4> client_features;
+  packet.GetStringRef().split(client_features, ';');
+  return SendPacketNoLock(llvm::join(HandleFeatures(client_features), ";"));
 }
 
 GDBRemoteCommunication::PacketResult
@@ -1311,3 +1276,16 @@
 
   return matched_module_spec;
 }
+
+std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures(
+    const llvm::ArrayRef<llvm::StringRef> client_features) {
+  // 128KBytes is a reasonable max packet size--debugger can always use less.
+  constexpr uint32_t max_packet_size = 128 * 1024;
+
+  // Features common to platform server and llgs.
+  return {
+      llvm::formatv("PacketSize={0}", max_packet_size),
+      "QStartNoAckMode+",
+      "qEcho+",
+  };
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 0f933c0..ecd8092 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -36,8 +36,6 @@
   Status m_process_launch_error;
   ProcessInstanceInfoList m_proc_infos;
   uint32_t m_proc_infos_index;
-  bool m_thread_suffix_supported;
-  bool m_list_threads_in_stop_reply;
 
   PacketResult Handle_A(StringExtractorGDBRemote &packet);
 
@@ -91,10 +89,6 @@
 
   PacketResult Handle_qSupported(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
-
-  PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
-
   PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet);
 
   PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet);
@@ -145,6 +139,11 @@
   virtual FileSpec FindModuleFile(const std::string &module_path,
                                   const ArchSpec &arch);
 
+  // Process client_features (qSupported) and return an array of server features
+  // to be returned in response.
+  virtual std::vector<std::string>
+  HandleFeatures(llvm::ArrayRef<llvm::StringRef> client_features);
+
 private:
   ModuleSpec GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple);
 };
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 62a09a2..8e1f6bc 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -6,13 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <errno.h>
+#include <cerrno>
 
 #include "lldb/Host/Config.h"
 
 
 #include <chrono>
 #include <cstring>
+#include <limits>
 #include <thread>
 
 #include "GDBRemoteCommunicationServerLLGS.h"
@@ -70,6 +71,7 @@
     : GDBRemoteCommunicationServerCommon("gdb-remote.server",
                                          "gdb-remote.server.rx_packet"),
       m_mainloop(mainloop), m_process_factory(process_factory),
+      m_current_process(nullptr), m_continue_process(nullptr),
       m_stdio_communication("process.stdio") {
   RegisterPacketHandlers();
 }
@@ -113,6 +115,12 @@
       StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
       &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
   RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
+      &GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
+      &GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply);
+  RegisterMemberFunctionHandler(
       StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
       &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
   RegisterMemberFunctionHandler(
@@ -186,27 +194,32 @@
       &GDBRemoteCommunicationServerLLGS::Handle_QPassSignals);
 
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jTraceStart,
-      &GDBRemoteCommunicationServerLLGS::Handle_jTraceStart);
+      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupported,
+      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jTraceBufferRead,
-      &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStart,
+      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jTraceMetaRead,
-      &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceStop,
+      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jTraceStop,
-      &GDBRemoteCommunicationServerLLGS::Handle_jTraceStop);
+      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetState,
+      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState);
   RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
-      &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
-  RegisterMemberFunctionHandler(
-      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType,
-      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType);
+      StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
+      &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
 
   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
                                 &GDBRemoteCommunicationServerLLGS::Handle_g);
 
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qMemTags,
+      &GDBRemoteCommunicationServerLLGS::Handle_qMemTags);
+
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QMemTags,
+      &GDBRemoteCommunicationServerLLGS::Handle_QMemTags);
+
   RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
                         [this](StringExtractorGDBRemote packet, Status &error,
                                bool &interrupt, bool &quit) {
@@ -245,15 +258,18 @@
 
   {
     std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
-    assert(!m_debugged_process_up && "lldb-server creating debugged "
-                                     "process but one already exists");
+    assert(m_debugged_processes.empty() && "lldb-server creating debugged "
+                                           "process but one already exists");
     auto process_or =
         m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
     if (!process_or)
       return Status(process_or.takeError());
-    m_debugged_process_up = std::move(*process_or);
+    m_continue_process = m_current_process = process_or->get();
+    m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
   }
 
+  SetEnabledExtensions(*m_current_process);
+
   // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as
   // needed. llgs local-process debugging may specify PTY paths, which will
   // make these file actions non-null process launch -i/e/o will also make
@@ -266,10 +282,10 @@
     LLDB_LOG(log,
              "pid = {0}: setting up stdout/stderr redirection via $O "
              "gdb-remote commands",
-             m_debugged_process_up->GetID());
+             m_current_process->GetID());
 
     // Setup stdout/stderr mapping from inferior to $O
-    auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
+    auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
     if (terminal_fd >= 0) {
       LLDB_LOGF(log,
                 "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
@@ -288,12 +304,12 @@
     LLDB_LOG(log,
              "pid = {0} skipping stdout/stderr redirection via $O: inferior "
              "will communicate over client-provided file descriptors",
-             m_debugged_process_up->GetID());
+             m_current_process->GetID());
   }
 
   printf("Launched '%s' as process %" PRIu64 "...\n",
          m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
-         m_debugged_process_up->GetID());
+         m_current_process->GetID());
 
   return Status();
 }
@@ -305,12 +321,11 @@
 
   // Before we try to attach, make sure we aren't already monitoring something
   // else.
-  if (m_debugged_process_up &&
-      m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID)
+  if (!m_debugged_processes.empty())
     return Status("cannot attach to process %" PRIu64
                   " when another process with pid %" PRIu64
                   " is being debugged.",
-                  pid, m_debugged_process_up->GetID());
+                  pid, m_current_process->GetID());
 
   // Try to attach.
   auto process_or = m_process_factory.Attach(pid, *this, m_mainloop);
@@ -320,10 +335,12 @@
                                   status);
     return status;
   }
-  m_debugged_process_up = std::move(*process_or);
+  m_continue_process = m_current_process = process_or->get();
+  m_debugged_processes[m_current_process->GetID()] = std::move(*process_or);
+  SetEnabledExtensions(*m_current_process);
 
   // Setup stdout/stderr mapping from inferior.
-  auto terminal_fd = m_debugged_process_up->GetTerminalFileDescriptor();
+  auto terminal_fd = m_current_process->GetTerminalFileDescriptor();
   if (terminal_fd >= 0) {
     LLDB_LOGF(log,
               "ProcessGDBRemoteCommunicationServerLLGS::%s setting "
@@ -648,6 +665,14 @@
     return "exception";
   case eStopReasonExec:
     return "exec";
+  case eStopReasonProcessorTrace:
+    return "processor trace";
+  case eStopReasonFork:
+    return "fork";
+  case eStopReasonVFork:
+    return "vfork";
+  case eStopReasonVForkDone:
+    return "vforkdone";
   case eStopReasonInstrumentation:
   case eStopReasonInvalid:
   case eStopReasonPlanComplete:
@@ -736,15 +761,15 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
   // Ensure we have a debugged process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(50);
 
   LLDB_LOG(log, "preparing packet for pid {0} tid {1}",
-           m_debugged_process_up->GetID(), tid);
+           m_current_process->GetID(), tid);
 
   // Ensure we can get info on the given thread.
-  NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+  NativeThreadProtocol *thread = m_current_process->GetThreadByID(tid);
   if (!thread)
     return SendErrorResponse(51);
 
@@ -767,7 +792,7 @@
   LLDB_LOG(
       log,
       "pid {0}, tid {1}, got signal signo = {2}, reason = {3}, exc_type = {4}",
-      m_debugged_process_up->GetID(), tid, signum, int(tid_stop_info.reason),
+      m_current_process->GetID(), tid, signum, int(tid_stop_info.reason),
       tid_stop_info.details.exception.type);
 
   // Print the signal number.
@@ -805,9 +830,9 @@
 
     uint32_t thread_index = 0;
     NativeThreadProtocol *listed_thread;
-    for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+    for (listed_thread = m_current_process->GetThreadAtIndex(thread_index);
          listed_thread; ++thread_index,
-        listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+        listed_thread = m_current_process->GetThreadAtIndex(thread_index)) {
       if (thread_index > 0)
         response.PutChar(',');
       response.Printf("%" PRIx64, listed_thread->GetID());
@@ -822,7 +847,7 @@
     if (thread_index > 1) {
       const bool threads_with_valid_stop_info_only = true;
       llvm::Expected<json::Array> threads_info = GetJSONThreadsInfo(
-          *m_debugged_process_up, threads_with_valid_stop_info_only);
+          *m_current_process, threads_with_valid_stop_info_only);
       if (threads_info) {
         response.PutCString("jstopinfo:");
         StreamString unescaped_response;
@@ -832,7 +857,7 @@
       } else {
         LLDB_LOG_ERROR(log, threads_info.takeError(),
                        "failed to prepare a jstopinfo field for pid {1}: {0}",
-                       m_debugged_process_up->GetID());
+                       m_current_process->GetID());
       }
     }
 
@@ -840,8 +865,7 @@
     response.PutCString("thread-pcs");
     char delimiter = ':';
     for (NativeThreadProtocol *thread;
-         (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
-         ++i) {
+         (thread = m_current_process->GetThreadAtIndex(i)) != nullptr; ++i) {
       NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
 
       uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
@@ -924,6 +948,22 @@
     }
   }
 
+  // Include child process PID/TID for forks.
+  if (tid_stop_info.reason == eStopReasonFork ||
+      tid_stop_info.reason == eStopReasonVFork) {
+    assert(bool(m_extensions_supported &
+                NativeProcessProtocol::Extension::multiprocess));
+    if (tid_stop_info.reason == eStopReasonFork)
+      assert(bool(m_extensions_supported &
+                  NativeProcessProtocol::Extension::fork));
+    if (tid_stop_info.reason == eStopReasonVFork)
+      assert(bool(m_extensions_supported &
+                  NativeProcessProtocol::Extension::vfork));
+    response.Printf("%s:p%" PRIx64 ".%" PRIx64 ";", reason_str,
+                    tid_stop_info.details.fork.child_pid,
+                    tid_stop_info.details.fork.child_tid);
+  }
+
   return SendPacketNoLock(response.GetString());
 }
 
@@ -1028,6 +1068,15 @@
   ClearProcessSpecificData();
 }
 
+void GDBRemoteCommunicationServerLLGS::NewSubprocess(
+    NativeProcessProtocol *parent_process,
+    std::unique_ptr<NativeProcessProtocol> child_process) {
+  lldb::pid_t child_pid = child_process->GetID();
+  assert(child_pid != LLDB_INVALID_PROCESS_ID);
+  assert(m_debugged_processes.find(child_pid) == m_debugged_processes.end());
+  m_debugged_processes[child_pid] = std::move(child_process);
+}
+
 void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
   Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
 
@@ -1170,266 +1219,110 @@
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceStart(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupported(
     StringExtractorGDBRemote &packet) {
-  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
-    return SendErrorResponse(68);
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(Status("Process not running."));
 
-  if (!packet.ConsumeFront("jTraceStart:"))
-    return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
-  TraceOptions options;
-  uint64_t type = std::numeric_limits<uint64_t>::max();
-  uint64_t buffersize = std::numeric_limits<uint64_t>::max();
-  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-  uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
-
-  auto json_object = StructuredData::ParseJSON(packet.Peek());
-
-  if (!json_object ||
-      json_object->GetType() != lldb::eStructuredDataTypeDictionary)
-    return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
-  auto json_dict = json_object->GetAsDictionary();
-
-  json_dict->GetValueForKeyAsInteger("metabuffersize", metabuffersize);
-  options.setMetaDataBufferSize(metabuffersize);
-
-  json_dict->GetValueForKeyAsInteger("buffersize", buffersize);
-  options.setTraceBufferSize(buffersize);
-
-  json_dict->GetValueForKeyAsInteger("type", type);
-  options.setType(static_cast<lldb::TraceType>(type));
-
-  json_dict->GetValueForKeyAsInteger("threadid", tid);
-  options.setThreadID(tid);
-
-  StructuredData::ObjectSP custom_params_sp =
-      json_dict->GetValueForKey("params");
-  if (custom_params_sp &&
-      custom_params_sp->GetType() != lldb::eStructuredDataTypeDictionary)
-    return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
-
-  options.setTraceParams(
-      std::static_pointer_cast<StructuredData::Dictionary>(custom_params_sp));
-
-  if (buffersize == std::numeric_limits<uint64_t>::max() ||
-      type != lldb::TraceType::eTraceTypeProcessorTrace) {
-    LLDB_LOG(log, "Ill formed packet buffersize = {0} type = {1}", buffersize,
-             type);
-    return SendIllFormedResponse(packet, "JTrace:start: Ill formed packet ");
-  }
-
-  Status error;
-  lldb::user_id_t uid = LLDB_INVALID_UID;
-  uid = m_debugged_process_up->StartTrace(options, error);
-  LLDB_LOG(log, "uid is {0} , error is {1}", uid, error.GetError());
-  if (error.Fail())
-    return SendErrorResponse(error);
-
-  StreamGDBRemote response;
-  response.Printf("%" PRIx64, uid);
-  return SendPacketNoLock(response.GetString());
+  return SendJSONResponse(m_current_process->TraceSupported());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStop(
     StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
-    return SendErrorResponse(68);
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(Status("Process not running."));
 
-  if (!packet.ConsumeFront("jTraceStop:"))
-    return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
+  packet.ConsumeFront("jLLDBTraceStop:");
+  Expected<TraceStopRequest> stop_request =
+      json::parse<TraceStopRequest>(packet.Peek(), "TraceStopRequest");
+  if (!stop_request)
+    return SendErrorResponse(stop_request.takeError());
 
-  lldb::user_id_t uid = LLDB_INVALID_UID;
-  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-
-  auto json_object = StructuredData::ParseJSON(packet.Peek());
-
-  if (!json_object ||
-      json_object->GetType() != lldb::eStructuredDataTypeDictionary)
-    return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
-
-  auto json_dict = json_object->GetAsDictionary();
-
-  if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
-    return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
-
-  json_dict->GetValueForKeyAsInteger("threadid", tid);
-
-  Status error = m_debugged_process_up->StopTrace(uid, tid);
-
-  if (error.Fail())
-    return SendErrorResponse(error);
+  if (Error err = m_current_process->TraceStop(*stop_request))
+    return SendErrorResponse(std::move(err));
 
   return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceStart(
     StringExtractorGDBRemote &packet) {
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(Status("Process not running."));
 
-  llvm::Expected<TraceTypeInfo> supported_trace_type =
-      m_debugged_process_up->GetSupportedTraceType();
-  if (!supported_trace_type)
-    return SendErrorResponse(supported_trace_type.takeError());
+  packet.ConsumeFront("jLLDBTraceStart:");
+  Expected<TraceStartRequest> request =
+      json::parse<TraceStartRequest>(packet.Peek(), "TraceStartRequest");
+  if (!request)
+    return SendErrorResponse(request.takeError());
 
-  StreamGDBRemote escaped_response;
-  StructuredData::Dictionary json_packet;
+  if (Error err = m_current_process->TraceStart(packet.Peek(), request->type))
+    return SendErrorResponse(std::move(err));
 
-  json_packet.AddStringItem("name", supported_trace_type->name);
-  json_packet.AddStringItem("description", supported_trace_type->description);
-
-  StreamString json_string;
-  json_packet.Dump(json_string, false);
-  escaped_response.PutEscapedBytes(json_string.GetData(),
-                                   json_string.GetSize());
-  return SendPacketNoLock(escaped_response.GetString());
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetState(
     StringExtractorGDBRemote &packet) {
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
-    return SendErrorResponse(68);
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(Status("Process not running."));
 
-  if (!packet.ConsumeFront("jTraceConfigRead:"))
-    return SendIllFormedResponse(packet,
-                                 "jTraceConfigRead: Ill formed packet ");
+  packet.ConsumeFront("jLLDBTraceGetState:");
+  Expected<TraceGetStateRequest> request =
+      json::parse<TraceGetStateRequest>(packet.Peek(), "TraceGetStateRequest");
+  if (!request)
+    return SendErrorResponse(request.takeError());
 
-  lldb::user_id_t uid = LLDB_INVALID_UID;
-  lldb::tid_t threadid = LLDB_INVALID_THREAD_ID;
-
-  auto json_object = StructuredData::ParseJSON(packet.Peek());
-
-  if (!json_object ||
-      json_object->GetType() != lldb::eStructuredDataTypeDictionary)
-    return SendIllFormedResponse(packet,
-                                 "jTraceConfigRead: Ill formed packet ");
-
-  auto json_dict = json_object->GetAsDictionary();
-
-  if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
-    return SendIllFormedResponse(packet,
-                                 "jTraceConfigRead: Ill formed packet ");
-
-  json_dict->GetValueForKeyAsInteger("threadid", threadid);
-
-  TraceOptions options;
-  StreamGDBRemote response;
-
-  options.setThreadID(threadid);
-  Status error = m_debugged_process_up->GetTraceConfig(uid, options);
-
-  if (error.Fail())
-    return SendErrorResponse(error);
-
-  StreamGDBRemote escaped_response;
-  StructuredData::Dictionary json_packet;
-
-  json_packet.AddIntegerItem("type", options.getType());
-  json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
-  json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
-
-  StructuredData::DictionarySP custom_params = options.getTraceParams();
-  if (custom_params)
-    json_packet.AddItem("params", custom_params);
-
-  StreamString json_string;
-  json_packet.Dump(json_string, false);
-  escaped_response.PutEscapedBytes(json_string.GetData(),
-                                   json_string.GetSize());
-  return SendPacketNoLock(escaped_response.GetString());
+  return SendJSONResponse(m_current_process->TraceGetState(request->type));
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jTraceRead(
+GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData(
     StringExtractorGDBRemote &packet) {
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
-    return SendErrorResponse(68);
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(Status("Process not running."));
 
-  enum PacketType { MetaData, BufferData };
-  PacketType tracetype = MetaData;
+  packet.ConsumeFront("jLLDBTraceGetBinaryData:");
+  llvm::Expected<TraceGetBinaryDataRequest> request =
+      llvm::json::parse<TraceGetBinaryDataRequest>(packet.Peek(),
+                                                   "TraceGetBinaryDataRequest");
+  if (!request)
+    return SendErrorResponse(Status(request.takeError()));
 
-  if (packet.ConsumeFront("jTraceBufferRead:"))
-    tracetype = BufferData;
-  else if (packet.ConsumeFront("jTraceMetaRead:"))
-    tracetype = MetaData;
-  else {
-    return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
-  }
-
-  lldb::user_id_t uid = LLDB_INVALID_UID;
-
-  uint64_t byte_count = std::numeric_limits<uint64_t>::max();
-  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-  uint64_t offset = std::numeric_limits<uint64_t>::max();
-
-  auto json_object = StructuredData::ParseJSON(packet.Peek());
-
-  if (!json_object ||
-      json_object->GetType() != lldb::eStructuredDataTypeDictionary)
-    return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
-
-  auto json_dict = json_object->GetAsDictionary();
-
-  if (!json_dict->GetValueForKeyAsInteger("traceid", uid) ||
-      !json_dict->GetValueForKeyAsInteger("offset", offset) ||
-      !json_dict->GetValueForKeyAsInteger("buffersize", byte_count))
-    return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
-
-  json_dict->GetValueForKeyAsInteger("threadid", tid);
-
-  // Allocate the response buffer.
-  std::unique_ptr<uint8_t[]> buffer (new (std::nothrow) uint8_t[byte_count]);
-  if (!buffer)
-    return SendErrorResponse(0x78);
-
-  StreamGDBRemote response;
-  Status error;
-  llvm::MutableArrayRef<uint8_t> buf(buffer.get(), byte_count);
-
-  if (tracetype == BufferData)
-    error = m_debugged_process_up->GetData(uid, tid, buf, offset);
-  else if (tracetype == MetaData)
-    error = m_debugged_process_up->GetMetaData(uid, tid, buf, offset);
-
-  if (error.Fail())
-    return SendErrorResponse(error);
-
-  for (auto i : buf)
-    response.PutHex8(i);
-
-  StreamGDBRemote escaped_response;
-  escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
-  return SendPacketNoLock(escaped_response.GetString());
+  if (Expected<std::vector<uint8_t>> bytes =
+          m_current_process->TraceGetBinaryData(*request)) {
+    StreamGDBRemote response;
+    response.PutEscapedBytes(bytes->data(), bytes->size());
+    return SendPacketNoLock(response.GetString());
+  } else
+    return SendErrorResponse(bytes.takeError());
 }
 
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
     StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(68);
 
-  lldb::pid_t pid = m_debugged_process_up->GetID();
+  lldb::pid_t pid = m_current_process->GetID();
 
   if (pid == LLDB_INVALID_PROCESS_ID)
     return SendErrorResponse(1);
@@ -1446,16 +1339,16 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(68);
 
   // Make sure we set the current thread so g and p packets return the data the
   // gdb will expect.
-  lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
+  lldb::tid_t tid = m_current_process->GetCurrentThreadID();
   SetCurrentThreadID(tid);
 
-  NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread();
+  NativeThreadProtocol *thread = m_current_process->GetCurrentThread();
   if (!thread)
     return SendErrorResponse(69);
 
@@ -1471,15 +1364,15 @@
 
   StopSTDIOForwarding();
 
-  if (!m_debugged_process_up) {
+  if (!m_current_process) {
     LLDB_LOG(log, "No debugged process found.");
     return PacketResult::Success;
   }
 
-  Status error = m_debugged_process_up->Kill();
+  Status error = m_current_process->Kill();
   if (error.Fail())
     LLDB_LOG(log, "Failed to kill debugged process {0}: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
 
   // No OK response for kill packet.
   // return SendOKResponse ();
@@ -1521,12 +1414,26 @@
 }
 
 GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QThreadSuffixSupported(
+    StringExtractorGDBRemote &packet) {
+  m_thread_suffix_supported = true;
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QListThreadsInStopReply(
+    StringExtractorGDBRemote &packet) {
+  m_list_threads_in_stop_reply = true;
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
   LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
 
   // Ensure we have a native process.
-  if (!m_debugged_process_up) {
+  if (!m_continue_process) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s no debugged process "
               "shared pointer",
@@ -1579,20 +1486,20 @@
   } else {
     // Send the signal to the process since we weren't targeting a specific
     // continue thread with the signal.
-    error = m_debugged_process_up->Signal(signo);
+    error = m_continue_process->Signal(signo);
     if (error.Fail()) {
       LLDB_LOG(log, "failed to send signal for process {0}: {1}",
-               m_debugged_process_up->GetID(), error);
+               m_continue_process->GetID(), error);
 
       return SendErrorResponse(0x52);
     }
   }
 
   // Resume the threads.
-  error = m_debugged_process_up->Resume(resume_actions);
+  error = m_continue_process->Resume(resume_actions);
   if (error.Fail()) {
     LLDB_LOG(log, "failed to resume threads for process {0}: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_continue_process->GetID(), error);
 
     return SendErrorResponse(0x38);
   }
@@ -1617,7 +1524,7 @@
   }
 
   // Ensure we have a native process.
-  if (!m_debugged_process_up) {
+  if (!m_continue_process) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s no debugged process "
               "shared pointer",
@@ -1629,14 +1536,14 @@
   ResumeActionList actions(StateType::eStateRunning,
                            LLDB_INVALID_SIGNAL_NUMBER);
 
-  Status error = m_debugged_process_up->Resume(actions);
+  Status error = m_continue_process->Resume(actions);
   if (error.Fail()) {
-    LLDB_LOG(log, "c failed for process {0}: {1}",
-             m_debugged_process_up->GetID(), error);
+    LLDB_LOG(log, "c failed for process {0}: {1}", m_continue_process->GetID(),
+             error);
     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
   }
 
-  LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID());
+  LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
   // No response required from continue.
   return PacketResult::Success;
 }
@@ -1679,7 +1586,7 @@
   }
 
   // Ensure we have a native process.
-  if (!m_debugged_process_up) {
+  if (!m_continue_process) {
     LLDB_LOG(log, "no debugged process");
     return SendErrorResponse(0x36);
   }
@@ -1732,23 +1639,27 @@
       // Consume the separator.
       packet.GetChar();
 
-      thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
-      if (thread_action.tid == LLDB_INVALID_THREAD_ID)
-        return SendIllFormedResponse(
-            packet, "Could not parse thread number in vCont packet");
+      llvm::Expected<lldb::tid_t> tid_ret =
+          ReadTid(packet, /*allow_all=*/true, m_continue_process->GetID());
+      if (!tid_ret)
+        return SendErrorResponse(tid_ret.takeError());
+
+      thread_action.tid = tid_ret.get();
+      if (thread_action.tid == StringExtractorGDBRemote::AllThreads)
+        thread_action.tid = LLDB_INVALID_THREAD_ID;
     }
 
     thread_actions.Append(thread_action);
   }
 
-  Status error = m_debugged_process_up->Resume(thread_actions);
+  Status error = m_continue_process->Resume(thread_actions);
   if (error.Fail()) {
     LLDB_LOG(log, "vCont failed for process {0}: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_continue_process->GetID(), error);
     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
   }
 
-  LLDB_LOG(log, "continued process {0}", m_debugged_process_up->GetID());
+  LLDB_LOG(log, "continued process {0}", m_continue_process->GetID());
   // No response required from vCont.
   return PacketResult::Success;
 }
@@ -1758,8 +1669,8 @@
   LLDB_LOG(log, "setting current thread id to {0}", tid);
 
   m_current_tid = tid;
-  if (m_debugged_process_up)
-    m_debugged_process_up->SetCurrentThreadID(m_current_tid);
+  if (m_current_process)
+    m_current_process->SetCurrentThreadID(m_current_tid);
 }
 
 void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
@@ -1775,10 +1686,10 @@
   // Handle the $? gdbremote command.
 
   // If no process, indicate error
-  if (!m_debugged_process_up)
+  if (!m_current_process)
     return SendErrorResponse(02);
 
-  return SendStopReasonForState(m_debugged_process_up->GetState());
+  return SendStopReasonForState(m_current_process->GetState());
 }
 
 GDBRemoteCommunication::PacketResult
@@ -1799,8 +1710,8 @@
   case eStateSuspended:
   case eStateStopped:
   case eStateCrashed: {
-    assert(m_debugged_process_up != nullptr);
-    lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
+    assert(m_current_process != nullptr);
+    lldb::tid_t tid = m_current_process->GetCurrentThreadID();
     // Make sure we set the current thread so g and p packets return the data
     // the gdb will expect.
     SetCurrentThreadID(tid);
@@ -1810,11 +1721,11 @@
   case eStateInvalid:
   case eStateUnloaded:
   case eStateExited:
-    return SendWResponse(m_debugged_process_up.get());
+    return SendWResponse(m_current_process);
 
   default:
     LLDB_LOG(log, "pid {0}, current state reporting not handled: {1}",
-             m_debugged_process_up->GetID(), process_state);
+             m_current_process->GetID(), process_state);
     break;
   }
 
@@ -1825,12 +1736,12 @@
 GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
     StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(68);
 
   // Ensure we have a thread.
-  NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+  NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
   if (!thread)
     return SendErrorResponse(69);
 
@@ -1925,11 +1836,11 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOG(log, "no process ({0}), returning OK",
-             m_debugged_process_up ? "invalid process id"
-                                   : "null m_debugged_process_up");
+             m_current_process ? "invalid process id"
+                               : "null m_current_process");
     return SendOKResponse();
   }
 
@@ -1940,9 +1851,9 @@
   NativeThreadProtocol *thread;
   uint32_t thread_index;
   for (thread_index = 0,
-      thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+      thread = m_current_process->GetThreadAtIndex(thread_index);
        thread; ++thread_index,
-      thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+      thread = m_current_process->GetThreadAtIndex(thread_index)) {
     LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
              thread->GetID());
     if (thread_index > 0)
@@ -2163,9 +2074,8 @@
   // Build the reginfos response.
   StreamGDBRemote response;
 
-  RegisterValue reg_value(
-      makeArrayRef(reg_bytes, reg_size),
-      m_debugged_process_up->GetArchitecture().GetByteOrder());
+  RegisterValue reg_value(makeArrayRef(reg_bytes, reg_size),
+                          m_current_process->GetArchitecture().GetByteOrder());
   Status error = reg_context.WriteRegister(reg_info, reg_value);
   if (error.Fail()) {
     LLDB_LOGF(log,
@@ -2182,16 +2092,6 @@
 GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-  // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
-    LLDB_LOGF(
-        log,
-        "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
-        __FUNCTION__);
-    return SendErrorResponse(0x15);
-  }
-
   // Parse out which variant of $H is requested.
   packet.SetFilePos(strlen("H"));
   if (packet.GetBytesLeft() < 1) {
@@ -2203,11 +2103,14 @@
   }
 
   const char h_variant = packet.GetChar();
+  NativeProcessProtocol *default_process;
   switch (h_variant) {
   case 'g':
+    default_process = m_current_process;
     break;
 
   case 'c':
+    default_process = m_continue_process;
     break;
 
   default:
@@ -2220,14 +2123,32 @@
   }
 
   // Parse out the thread number.
-  // FIXME return a parse success/fail value.  All values are valid here.
-  const lldb::tid_t tid =
-      packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max());
+  auto pid_tid = packet.GetPidTid(default_process ? default_process->GetID()
+                                                  : LLDB_INVALID_PROCESS_ID);
+  if (!pid_tid)
+    return SendErrorResponse(llvm::make_error<StringError>(
+        inconvertibleErrorCode(), "Malformed thread-id"));
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  if (pid == StringExtractorGDBRemote::AllProcesses)
+    return SendUnimplementedResponse("Selecting all processes not supported");
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(llvm::make_error<StringError>(
+        inconvertibleErrorCode(), "No current process and no PID provided"));
+
+  // Check the process ID and find respective process instance.
+  auto new_process_it = m_debugged_processes.find(pid);
+  if (new_process_it == m_debugged_processes.end())
+    return SendErrorResponse(llvm::make_error<StringError>(
+        inconvertibleErrorCode(),
+        llvm::formatv("No process with PID {0} debugged", pid)));
 
   // Ensure we have the given thread when not specifying -1 (all threads) or 0
   // (any thread).
   if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
-    NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+    NativeThreadProtocol *thread = new_process_it->second->GetThreadByID(tid);
     if (!thread) {
       LLDB_LOGF(log,
                 "GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
@@ -2237,13 +2158,15 @@
     }
   }
 
-  // Now switch the given thread type.
+  // Now switch the given process and thread type.
   switch (h_variant) {
   case 'g':
+    m_current_process = new_process_it->second.get();
     SetCurrentThreadID(tid);
     break;
 
   case 'c':
+    m_continue_process = new_process_it->second.get();
     SetContinueThreadID(tid);
     break;
 
@@ -2261,8 +2184,8 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2297,21 +2220,21 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOG(log, "failed, no process available");
     return SendErrorResponse(0x15);
   }
 
   // Interrupt the process.
-  Status error = m_debugged_process_up->Interrupt();
+  Status error = m_current_process->Interrupt();
   if (error.Fail()) {
-    LLDB_LOG(log, "failed for process {0}: {1}", m_debugged_process_up->GetID(),
+    LLDB_LOG(log, "failed for process {0}: {1}", m_current_process->GetID(),
              error);
     return SendErrorResponse(GDBRemoteServerError::eErrorResume);
   }
 
-  LLDB_LOG(log, "stopped process {0}", m_debugged_process_up->GetID());
+  LLDB_LOG(log, "stopped process {0}", m_current_process->GetID());
 
   // No response required from stop all.
   return PacketResult::Success;
@@ -2322,8 +2245,8 @@
     StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2365,13 +2288,13 @@
 
   // Retrieve the process memory.
   size_t bytes_read = 0;
-  Status error = m_debugged_process_up->ReadMemoryWithoutTrap(
+  Status error = m_current_process->ReadMemoryWithoutTrap(
       read_addr, &buf[0], byte_count, bytes_read);
   if (error.Fail()) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
               " mem 0x%" PRIx64 ": failed to read. Error: %s",
-              __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
+              __FUNCTION__, m_current_process->GetID(), read_addr,
               error.AsCString());
     return SendErrorResponse(0x08);
   }
@@ -2380,8 +2303,7 @@
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
               " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
-              __FUNCTION__, m_debugged_process_up->GetID(), read_addr,
-              byte_count);
+              __FUNCTION__, m_current_process->GetID(), read_addr, byte_count);
     return SendErrorResponse(0x08);
   }
 
@@ -2403,8 +2325,8 @@
 GDBRemoteCommunicationServerLLGS::Handle__M(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2439,8 +2361,7 @@
     }
   }
 
-  llvm::Expected<addr_t> addr =
-      m_debugged_process_up->AllocateMemory(size, perms);
+  llvm::Expected<addr_t> addr = m_current_process->AllocateMemory(size, perms);
   if (!addr)
     return SendErrorResponse(addr.takeError());
 
@@ -2453,8 +2374,8 @@
 GDBRemoteCommunicationServerLLGS::Handle__m(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2471,7 +2392,7 @@
   if (addr == LLDB_INVALID_ADDRESS)
     return SendIllFormedResponse(packet, "Address not valid");
 
-  if (llvm::Error Err = m_debugged_process_up->DeallocateMemory(addr))
+  if (llvm::Error Err = m_current_process->DeallocateMemory(addr))
     return SendErrorResponse(std::move(Err));
 
   return SendOKResponse();
@@ -2481,8 +2402,8 @@
 GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2531,8 +2452,7 @@
     LLDB_LOG(log,
              "pid {0} mem {1:x}: asked to write {2} bytes, but only found {3} "
              "to convert.",
-             m_debugged_process_up->GetID(), write_addr, byte_count,
-             convert_count);
+             m_current_process->GetID(), write_addr, byte_count, convert_count);
     return SendIllFormedResponse(packet, "M content byte length specified did "
                                          "not match hex-encoded content "
                                          "length");
@@ -2540,17 +2460,17 @@
 
   // Write the process memory.
   size_t bytes_written = 0;
-  Status error = m_debugged_process_up->WriteMemory(write_addr, &buf[0],
-                                                    byte_count, bytes_written);
+  Status error = m_current_process->WriteMemory(write_addr, &buf[0], byte_count,
+                                                bytes_written);
   if (error.Fail()) {
     LLDB_LOG(log, "pid {0} mem {1:x}: failed to write. Error: {2}",
-             m_debugged_process_up->GetID(), write_addr, error);
+             m_current_process->GetID(), write_addr, error);
     return SendErrorResponse(0x09);
   }
 
   if (bytes_written == 0) {
     LLDB_LOG(log, "pid {0} mem {1:x}: wrote 0 of {2} requested bytes",
-             m_debugged_process_up->GetID(), write_addr, byte_count);
+             m_current_process->GetID(), write_addr, byte_count);
     return SendErrorResponse(0x09);
   }
 
@@ -2569,8 +2489,8 @@
 
   // Ensure we have a process running; otherwise, we can't figure this out
   // since we won't have a NativeProcessProtocol.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2580,8 +2500,7 @@
 
   // Test if we can get any region back when asking for the region around NULL.
   MemoryRegionInfo region_info;
-  const Status error =
-      m_debugged_process_up->GetMemoryRegionInfo(0, region_info);
+  const Status error = m_current_process->GetMemoryRegionInfo(0, region_info);
   if (error.Fail()) {
     // We don't support memory region info collection for this
     // NativeProcessProtocol.
@@ -2597,8 +2516,8 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
   // Ensure we have a process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2619,7 +2538,7 @@
   // Get the memory region info for the target address.
   MemoryRegionInfo region_info;
   const Status error =
-      m_debugged_process_up->GetMemoryRegionInfo(read_addr, region_info);
+      m_current_process->GetMemoryRegionInfo(read_addr, region_info);
   if (error.Fail()) {
     // Return the error message.
 
@@ -2674,8 +2593,8 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
   // Ensure we have a process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
     LLDB_LOG(log, "failed, no process available");
     return SendErrorResponse(0x15);
@@ -2745,22 +2664,22 @@
   if (want_breakpoint) {
     // Try to set the breakpoint.
     const Status error =
-        m_debugged_process_up->SetBreakpoint(addr, size, want_hardware);
+        m_current_process->SetBreakpoint(addr, size, want_hardware);
     if (error.Success())
       return SendOKResponse();
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
     LLDB_LOG(log, "pid {0} failed to set breakpoint: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x09);
   } else {
     // Try to set the watchpoint.
-    const Status error = m_debugged_process_up->SetWatchpoint(
+    const Status error = m_current_process->SetWatchpoint(
         addr, size, watch_flags, want_hardware);
     if (error.Success())
       return SendOKResponse();
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
     LLDB_LOG(log, "pid {0} failed to set watchpoint: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x09);
   }
 }
@@ -2768,8 +2687,8 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
   // Ensure we have a process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
     LLDB_LOG(log, "failed, no process available");
     return SendErrorResponse(0x15);
@@ -2833,21 +2752,21 @@
   if (want_breakpoint) {
     // Try to clear the breakpoint.
     const Status error =
-        m_debugged_process_up->RemoveBreakpoint(addr, want_hardware);
+        m_current_process->RemoveBreakpoint(addr, want_hardware);
     if (error.Success())
       return SendOKResponse();
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
     LLDB_LOG(log, "pid {0} failed to remove breakpoint: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x09);
   } else {
     // Try to clear the watchpoint.
-    const Status error = m_debugged_process_up->RemoveWatchpoint(addr);
+    const Status error = m_current_process->RemoveWatchpoint(addr);
     if (error.Success())
       return SendOKResponse();
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
     LLDB_LOG(log, "pid {0} failed to remove watchpoint: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x09);
   }
 }
@@ -2857,8 +2776,8 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
   // Ensure we have a process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_continue_process ||
+      (m_continue_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     LLDB_LOGF(
         log,
         "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
@@ -2876,7 +2795,7 @@
 
   // Double check that we have such a thread.
   // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
-  NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+  NativeThreadProtocol *thread = m_continue_process->GetThreadByID(tid);
   if (!thread)
     return SendErrorResponse(0x33);
 
@@ -2889,12 +2808,12 @@
 
   // All other threads stop while we're single stepping a thread.
   actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
-  Status error = m_debugged_process_up->Resume(actions);
+  Status error = m_continue_process->Resume(actions);
   if (error.Fail()) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
               " tid %" PRIu64 " Resume() failed with error: %s",
-              __FUNCTION__, m_debugged_process_up->GetID(), tid,
+              __FUNCTION__, m_continue_process->GetID(), tid,
               error.AsCString());
     return SendErrorResponse(0x49);
   }
@@ -2906,7 +2825,7 @@
 llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
 GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
   // Ensure we have a thread.
-  NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+  NativeThreadProtocol *thread = m_current_process->GetThreadAtIndex(0);
   if (!thread)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "No thread available");
@@ -2921,7 +2840,7 @@
   response.Printf("<target version=\"1.0\">");
 
   response.Printf("<architecture>%s</architecture>",
-                  m_debugged_process_up->GetArchitecture()
+                  m_current_process->GetArchitecture()
                       .GetTriple()
                       .getArchName()
                       .str()
@@ -3010,22 +2929,22 @@
 GDBRemoteCommunicationServerLLGS::ReadXferObject(llvm::StringRef object,
                                                  llvm::StringRef annex) {
   // Make sure we have a valid process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "No process available");
   }
 
   if (object == "auxv") {
     // Grab the auxv data.
-    auto buffer_or_error = m_debugged_process_up->GetAuxvData();
+    auto buffer_or_error = m_current_process->GetAuxvData();
     if (!buffer_or_error)
       return llvm::errorCodeToError(buffer_or_error.getError());
     return std::move(*buffer_or_error);
   }
 
   if (object == "libraries-svr4") {
-    auto library_list = m_debugged_process_up->GetLoadedSVR4Libraries();
+    auto library_list = m_current_process->GetLoadedSVR4Libraries();
     if (!library_list)
       return library_list.takeError();
 
@@ -3148,7 +3067,7 @@
   Status error = reg_context.ReadAllRegisterValues(register_data_sp);
   if (error.Fail()) {
     LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x75);
   }
 
@@ -3211,7 +3130,7 @@
     if (it == m_saved_registers_map.end()) {
       LLDB_LOG(log,
                "pid {0} does not have a register set save buffer for id {1}",
-               m_debugged_process_up->GetID(), save_id);
+               m_current_process->GetID(), save_id);
       return SendErrorResponse(0x77);
     }
     register_data_sp = it->second;
@@ -3223,7 +3142,7 @@
   Status error = reg_context.WriteAllRegisterValues(register_data_sp);
   if (error.Fail()) {
     LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
-             m_debugged_process_up->GetID(), error);
+             m_current_process->GetID(), error);
     return SendErrorResponse(0x77);
   }
 
@@ -3263,7 +3182,7 @@
   }
 
   // Notify we attached by sending a stop packet.
-  return SendStopReasonForState(m_debugged_process_up->GetState());
+  return SendStopReasonForState(m_current_process->GetState());
 }
 
 GDBRemoteCommunication::PacketResult
@@ -3293,7 +3212,7 @@
   }
 
   // Notify we attached by sending a stop packet.
-  return SendStopReasonForState(m_debugged_process_up->GetState());
+  return SendStopReasonForState(m_current_process->GetState());
 }
 
 GDBRemoteCommunication::PacketResult
@@ -3329,25 +3248,13 @@
   }
 
   // Notify we attached by sending a stop packet.
-  return SendStopReasonForState(m_debugged_process_up->GetState());
+  return SendStopReasonForState(m_current_process->GetState());
 }
 
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
-  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
   StopSTDIOForwarding();
 
-  // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
-    LLDB_LOGF(
-        log,
-        "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
-        __FUNCTION__);
-    return SendErrorResponse(0x15);
-  }
-
   lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
 
   // Consume the ';' after D.
@@ -3362,19 +3269,32 @@
       return SendIllFormedResponse(packet, "D failed to parse the process id");
   }
 
-  if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_up->GetID() != pid) {
-    return SendIllFormedResponse(packet, "Invalid pid");
+  // Detach forked children if their PID was specified *or* no PID was requested
+  // (i.e. detach-all packet).
+  llvm::Error detach_error = llvm::Error::success();
+  bool detached = false;
+  for (auto it = m_debugged_processes.begin();
+       it != m_debugged_processes.end();) {
+    if (pid == LLDB_INVALID_PROCESS_ID || pid == it->first) {
+      if (llvm::Error e = it->second->Detach().ToError())
+        detach_error = llvm::joinErrors(std::move(detach_error), std::move(e));
+      else {
+        if (it->second.get() == m_current_process)
+          m_current_process = nullptr;
+        if (it->second.get() == m_continue_process)
+          m_continue_process = nullptr;
+        it = m_debugged_processes.erase(it);
+        detached = true;
+        continue;
+      }
+    }
+    ++it;
   }
 
-  const Status error = m_debugged_process_up->Detach();
-  if (error.Fail()) {
-    LLDB_LOGF(log,
-              "GDBRemoteCommunicationServerLLGS::%s failed to detach from "
-              "pid %" PRIu64 ": %s\n",
-              __FUNCTION__, m_debugged_process_up->GetID(), error.AsCString());
-    return SendErrorResponse(0x01);
-  }
-
+  if (detach_error)
+    return SendErrorResponse(std::move(detach_error));
+  if (!detached)
+    return SendErrorResponse(Status("PID %" PRIu64 " not traced", pid));
   return SendOKResponse();
 }
 
@@ -3384,7 +3304,7 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
   packet.SetFilePos(strlen("qThreadStopInfo"));
-  const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+  const lldb::tid_t tid = packet.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
   if (tid == LLDB_INVALID_THREAD_ID) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s failed, could not "
@@ -3401,19 +3321,19 @@
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
   // Ensure we have a debugged process.
-  if (!m_debugged_process_up ||
-      (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID))
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
     return SendErrorResponse(50);
-  LLDB_LOG(log, "preparing packet for pid {0}", m_debugged_process_up->GetID());
+  LLDB_LOG(log, "preparing packet for pid {0}", m_current_process->GetID());
 
   StreamString response;
   const bool threads_with_valid_stop_info_only = false;
-  llvm::Expected<json::Value> threads_info = GetJSONThreadsInfo(
-      *m_debugged_process_up, threads_with_valid_stop_info_only);
+  llvm::Expected<json::Value> threads_info =
+      GetJSONThreadsInfo(*m_current_process, threads_with_valid_stop_info_only);
   if (!threads_info) {
     LLDB_LOG_ERROR(log, threads_info.takeError(),
                    "failed to prepare a packet for pid {1}: {0}",
-                   m_debugged_process_up->GetID());
+                   m_current_process->GetID());
     return SendErrorResponse(52);
   }
 
@@ -3427,8 +3347,8 @@
 GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
     StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+  if (!m_current_process ||
+      m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
     return SendErrorResponse(68);
 
   packet.SetFilePos(strlen("qWatchpointSupportInfo"));
@@ -3437,7 +3357,7 @@
   if (packet.GetChar() != ':')
     return SendErrorResponse(67);
 
-  auto hw_debug_cap = m_debugged_process_up->GetHardwareDebugSupportInfo();
+  auto hw_debug_cap = m_current_process->GetHardwareDebugSupportInfo();
 
   StreamGDBRemote response;
   if (hw_debug_cap == llvm::None)
@@ -3452,8 +3372,8 @@
 GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
     StringExtractorGDBRemote &packet) {
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up ||
-      m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+  if (!m_current_process ||
+      m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
     return SendErrorResponse(67);
 
   packet.SetFilePos(strlen("qFileLoadAddress:"));
@@ -3465,7 +3385,7 @@
 
   lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
   Status error =
-      m_debugged_process_up->GetFileLoadAddress(file_name, file_load_address);
+      m_current_process->GetFileLoadAddress(file_name, file_load_address);
   if (error.Fail())
     return SendErrorResponse(69);
 
@@ -3501,16 +3421,189 @@
   }
 
   // Fail if we don't have a current process.
-  if (!m_debugged_process_up)
+  if (!m_current_process)
     return SendErrorResponse(68);
 
-  Status error = m_debugged_process_up->IgnoreSignals(signals);
+  Status error = m_current_process->IgnoreSignals(signals);
   if (error.Fail())
     return SendErrorResponse(69);
 
   return SendOKResponse();
 }
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qMemTags(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  // Ensure we have a process.
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    LLDB_LOGF(
+        log,
+        "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+        __FUNCTION__);
+    return SendErrorResponse(1);
+  }
+
+  // We are expecting
+  // qMemTags:<hex address>,<hex length>:<hex type>
+
+  // Address
+  packet.SetFilePos(strlen("qMemTags:"));
+  const char *current_char = packet.Peek();
+  if (!current_char || *current_char == ',')
+    return SendIllFormedResponse(packet, "Missing address in qMemTags packet");
+  const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+  // Length
+  char previous_char = packet.GetChar();
+  current_char = packet.Peek();
+  // If we don't have a separator or the length field is empty
+  if (previous_char != ',' || (current_char && *current_char == ':'))
+    return SendIllFormedResponse(packet,
+                                 "Invalid addr,length pair in qMemTags packet");
+
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(
+        packet, "Too short qMemtags: packet (looking for length)");
+  const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+  // Type
+  const char *invalid_type_err = "Invalid type field in qMemTags: packet";
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+    return SendIllFormedResponse(packet, invalid_type_err);
+
+  // Type is a signed integer but packed into the packet as its raw bytes.
+  // However, our GetU64 uses strtoull which allows +/-. We do not want this.
+  const char *first_type_char = packet.Peek();
+  if (first_type_char && (*first_type_char == '+' || *first_type_char == '-'))
+    return SendIllFormedResponse(packet, invalid_type_err);
+
+  // Extract type as unsigned then cast to signed.
+  // Using a uint64_t here so that we have some value outside of the 32 bit
+  // range to use as the invalid return value.
+  uint64_t raw_type =
+      packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16);
+
+  if ( // Make sure the cast below would be valid
+      raw_type > std::numeric_limits<uint32_t>::max() ||
+      // To catch inputs like "123aardvark" that will parse but clearly aren't
+      // valid in this case.
+      packet.GetBytesLeft()) {
+    return SendIllFormedResponse(packet, invalid_type_err);
+  }
+
+  // First narrow to 32 bits otherwise the copy into type would take
+  // the wrong 4 bytes on big endian.
+  uint32_t raw_type_32 = raw_type;
+  int32_t type = reinterpret_cast<int32_t &>(raw_type_32);
+
+  StreamGDBRemote response;
+  std::vector<uint8_t> tags;
+  Status error = m_current_process->ReadMemoryTags(type, addr, length, tags);
+  if (error.Fail())
+    return SendErrorResponse(1);
+
+  // This m is here in case we want to support multi part replies in the future.
+  // In the same manner as qfThreadInfo/qsThreadInfo.
+  response.PutChar('m');
+  response.PutBytesAsRawHex8(tags.data(), tags.size());
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QMemTags(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  // Ensure we have a process.
+  if (!m_current_process ||
+      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    LLDB_LOGF(
+        log,
+        "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+        __FUNCTION__);
+    return SendErrorResponse(1);
+  }
+
+  // We are expecting
+  // QMemTags:<hex address>,<hex length>:<hex type>:<tags as hex bytes>
+
+  // Address
+  packet.SetFilePos(strlen("QMemTags:"));
+  const char *current_char = packet.Peek();
+  if (!current_char || *current_char == ',')
+    return SendIllFormedResponse(packet, "Missing address in QMemTags packet");
+  const lldb::addr_t addr = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+  // Length
+  char previous_char = packet.GetChar();
+  current_char = packet.Peek();
+  // If we don't have a separator or the length field is empty
+  if (previous_char != ',' || (current_char && *current_char == ':'))
+    return SendIllFormedResponse(packet,
+                                 "Invalid addr,length pair in QMemTags packet");
+
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(
+        packet, "Too short QMemtags: packet (looking for length)");
+  const size_t length = packet.GetHexMaxU64(/*little_endian=*/false, 0);
+
+  // Type
+  const char *invalid_type_err = "Invalid type field in QMemTags: packet";
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+    return SendIllFormedResponse(packet, invalid_type_err);
+
+  // Our GetU64 uses strtoull which allows leading +/-, we don't want that.
+  const char *first_type_char = packet.Peek();
+  if (first_type_char && (*first_type_char == '+' || *first_type_char == '-'))
+    return SendIllFormedResponse(packet, invalid_type_err);
+
+  // The type is a signed integer but is in the packet as its raw bytes.
+  // So parse first as unsigned then cast to signed later.
+  // We extract to 64 bit, even though we only expect 32, so that we've
+  // got some invalid value we can check for.
+  uint64_t raw_type =
+      packet.GetU64(std::numeric_limits<uint64_t>::max(), /*base=*/16);
+  if (raw_type > std::numeric_limits<uint32_t>::max())
+    return SendIllFormedResponse(packet, invalid_type_err);
+
+  // First narrow to 32 bits. Otherwise the copy below would get the wrong
+  // 4 bytes on big endian.
+  uint32_t raw_type_32 = raw_type;
+  int32_t type = reinterpret_cast<int32_t &>(raw_type_32);
+
+  // Tag data
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ':')
+    return SendIllFormedResponse(packet,
+                                 "Missing tag data in QMemTags: packet");
+
+  // Must be 2 chars per byte
+  const char *invalid_data_err = "Invalid tag data in QMemTags: packet";
+  if (packet.GetBytesLeft() % 2)
+    return SendIllFormedResponse(packet, invalid_data_err);
+
+  // This is bytes here and is unpacked into target specific tags later
+  // We cannot assume that number of bytes == length here because the server
+  // can repeat tags to fill a given range.
+  std::vector<uint8_t> tag_data;
+  // Zero length writes will not have any tag data
+  // (but we pass them on because it will still check that tagging is enabled)
+  if (packet.GetBytesLeft()) {
+    size_t byte_count = packet.GetBytesLeft() / 2;
+    tag_data.resize(byte_count);
+    size_t converted_bytes = packet.GetHexBytes(tag_data, 0);
+    if (converted_bytes != byte_count) {
+      return SendIllFormedResponse(packet, invalid_data_err);
+    }
+  }
+
+  Status status =
+      m_current_process->WriteMemoryTags(type, addr, length, tag_data);
+  return status.Success() ? SendOKResponse() : SendErrorResponse(1);
+}
+
 void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
@@ -3539,8 +3632,8 @@
 NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
     StringExtractorGDBRemote &packet) {
   // We have no thread if we don't have a process.
-  if (!m_debugged_process_up ||
-      m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
+  if (!m_current_process ||
+      m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)
     return nullptr;
 
   // If the client hasn't asked for thread suffix support, there will not be a
@@ -3551,9 +3644,9 @@
       return nullptr;
     else if (current_tid == 0) {
       // Pick a thread.
-      return m_debugged_process_up->GetThreadAtIndex(0);
+      return m_current_process->GetThreadAtIndex(0);
     } else
-      return m_debugged_process_up->GetThreadByID(current_tid);
+      return m_current_process->GetThreadByID(current_tid);
   }
 
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
@@ -3583,7 +3676,7 @@
   packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
   const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
   if (tid != 0)
-    return m_debugged_process_up->GetThreadByID(tid);
+    return m_current_process->GetThreadByID(tid);
 
   return nullptr;
 }
@@ -3593,9 +3686,9 @@
     // Use whatever the debug process says is the current thread id since the
     // protocol either didn't specify or specified we want any/all threads
     // marked as the current thread.
-    if (!m_debugged_process_up)
+    if (!m_current_process)
       return LLDB_INVALID_THREAD_ID;
-    return m_debugged_process_up->GetCurrentThreadID();
+    return m_current_process->GetCurrentThreadID();
   }
   // Use the specific current thread id set by the gdb remote protocol.
   return m_current_tid;
@@ -3616,9 +3709,9 @@
 FileSpec
 GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
                                                  const ArchSpec &arch) {
-  if (m_debugged_process_up) {
+  if (m_current_process) {
     FileSpec file_spec;
-    if (m_debugged_process_up
+    if (m_current_process
             ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
             .Success()) {
       if (FileSystem::Instance().Exists(file_spec))
@@ -3653,3 +3746,93 @@
   }
   return result;
 }
+
+llvm::Expected<lldb::tid_t> GDBRemoteCommunicationServerLLGS::ReadTid(
+    StringExtractorGDBRemote &packet, bool allow_all, lldb::pid_t default_pid) {
+  assert(m_current_process);
+  assert(m_current_process->GetID() != LLDB_INVALID_PROCESS_ID);
+
+  auto pid_tid = packet.GetPidTid(default_pid);
+  if (!pid_tid)
+    return llvm::make_error<StringError>(inconvertibleErrorCode(),
+                                         "Malformed thread-id");
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  if (!allow_all && pid == StringExtractorGDBRemote::AllProcesses)
+    return llvm::make_error<StringError>(
+        inconvertibleErrorCode(),
+        llvm::formatv("PID value {0} not allowed", pid == 0 ? 0 : -1));
+
+  if (!allow_all && tid == StringExtractorGDBRemote::AllThreads)
+    return llvm::make_error<StringError>(
+        inconvertibleErrorCode(),
+        llvm::formatv("TID value {0} not allowed", tid == 0 ? 0 : -1));
+
+  if (pid != StringExtractorGDBRemote::AllProcesses) {
+    if (pid != m_current_process->GetID())
+      return llvm::make_error<StringError>(
+          inconvertibleErrorCode(), llvm::formatv("PID {0} not debugged", pid));
+  }
+
+  return tid;
+}
+
+std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
+    const llvm::ArrayRef<llvm::StringRef> client_features) {
+  std::vector<std::string> ret =
+      GDBRemoteCommunicationServerCommon::HandleFeatures(client_features);
+  ret.insert(ret.end(), {
+                            "QThreadSuffixSupported+",
+                            "QListThreadsInStopReply+",
+                            "qXfer:features:read+",
+                        });
+
+  // report server-only features
+  using Extension = NativeProcessProtocol::Extension;
+  Extension plugin_features = m_process_factory.GetSupportedExtensions();
+  if (bool(plugin_features & Extension::pass_signals))
+    ret.push_back("QPassSignals+");
+  if (bool(plugin_features & Extension::auxv))
+    ret.push_back("qXfer:auxv:read+");
+  if (bool(plugin_features & Extension::libraries_svr4))
+    ret.push_back("qXfer:libraries-svr4:read+");
+  if (bool(plugin_features & Extension::memory_tagging))
+    ret.push_back("memory-tagging+");
+
+  // check for client features
+  m_extensions_supported = {};
+  for (llvm::StringRef x : client_features)
+    m_extensions_supported |=
+        llvm::StringSwitch<Extension>(x)
+            .Case("multiprocess+", Extension::multiprocess)
+            .Case("fork-events+", Extension::fork)
+            .Case("vfork-events+", Extension::vfork)
+            .Default({});
+
+  m_extensions_supported &= plugin_features;
+
+  // fork & vfork require multiprocess
+  if (!bool(m_extensions_supported & Extension::multiprocess))
+    m_extensions_supported &= ~(Extension::fork | Extension::vfork);
+
+  // report only if actually supported
+  if (bool(m_extensions_supported & Extension::multiprocess))
+    ret.push_back("multiprocess+");
+  if (bool(m_extensions_supported & Extension::fork))
+    ret.push_back("fork-events+");
+  if (bool(m_extensions_supported & Extension::vfork))
+    ret.push_back("vfork-events+");
+
+  for (auto &x : m_debugged_processes)
+    SetEnabledExtensions(*x.second);
+  return ret;
+}
+
+void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions(
+    NativeProcessProtocol &process) {
+  NativeProcessProtocol::Extension flags = m_extensions_supported;
+  assert(!bool(flags & ~m_process_factory.GetSupportedExtensions()));
+  process.SetEnabledExtensions(flags);
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index c511399..04d0605 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -78,6 +78,10 @@
 
   void DidExec(NativeProcessProtocol *process) override;
 
+  void
+  NewSubprocess(NativeProcessProtocol *parent_process,
+                std::unique_ptr<NativeProcessProtocol> child_process) override;
+
   Status InitializeConnection(std::unique_ptr<Connection> connection);
 
 protected:
@@ -86,8 +90,11 @@
   const NativeProcessProtocol::Factory &m_process_factory;
   lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
   lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
+  NativeProcessProtocol *m_current_process;
+  NativeProcessProtocol *m_continue_process;
   std::recursive_mutex m_debugged_process_mutex;
-  std::unique_ptr<NativeProcessProtocol> m_debugged_process_up;
+  std::unordered_map<lldb::pid_t, std::unique_ptr<NativeProcessProtocol>>
+      m_debugged_processes;
 
   Communication m_stdio_communication;
   MainLoop::ReadHandleUP m_stdio_handle_up;
@@ -98,6 +105,10 @@
   std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
   uint32_t m_next_saved_registers_id = 1;
   bool m_handshake_completed = false;
+  bool m_thread_suffix_supported = false;
+  bool m_list_threads_in_stop_reply = false;
+
+  NativeProcessProtocol::Extension m_extensions_supported = {};
 
   PacketResult SendONotification(const char *buffer, uint32_t len);
 
@@ -119,6 +130,10 @@
 
   PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
 
+  PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
+
+  PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
+
   PacketResult Handle_C(StringExtractorGDBRemote &packet);
 
   PacketResult Handle_c(StringExtractorGDBRemote &packet);
@@ -167,15 +182,15 @@
 
   PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_jTraceStart(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jLLDBTraceSupported(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_jTraceRead(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jLLDBTraceStart(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_jTraceStop(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jLLDBTraceStop(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jLLDBTraceGetState(StringExtractorGDBRemote &packet);
 
-  PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jLLDBTraceGetBinaryData(StringExtractorGDBRemote &packet);
 
   PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
 
@@ -201,6 +216,10 @@
 
   PacketResult Handle_g(StringExtractorGDBRemote &packet);
 
+  PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet);
+
+  PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet);
+
   void SetCurrentThreadID(lldb::tid_t tid);
 
   lldb::tid_t GetCurrentThreadID() const;
@@ -219,6 +238,9 @@
 
   static std::string XMLEncodeAttributeValue(llvm::StringRef value);
 
+  virtual std::vector<std::string> HandleFeatures(
+      const llvm::ArrayRef<llvm::StringRef> client_features) override;
+
 private:
   llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> BuildTargetXml();
 
@@ -244,6 +266,18 @@
 
   void StopSTDIOForwarding();
 
+  // Read thread-id from packet.  If the thread-id is correct, returns it.
+  // Otherwise, returns the error.
+  //
+  // If allow_all is true, then the pid/tid value of -1 ('all') will be allowed.
+  // In any case, the function assumes that exactly one inferior is being
+  // debugged and rejects pid values that do no match that inferior.
+  llvm::Expected<lldb::tid_t> ReadTid(StringExtractorGDBRemote &packet,
+                                      bool allow_all, lldb::pid_t default_pid);
+
+  // Call SetEnabledExtensions() with appropriate flags on the process.
+  void SetEnabledExtensions(NativeProcessProtocol &process);
+
   // For GDBRemoteCommunicationServerLLGS only
   GDBRemoteCommunicationServerLLGS(const GDBRemoteCommunicationServerLLGS &) =
       delete;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 3462fb7..7c2f80d 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -8,7 +8,7 @@
 
 #include "GDBRemoteCommunicationServerPlatform.h"
 
-#include <errno.h>
+#include <cerrno>
 
 #include <chrono>
 #include <csignal>
@@ -153,7 +153,8 @@
 }
 
 // Destructor
-GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
+GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() =
+    default;
 
 Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
     const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 1000661..65cf9fb 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -36,7 +36,7 @@
     : RegisterContext(thread, concrete_frame_idx),
       m_reg_info_sp(std::move(reg_info_sp)), m_reg_valid(), m_reg_data(),
       m_read_all_at_once(read_all_at_once),
-      m_write_all_at_once(write_all_at_once) {
+      m_write_all_at_once(write_all_at_once), m_gpacket_cached(false) {
   // Resize our vector of bools to contain one bool for every register. We will
   // use these boolean values to know when a register value is valid in
   // m_reg_data.
@@ -50,13 +50,14 @@
 }
 
 // Destructor
-GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
+GDBRemoteRegisterContext::~GDBRemoteRegisterContext() = default;
 
 void GDBRemoteRegisterContext::InvalidateAllRegisters() {
   SetAllRegisterValid(false);
 }
 
 void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
+  m_gpacket_cached = b;
   std::vector<bool>::iterator pos, end = m_reg_valid.end();
   for (pos = m_reg_valid.begin(); pos != end; ++pos)
     *pos = b;
@@ -200,7 +201,7 @@
   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
 
   if (!GetRegisterIsValid(reg)) {
-    if (m_read_all_at_once) {
+    if (m_read_all_at_once && !m_gpacket_cached) {
       if (DataBufferSP buffer_sp =
               gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
         memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
@@ -221,7 +222,10 @@
               m_reg_valid[i] = false;
             }
           }
-          return true;
+
+          m_gpacket_cached = true;
+          if (GetRegisterIsValid(reg))
+            return true;
         } else {
           Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
                                                                 GDBR_LOG_PACKETS));
@@ -233,9 +237,9 @@
               " bytes "
               "but only got %" PRId64 " bytes.",
               m_reg_data.GetByteSize(), buffer_sp->GetByteSize());
+          return false;
         }
       }
-      return false;
     }
     if (reg_info->value_regs) {
       // Process this composite register request by delegating to the
@@ -249,7 +253,8 @@
           break;
         // We have a valid primordial register as our constituent. Grab the
         // corresponding register info.
-        const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+        const RegisterInfo *prim_reg_info =
+            GetRegisterInfo(eRegisterKindProcessPlugin, prim_reg);
         if (prim_reg_info == nullptr)
           success = false;
         else {
@@ -359,7 +364,7 @@
                                reg_info->byte_size,        // dst length
                                m_reg_data.GetByteOrder())) // dst byte order
   {
-    GDBRemoteClientBase::Lock lock(gdb_comm, false);
+    GDBRemoteClientBase::Lock lock(gdb_comm);
     if (lock) {
       if (m_write_all_at_once) {
         // Invalidate all register values
@@ -395,7 +400,8 @@
               break;
             // We have a valid primordial register as our constituent. Grab the
             // corresponding register info.
-            const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+            const RegisterInfo *value_reg_info =
+                GetRegisterInfo(eRegisterKindProcessPlugin, reg);
             if (value_reg_info == nullptr)
               success = false;
             else
@@ -414,9 +420,10 @@
         if (reg_info->invalidate_regs) {
           for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
                reg != LLDB_INVALID_REGNUM;
-               reg = reg_info->invalidate_regs[++idx]) {
-            SetRegisterIsValid(reg, false);
-          }
+               reg = reg_info->invalidate_regs[++idx])
+            SetRegisterIsValid(ConvertRegisterKindToRegisterNumber(
+                                   eRegisterKindProcessPlugin, reg),
+                               false);
         }
 
         return success;
@@ -501,7 +508,7 @@
   const bool use_g_packet =
       !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
 
-  GDBRemoteClientBase::Lock lock(gdb_comm, false);
+  GDBRemoteClientBase::Lock lock(gdb_comm);
   if (lock) {
     if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
       InvalidateAllRegisters();
@@ -567,7 +574,7 @@
   const bool use_g_packet =
       !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
 
-  GDBRemoteClientBase::Lock lock(gdb_comm, false);
+  GDBRemoteClientBase::Lock lock(gdb_comm);
   if (lock) {
     // The data_sp contains the G response packet.
     if (use_g_packet) {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 252d7b3..18fcb73 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -118,6 +118,7 @@
   DataExtractor m_reg_data;
   bool m_read_all_at_once;
   bool m_write_all_at_once;
+  bool m_gpacket_cached;
 
 private:
   // Helper function for ReadRegisterBytes().
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index aba870c..6914b37 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -8,8 +8,8 @@
 
 #include "lldb/Host/Config.h"
 
-#include <errno.h>
-#include <stdlib.h>
+#include <cerrno>
+#include <cstdlib>
 #if LLDB_ENABLE_POSIX
 #include <netinet/in.h>
 #include <sys/mman.h>
@@ -20,8 +20,8 @@
 #if defined(__APPLE__)
 #include <sys/sysctl.h>
 #endif
+#include <ctime>
 #include <sys/types.h>
-#include <time.h>
 
 #include <algorithm>
 #include <csignal>
@@ -135,7 +135,7 @@
     m_collection_sp->Initialize(g_processgdbremote_properties);
   }
 
-  ~PluginProperties() override {}
+  ~PluginProperties() override = default;
 
   uint64_t GetPacketTimeout() {
     const uint32_t idx = ePropertyPacketTimeout;
@@ -213,6 +213,10 @@
   return process_sp;
 }
 
+std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() {
+  return std::chrono::seconds(GetGlobalPluginProperties()->GetPacketTimeout());
+}
+
 bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
                                 bool plugin_specified_by_name) {
   if (plugin_specified_by_name)
@@ -461,7 +465,7 @@
     assert(packet_len < (int)sizeof(packet));
     UNUSED_IF_ASSERT_DISABLED(packet_len);
     StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, false) ==
+    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response) ==
         GDBRemoteCommunication::PacketResult::Success) {
       response_type = response.GetResponseType();
       if (response_type == StringExtractorGDBRemote::eResponse) {
@@ -1011,7 +1015,7 @@
   for (size_t idx = 0; idx < num_cmds; idx++) {
     StringExtractorGDBRemote response;
     m_gdb_comm.SendPacketAndWaitForResponse(
-        GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+        GetExtraStartupCommands().GetArgumentAtIndex(idx), response);
   }
   return error;
 }
@@ -1038,6 +1042,12 @@
              process_arch.GetTriple().getTriple());
   }
 
+  if (int addresssable_bits = m_gdb_comm.GetAddressingBits()) {
+    lldb::addr_t address_mask = ~((1ULL << addresssable_bits) - 1);
+    SetCodeAddressMask(address_mask);
+    SetDataAddressMask(address_mask);
+  }
+
   if (process_arch.IsValid()) {
     const ArchSpec &target_arch = GetTarget().GetArchitecture();
     if (target_arch.IsValid()) {
@@ -1199,34 +1209,26 @@
   return error;
 }
 
-lldb::user_id_t ProcessGDBRemote::StartTrace(const TraceOptions &options,
-                                             Status &error) {
-  return m_gdb_comm.SendStartTracePacket(options, error);
+llvm::Expected<TraceSupportedResponse> ProcessGDBRemote::TraceSupported() {
+  return m_gdb_comm.SendTraceSupported(GetInterruptTimeout());
 }
 
-Status ProcessGDBRemote::StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
-  return m_gdb_comm.SendStopTracePacket(uid, thread_id);
+llvm::Error ProcessGDBRemote::TraceStop(const TraceStopRequest &request) {
+  return m_gdb_comm.SendTraceStop(request, GetInterruptTimeout());
 }
 
-Status ProcessGDBRemote::GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
-                                 llvm::MutableArrayRef<uint8_t> &buffer,
-                                 size_t offset) {
-  return m_gdb_comm.SendGetDataPacket(uid, thread_id, buffer, offset);
+llvm::Error ProcessGDBRemote::TraceStart(const llvm::json::Value &request) {
+  return m_gdb_comm.SendTraceStart(request, GetInterruptTimeout());
 }
 
-Status ProcessGDBRemote::GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
-                                     llvm::MutableArrayRef<uint8_t> &buffer,
-                                     size_t offset) {
-  return m_gdb_comm.SendGetMetaDataPacket(uid, thread_id, buffer, offset);
+llvm::Expected<std::string>
+ProcessGDBRemote::TraceGetState(llvm::StringRef type) {
+  return m_gdb_comm.SendTraceGetState(type, GetInterruptTimeout());
 }
 
-Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
-                                        TraceOptions &options) {
-  return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
-}
-
-llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() {
-  return m_gdb_comm.SendGetSupportedTraceType();
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
+  return m_gdb_comm.SendTraceGetBinaryData(request, GetInterruptTimeout());
 }
 
 void ProcessGDBRemote::DidExit() {
@@ -1471,7 +1473,7 @@
   while (true) {
     // Send vStopped
     StringExtractorGDBRemote response;
-    m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+    m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response);
 
     // OK represents end of signal list
     if (response.IsOKResponse())
@@ -1491,22 +1493,22 @@
   m_thread_pcs.clear();
 }
 
-size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(
+    llvm::StringRef value) {
   m_thread_ids.clear();
-  size_t comma_pos;
-  lldb::tid_t tid;
-  while ((comma_pos = value.find(',')) != std::string::npos) {
-    value[comma_pos] = '\0';
-    // thread in big endian hex
-    tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
-    if (tid != LLDB_INVALID_THREAD_ID)
-      m_thread_ids.push_back(tid);
-    value.erase(0, comma_pos + 1);
-  }
-  tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
-  if (tid != LLDB_INVALID_THREAD_ID)
-    m_thread_ids.push_back(tid);
+  lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+  StringExtractorGDBRemote thread_ids{value};
+
+  do {
+    auto pid_tid = thread_ids.GetPidTid(pid);
+    if (pid_tid && pid_tid->first == pid) {
+      lldb::tid_t tid = pid_tid->second;
+      if (tid != LLDB_INVALID_THREAD_ID &&
+          tid != StringExtractorGDBRemote::AllProcesses)
+        m_thread_ids.push_back(tid);
+    }
+  } while (thread_ids.GetChar() == ',');
+
   return m_thread_ids.size();
 }
 
@@ -1523,7 +1525,7 @@
     value.erase(0, comma_pos + 1);
   }
   pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
-  if (pc != LLDB_INVALID_THREAD_ID)
+  if (pc != LLDB_INVALID_ADDRESS)
     m_thread_pcs.push_back(pc);
   return m_thread_pcs.size();
 }
@@ -1748,7 +1750,9 @@
     if (thread_sp) {
       ThreadGDBRemote *gdb_thread =
           static_cast<ThreadGDBRemote *>(thread_sp.get());
-      gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+      RegisterContextSP gdb_reg_ctx_sp(gdb_thread->GetRegisterContext());
+
+      gdb_reg_ctx_sp->InvalidateIfNeeded(true);
 
       auto iter = std::find(m_thread_ids.begin(), m_thread_ids.end(), tid);
       if (iter != m_thread_ids.end()) {
@@ -1760,7 +1764,10 @@
         DataBufferSP buffer_sp(new DataBufferHeap(
             reg_value_extractor.GetStringRef().size() / 2, 0));
         reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
-        gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+        uint32_t lldb_regnum =
+            gdb_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+                eRegisterKindProcessPlugin, pair.first);
+        gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());
       }
 
       // AArch64 SVE specific code below calls AArch64SVEReconfigure to update
@@ -1825,8 +1832,7 @@
               // If the current pc is a breakpoint site then the StopInfo
               // should be set to Breakpoint Otherwise, it will be set to
               // Trace.
-              if (bp_site_sp &&
-                  bp_site_sp->ValidForThisThread(thread_sp.get())) {
+              if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
                 thread_sp->SetStopInfo(
                     StopInfo::CreateStopReasonWithBreakpointSiteID(
                         *thread_sp, bp_site_sp->GetID()));
@@ -1846,7 +1852,7 @@
                 // breakpoint here, that will be taken care of when the thread
                 // resumes and notices that there's a breakpoint under the pc.
                 handled = true;
-                if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+                if (bp_site_sp->ValidForThisThread(*thread_sp)) {
                   thread_sp->SetStopInfo(
                       StopInfo::CreateStopReasonWithBreakpointSiteID(
                           *thread_sp, bp_site_sp->GetID()));
@@ -1897,6 +1903,9 @@
               thread_sp->SetStopInfo(
                   StopInfo::CreateStopReasonWithExec(*thread_sp));
               handled = true;
+            } else if (reason == "processor trace") {
+              thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace(
+                  *thread_sp, description.c_str()));
             }
           } else if (!signo) {
             addr_t pc = thread_sp->GetRegisterContext()->GetPC();
@@ -1909,7 +1918,7 @@
             // as such. This can happen when the thread is involuntarily
             // interrupted (e.g. due to stops on other threads) just as it is
             // about to execute the breakpoint instruction.
-            if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+            if (bp_site_sp && bp_site_sp->ValidForThisThread(*thread_sp)) {
               thread_sp->SetStopInfo(
                   StopInfo::CreateStopReasonWithBreakpointSiteID(
                       *thread_sp, bp_site_sp->GetID()));
@@ -1934,7 +1943,7 @@
                 // reason.  We don't need to worry about stepping over the
                 // breakpoint here, that will be taken care of when the thread
                 // resumes and notices that there's a breakpoint under the pc.
-                if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+                if (bp_site_sp->ValidForThisThread(*thread_sp)) {
                   if (m_breakpoint_pc_offset != 0)
                     thread_sp->GetRegisterContext()->SetPC(pc);
                   thread_sp->SetStopInfo(
@@ -2137,6 +2146,7 @@
 }
 
 StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+  lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
   stop_packet.SetFilePos(0);
   const char stop_type = stop_packet.GetChar();
   switch (stop_type) {
@@ -2151,14 +2161,12 @@
     if (stop_id == 0) {
       // Our first stop, make sure we have a process ID, and also make sure we
       // know about our registers
-      if (GetID() == LLDB_INVALID_PROCESS_ID) {
-        lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
-        if (pid != LLDB_INVALID_PROCESS_ID)
-          SetID(pid);
-      }
+      if (GetID() == LLDB_INVALID_PROCESS_ID && pid != LLDB_INVALID_PROCESS_ID)
+        SetID(pid);
       BuildDynamicRegisterInfo(true);
     }
     // Stop with signal and thread info
+    lldb::pid_t stop_pid = LLDB_INVALID_PROCESS_ID;
     lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
     const uint8_t signo = stop_packet.GetHexU8();
     llvm::StringRef key;
@@ -2187,24 +2195,18 @@
         value.getAsInteger(16, x);
         exc_data.push_back(x);
       } else if (key.compare("thread") == 0) {
-        // thread in big endian hex
-        if (value.getAsInteger(16, tid))
+        // thread-id
+        StringExtractorGDBRemote thread_id{value};
+        auto pid_tid = thread_id.GetPidTid(pid);
+        if (pid_tid) {
+          stop_pid = pid_tid->first;
+          tid = pid_tid->second;
+        } else
           tid = LLDB_INVALID_THREAD_ID;
       } else if (key.compare("threads") == 0) {
         std::lock_guard<std::recursive_mutex> guard(
             m_thread_list_real.GetMutex());
-
-        m_thread_ids.clear();
-        // A comma separated list of all threads in the current
-        // process that includes the thread for this stop reply packet
-        lldb::tid_t tid;
-        while (!value.empty()) {
-          llvm::StringRef tid_str;
-          std::tie(tid_str, value) = value.split(',');
-          if (tid_str.getAsInteger(16, tid))
-            tid = LLDB_INVALID_THREAD_ID;
-          m_thread_ids.push_back(tid);
-        }
+        UpdateThreadIDsFromStopReplyThreadsValue(value);
       } else if (key.compare("thread-pcs") == 0) {
         m_thread_pcs.clear();
         // A comma separated list of all threads in the current
@@ -2317,6 +2319,14 @@
       }
     }
 
+    if (stop_pid != LLDB_INVALID_PROCESS_ID && stop_pid != pid) {
+      Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+      LLDB_LOG(log,
+               "Received stop for incorrect PID = {0} (inferior PID = {1})",
+               stop_pid, pid);
+      return eStateInvalid;
+    }
+
     if (tid == LLDB_INVALID_THREAD_ID) {
       // A thread id may be invalid if the response is old style 'S' packet
       // which does not provide the
@@ -2404,7 +2414,7 @@
     // file handle and debugserver will go away, and we can be done...
     m_gdb_comm.Disconnect();
   } else
-    caused_stop = m_gdb_comm.Interrupt();
+    caused_stop = m_gdb_comm.Interrupt(GetInterruptTimeout());
   return error;
 }
 
@@ -2553,11 +2563,11 @@
   if (m_gdb_comm.IsConnected()) {
     if (m_public_state.GetValue() != eStateAttaching) {
       StringExtractorGDBRemote response;
-      bool send_async = true;
       GDBRemoteCommunication::ScopedTimeout(m_gdb_comm,
                                             std::chrono::seconds(3));
 
-      if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, send_async) ==
+      if (m_gdb_comm.SendPacketAndWaitForResponse("k", response,
+                                                  GetInterruptTimeout()) ==
           GDBRemoteCommunication::PacketResult::Success) {
         char packet_cmd = response.GetChar(0);
 
@@ -2721,7 +2731,8 @@
   assert(packet_len + 1 < (int)sizeof(packet));
   UNUSED_IF_ASSERT_DISABLED(packet_len);
   StringExtractorGDBRemote response;
-  if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response, true) ==
+  if (m_gdb_comm.SendPacketAndWaitForResponse(packet, response,
+                                              GetInterruptTimeout()) ==
       GDBRemoteCommunication::PacketResult::Success) {
     if (response.IsNormalResponse()) {
       error.Clear();
@@ -2757,6 +2768,37 @@
   return 0;
 }
 
+bool ProcessGDBRemote::SupportsMemoryTagging() {
+  return m_gdb_comm.GetMemoryTaggingSupported();
+}
+
+llvm::Expected<std::vector<uint8_t>>
+ProcessGDBRemote::DoReadMemoryTags(lldb::addr_t addr, size_t len,
+                                   int32_t type) {
+  // By this point ReadMemoryTags has validated that tagging is enabled
+  // for this target/process/address.
+  DataBufferSP buffer_sp = m_gdb_comm.ReadMemoryTags(addr, len, type);
+  if (!buffer_sp) {
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "Error reading memory tags from remote");
+  }
+
+  // Return the raw tag data
+  llvm::ArrayRef<uint8_t> tag_data = buffer_sp->GetData();
+  std::vector<uint8_t> got;
+  got.reserve(tag_data.size());
+  std::copy(tag_data.begin(), tag_data.end(), std::back_inserter(got));
+  return got;
+}
+
+Status ProcessGDBRemote::DoWriteMemoryTags(lldb::addr_t addr, size_t len,
+                                           int32_t type,
+                                           const std::vector<uint8_t> &tags) {
+  // By now WriteMemoryTags should have validated that tagging is enabled
+  // for this target/process.
+  return m_gdb_comm.WriteMemoryTags(addr, len, type, tags);
+}
+
 Status ProcessGDBRemote::WriteObjectFile(
     std::vector<ObjectFile::LoadableData> entries) {
   Status error;
@@ -2847,7 +2889,7 @@
 
   StringExtractorGDBRemote response;
   if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                              true) ==
+                                              GetInterruptTimeout()) ==
       GDBRemoteCommunication::PacketResult::Success) {
     if (response.IsOKResponse()) {
       m_erased_flash_ranges.Insert(range, true);
@@ -2876,7 +2918,8 @@
   if (m_erased_flash_ranges.IsEmpty())
     return status;
   StringExtractorGDBRemote response;
-  if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response, true) ==
+  if (m_gdb_comm.SendPacketAndWaitForResponse("vFlashDone", response,
+                                              GetInterruptTimeout()) ==
       GDBRemoteCommunication::PacketResult::Success) {
     if (response.IsOKResponse()) {
       m_erased_flash_ranges.Clear();
@@ -2937,7 +2980,7 @@
   }
   StringExtractorGDBRemote response;
   if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                              true) ==
+                                              GetInterruptTimeout()) ==
       GDBRemoteCommunication::PacketResult::Success) {
     if (response.IsOKResponse()) {
       error.Clear();
@@ -3113,7 +3156,7 @@
       (!bp_site->HardwareRequired())) {
     // Try to send off a software breakpoint packet ($Z0)
     uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
-        eBreakpointSoftware, true, addr, bp_op_size);
+        eBreakpointSoftware, true, addr, bp_op_size, GetInterruptTimeout());
     if (error_no == 0) {
       // The breakpoint was placed successfully
       bp_site->SetEnabled(true);
@@ -3153,7 +3196,7 @@
   if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
     // Try to send off a hardware breakpoint packet ($Z1)
     uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
-        eBreakpointHardware, true, addr, bp_op_size);
+        eBreakpointHardware, true, addr, bp_op_size, GetInterruptTimeout());
     if (error_no == 0) {
       // The breakpoint was placed successfully
       bp_site->SetEnabled(true);
@@ -3217,13 +3260,15 @@
 
     case BreakpointSite::eHardware:
       if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
-                                                addr, bp_op_size))
+                                                addr, bp_op_size,
+                                                GetInterruptTimeout()))
         error.SetErrorToGenericError();
       break;
 
     case BreakpointSite::eExternal: {
       if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false,
-                                                addr, bp_op_size))
+                                                addr, bp_op_size,
+                                                GetInterruptTimeout()))
         error.SetErrorToGenericError();
     } break;
     }
@@ -3279,7 +3324,8 @@
     // Pass down an appropriate z/Z packet...
     if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
       if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
-                                                wp->GetByteSize()) == 0) {
+                                                wp->GetByteSize(),
+                                                GetInterruptTimeout()) == 0) {
         wp->SetEnabled(true, notify);
         return error;
       } else
@@ -3325,7 +3371,8 @@
       GDBStoppointType type = GetGDBStoppointType(wp);
       // Pass down an appropriate z/Z packet...
       if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
-                                                wp->GetByteSize()) == 0) {
+                                                wp->GetByteSize(),
+                                                GetInterruptTimeout()) == 0) {
         wp->SetEnabled(false, notify);
         return error;
       } else
@@ -3350,7 +3397,7 @@
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
   LLDB_LOGF(log, "ProcessGDBRemote::DoSignal (signal = %d)", signo);
 
-  if (!m_gdb_comm.SendAsyncSignal(signo))
+  if (!m_gdb_comm.SendAsyncSignal(signo, GetInterruptTimeout()))
     error.SetErrorStringWithFormat("failed to send signal %i", signo);
   return error;
 }
@@ -3678,12 +3725,25 @@
             __FUNCTION__, arg, process->GetID());
 
   EventSP event_sp;
+
+  // We need to ignore any packets that come in after we have
+  // have decided the process has exited.  There are some
+  // situations, for instance when we try to interrupt a running
+  // process and the interrupt fails, where another packet might
+  // get delivered after we've decided to give up on the process.
+  // But once we've decided we are done with the process we will
+  // not be in a state to do anything useful with new packets.
+  // So it is safer to simply ignore any remaining packets by
+  // explicitly checking for eStateExited before reentering the
+  // fetch loop.
+  
   bool done = false;
-  while (!done) {
+  while (!done && process->GetPrivateState() != eStateExited) {
     LLDB_LOGF(log,
               "ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
               ") listener.WaitForEvent (NULL, event_sp)...",
               __FUNCTION__, arg, process->GetID());
+
     if (process->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
       const uint32_t event_type = event_sp->GetType();
       if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
@@ -3715,7 +3775,7 @@
               // send the vCont packet
               if (!process->GetGDBRemote().SendvContPacket(
                       llvm::StringRef(continue_cstr, continue_cstr_len),
-                      response)) {
+                      process->GetInterruptTimeout(), response)) {
                 // Something went wrong
                 done = true;
                 break;
@@ -3727,6 +3787,7 @@
                   process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
                       *process, *process->GetUnixSignals(),
                       llvm::StringRef(continue_cstr, continue_cstr_len),
+                      process->GetInterruptTimeout(),
                       response);
 
               // We need to immediately clear the thread ID list so we are sure
@@ -3782,6 +3843,7 @@
                 } else {
                   process->SetExitStatus(-1, "lost connection");
                 }
+                done = true;
                 break;
               }
 
@@ -4020,8 +4082,7 @@
 
     StringExtractorGDBRemote response;
     response.SetResponseValidatorToJSON();
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                                false) ==
+    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
         GDBRemoteCommunication::PacketResult::Success) {
       StringExtractorGDBRemote::ResponseType response_type =
           response.GetResponseType();
@@ -4093,8 +4154,7 @@
 
     StringExtractorGDBRemote response;
     response.SetResponseValidatorToJSON();
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                                false) ==
+    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
         GDBRemoteCommunication::PacketResult::Success) {
       StringExtractorGDBRemote::ResponseType response_type =
           response.GetResponseType();
@@ -4127,8 +4187,7 @@
 
     StringExtractorGDBRemote response;
     response.SetResponseValidatorToJSON();
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                                false) ==
+    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) ==
         GDBRemoteCommunication::PacketResult::Success) {
       StringExtractorGDBRemote::ResponseType response_type =
           response.GetResponseType();
@@ -4894,8 +4953,7 @@
   packet.PutStringAsRawHex8(file_path);
 
   StringExtractorGDBRemote response;
-  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response,
-                                              false) !=
+  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) !=
       GDBRemoteCommunication::PacketResult::Success)
     return Status("Sending qFileLoadAddress packet failed");
 
@@ -5131,7 +5189,7 @@
     m_option_group.Finalize();
   }
 
-  ~CommandObjectProcessGDBRemoteSpeedTest() override {}
+  ~CommandObjectProcessGDBRemoteSpeedTest() override = default;
 
   Options *GetOptions() override { return &m_option_group; }
 
@@ -5182,7 +5240,7 @@
       : CommandObjectParsed(interpreter, "process plugin packet history",
                             "Dumps the packet history buffer. ", nullptr) {}
 
-  ~CommandObjectProcessGDBRemotePacketHistory() override {}
+  ~CommandObjectProcessGDBRemotePacketHistory() override = default;
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     const size_t argc = command.GetArgumentCount();
@@ -5213,7 +5271,7 @@
             "Maximum size that lldb will try to read/write one one chunk.",
             nullptr) {}
 
-  ~CommandObjectProcessGDBRemotePacketXferSize() override {}
+  ~CommandObjectProcessGDBRemotePacketXferSize() override = default;
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     const size_t argc = command.GetArgumentCount();
@@ -5222,7 +5280,6 @@
                                    "amount to be transferred when "
                                    "reading/writing",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -5255,7 +5312,7 @@
                             "stripped from the result.",
                             nullptr) {}
 
-  ~CommandObjectProcessGDBRemotePacketSend() override {}
+  ~CommandObjectProcessGDBRemotePacketSend() override = default;
 
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     const size_t argc = command.GetArgumentCount();
@@ -5263,7 +5320,6 @@
       result.AppendErrorWithFormat(
           "'%s' takes a one or more packet content arguments",
           m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -5272,10 +5328,9 @@
     if (process) {
       for (size_t i = 0; i < argc; ++i) {
         const char *packet_cstr = command.GetArgumentAtIndex(0);
-        bool send_async = true;
         StringExtractorGDBRemote response;
         process->GetGDBRemote().SendPacketAndWaitForResponse(
-            packet_cstr, response, send_async);
+            packet_cstr, response, process->GetInterruptTimeout());
         result.SetStatus(eReturnStatusSuccessFinishResult);
         Stream &output_strm = result.GetOutputStream();
         output_strm.Printf("  packet: %s\n", packet_cstr);
@@ -5306,14 +5361,13 @@
                          "encoded into a valid 'qRcmd' packet, sent and the "
                          "response will be printed.") {}
 
-  ~CommandObjectProcessGDBRemotePacketMonitor() override {}
+  ~CommandObjectProcessGDBRemotePacketMonitor() override = default;
 
   bool DoExecute(llvm::StringRef command,
                  CommandReturnObject &result) override {
     if (command.empty()) {
       result.AppendErrorWithFormat("'%s' takes a command string argument",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
 
@@ -5324,11 +5378,10 @@
       packet.PutCString("qRcmd,");
       packet.PutBytesAsRawHex8(command.data(), command.size());
 
-      bool send_async = true;
       StringExtractorGDBRemote response;
       Stream &output_strm = result.GetOutputStream();
       process->GetGDBRemote().SendPacketAndReceiveResponseWithOutputSupport(
-          packet.GetString(), response, send_async,
+          packet.GetString(), response, process->GetInterruptTimeout(),
           [&output_strm](llvm::StringRef output) { output_strm << output; });
       result.SetStatus(eReturnStatusSuccessFinishResult);
       output_strm.Printf("  packet: %s\n", packet.GetData());
@@ -5370,7 +5423,7 @@
                        interpreter)));
   }
 
-  ~CommandObjectProcessGDBRemotePacket() override {}
+  ~CommandObjectProcessGDBRemotePacket() override = default;
 };
 
 class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
@@ -5385,7 +5438,7 @@
         CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
   }
 
-  ~CommandObjectMultiwordProcessGDBRemote() override {}
+  ~CommandObjectMultiwordProcessGDBRemote() override = default;
 };
 
 CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 0921bf1..fe04cdd 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/src/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -68,6 +68,8 @@
 
   static const char *GetPluginDescriptionStatic();
 
+  static std::chrono::seconds GetPacketTimeout();
+
   // Check if a given Process
   bool CanDebug(lldb::TargetSP target_sp,
                 bool plugin_specified_by_name) override;
@@ -163,22 +165,16 @@
 
   Status GetWatchpointSupportInfo(uint32_t &num) override;
 
-  lldb::user_id_t StartTrace(const TraceOptions &options,
-                             Status &error) override;
+  llvm::Expected<TraceSupportedResponse> TraceSupported() override;
 
-  Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) override;
+  llvm::Error TraceStop(const TraceStopRequest &request) override;
 
-  Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
-                 llvm::MutableArrayRef<uint8_t> &buffer,
-                 size_t offset = 0) override;
+  llvm::Error TraceStart(const llvm::json::Value &request) override;
 
-  Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
-                     llvm::MutableArrayRef<uint8_t> &buffer,
-                     size_t offset = 0) override;
+  llvm::Expected<std::string> TraceGetState(llvm::StringRef type) override;
 
-  llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override;
-
-  Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override;
+  llvm::Expected<std::vector<uint8_t>>
+  TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
 
   Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
 
@@ -239,6 +235,8 @@
   friend class GDBRemoteCommunicationClient;
   friend class GDBRemoteRegisterContext;
 
+  bool SupportsMemoryTagging() override;
+
   /// Broadcaster event bits definitions.
   enum {
     eBroadcastBitAsyncContinue = (1 << 0),
@@ -339,7 +337,7 @@
 
   size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value);
 
-  size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value);
+  size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value);
 
   bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
 
@@ -410,6 +408,12 @@
 
   bool HasErased(FlashRange range);
 
+  llvm::Expected<std::vector<uint8_t>>
+  DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) override;
+
+  Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
+                           const std::vector<uint8_t> &tags) override;
+
 private:
   // For ProcessGDBRemote only
   std::string m_partial_profile_data;
diff --git a/src/llvm-project/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/src/llvm-project/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 0f77110..84548ed 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <errno.h>
-#include <stdlib.h>
+#include <cerrno>
+#include <cstdlib>
 
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Threading.h"
@@ -21,6 +21,7 @@
 #include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Utility/DataBuffer.h"
@@ -36,6 +37,7 @@
 
 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 
 #include <memory>
@@ -188,6 +190,59 @@
   return false;
 }
 
+// We have a hint about a binary -- a UUID, possibly a load address.
+// Try to load a file with that UUID into lldb, and if we have a load
+// address, set it correctly.  Else assume that the binary was loaded
+// with no slide.
+static bool load_standalone_binary(UUID uuid, addr_t addr, Target &target) {
+  if (uuid.IsValid()) {
+    ModuleSpec module_spec;
+    module_spec.GetUUID() = uuid;
+
+    // Look up UUID in global module cache before attempting
+    // dsymForUUID-like action.
+    ModuleSP module_sp;
+    Status error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
+                                               nullptr, nullptr);
+
+    if (!module_sp.get()) {
+      // Force a a dsymForUUID lookup, if that tool is available.
+      if (!module_spec.GetSymbolFileSpec())
+        Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+      if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+        module_sp = std::make_shared<Module>(module_spec);
+      }
+    }
+
+    if (module_sp.get() && module_sp->GetObjectFile()) {
+      target.SetArchitecture(module_sp->GetObjectFile()->GetArchitecture());
+      target.GetImages().AppendIfNeeded(module_sp, false);
+
+      Address base_addr = module_sp->GetObjectFile()->GetBaseAddress();
+      addr_t slide = 0;
+      if (addr != LLDB_INVALID_ADDRESS && base_addr.IsValid()) {
+        addr_t file_load_addr = base_addr.GetFileAddress();
+        slide = addr - file_load_addr;
+      }
+      bool changed = false;
+      module_sp->SetLoadAddress(target, slide, true, changed);
+
+      ModuleList added_module;
+      added_module.Append(module_sp, false);
+      target.ModulesDidLoad(added_module);
+
+      // Flush info in the process (stack frames, etc).
+      ProcessSP process_sp(target.GetProcessSP());
+      if (process_sp)
+        process_sp->Flush();
+
+      return true;
+    }
+  }
+  return false;
+}
+
 // Process Control
 Status ProcessMachCore::DoLoadCore() {
   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
@@ -277,7 +332,6 @@
     m_core_range_infos.Sort();
   }
 
-
   bool found_main_binary_definitively = false;
 
   addr_t objfile_binary_addr;
@@ -285,124 +339,86 @@
   ObjectFile::BinaryType type;
   if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_addr,
                                               objfile_binary_uuid, type)) {
-    if (objfile_binary_addr != LLDB_INVALID_ADDRESS)
-    {
-        m_mach_kernel_addr = objfile_binary_addr;
+    if (log) {
+      log->Printf(
+          "ProcessMachCore::DoLoadCore: using binary hint from 'main bin spec' "
+          "LC_NOTE with UUID %s address 0x%" PRIx64 " and type %d",
+          objfile_binary_uuid.GetAsString().c_str(), objfile_binary_addr, type);
+    }
+    if (objfile_binary_addr != LLDB_INVALID_ADDRESS) {
+      if (type == ObjectFile::eBinaryTypeUser) {
+        m_dyld_addr = objfile_binary_addr;
+        m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
         found_main_binary_definitively = true;
-        LLDB_LOGF(log,
-                  "ProcessMachCore::DoLoadCore: using kernel address 0x%" PRIx64
-                  " from LC_NOTE 'main bin spec' load command.",
-                  m_mach_kernel_addr);
+      }
+      if (type == ObjectFile::eBinaryTypeKernel) {
+        m_mach_kernel_addr = objfile_binary_addr;
+        m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+        found_main_binary_definitively = true;
+      }
+    }
+    if (!found_main_binary_definitively) {
+      // ObjectFile::eBinaryTypeStandalone, undeclared types
+      if (load_standalone_binary(objfile_binary_uuid, objfile_binary_addr,
+                                 GetTarget())) {
+        found_main_binary_definitively = true;
+        m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
+      }
     }
   }
 
   // This checks for the presence of an LC_IDENT string in a core file;
   // LC_IDENT is very obsolete and should not be used in new code, but if the
   // load command is present, let's use the contents.
-  std::string corefile_identifier = core_objfile->GetIdentifierString();
-  if (!found_main_binary_definitively &&
-      corefile_identifier.find("Darwin Kernel") != std::string::npos) {
-    UUID uuid;
-    addr_t addr = LLDB_INVALID_ADDRESS;
+  UUID ident_uuid;
+  addr_t ident_binary_addr = LLDB_INVALID_ADDRESS;
+  if (!found_main_binary_definitively) {
+    std::string corefile_identifier = core_objfile->GetIdentifierString();
+
+    // Search for UUID= and stext= strings in the identifier str.
     if (corefile_identifier.find("UUID=") != std::string::npos) {
       size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
       std::string uuid_str = corefile_identifier.substr(p, 36);
-      uuid.SetFromStringRef(uuid_str);
+      ident_uuid.SetFromStringRef(uuid_str);
+      if (log)
+        log->Printf("Got a UUID from LC_IDENT/kern ver str LC_NOTE: %s",
+                    ident_uuid.GetAsString().c_str());
     }
     if (corefile_identifier.find("stext=") != std::string::npos) {
       size_t p = corefile_identifier.find("stext=") + strlen("stext=");
       if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
-        errno = 0;
-        addr = ::strtoul(corefile_identifier.c_str() + p, nullptr, 16);
-        if (errno != 0 || addr == 0)
-          addr = LLDB_INVALID_ADDRESS;
+        ident_binary_addr =
+            ::strtoul(corefile_identifier.c_str() + p, nullptr, 16);
+        if (log)
+          log->Printf("Got a load address from LC_IDENT/kern ver str "
+                      "LC_NOTE: 0x%" PRIx64,
+                      ident_binary_addr);
       }
     }
-    if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
-      m_mach_kernel_addr = addr;
+
+    // Search for a "Darwin Kernel" str indicating kernel; else treat as
+    // standalone
+    if (corefile_identifier.find("Darwin Kernel") != std::string::npos &&
+        ident_uuid.IsValid() && ident_binary_addr != LLDB_INVALID_ADDRESS) {
+      if (log)
+        log->Printf("ProcessMachCore::DoLoadCore: Found kernel binary via "
+                    "LC_IDENT/kern ver str LC_NOTE");
+      m_mach_kernel_addr = ident_binary_addr;
       found_main_binary_definitively = true;
-      LLDB_LOGF(
-          log,
-          "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
-          " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
-          addr, corefile_identifier.c_str());
+    } else if (ident_uuid.IsValid()) {
+      if (load_standalone_binary(ident_uuid, ident_binary_addr, GetTarget())) {
+        found_main_binary_definitively = true;
+        m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
+      }
     }
   }
 
-  // In the case where we have an LC_NOTE specifying a standalone
-  // binary with only a UUID (and no load address) (iBoot, EFI, etc),
-  // then let's try to force a load of the binary and set its
-  // load address to 0-offset.
-  //
-  // The two forms this can come in is either a
-  //   'kern ver str' LC_NOTE with "EFI UUID=...."
-  //   'main bin spec' LC_NOTE with UUID and no load address.
-
+  // If we have a "all image infos" LC_NOTE, try to load all of the
+  // binaries listed, and set their Section load addresses in the Target.
   if (found_main_binary_definitively == false &&
-      (corefile_identifier.find("EFI ") != std::string::npos ||
-       (objfile_binary_uuid.IsValid() &&
-        objfile_binary_addr == LLDB_INVALID_ADDRESS))) {
-    UUID uuid;
-    if (objfile_binary_uuid.IsValid()) {
-      uuid = objfile_binary_uuid;
-      LLDB_LOGF(log,
-                "ProcessMachCore::DoLoadCore: Using the main bin spec "
-                "LC_NOTE with UUID %s and no load address",
-                uuid.GetAsString().c_str());
-    } else {
-      if (corefile_identifier.find("UUID=") != std::string::npos) {
-        size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
-        std::string uuid_str = corefile_identifier.substr(p, 36);
-        uuid.SetFromStringRef(uuid_str);
-        if (uuid.IsValid()) {
-          LLDB_LOGF(log,
-                    "ProcessMachCore::DoLoadCore: Using the EFI "
-                    "from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
-                    corefile_identifier.c_str());
-        }
-      }
-    }
-
-    if (uuid.IsValid()) {
-      ModuleSpec module_spec;
-      module_spec.GetUUID() = uuid;
-      module_spec.GetArchitecture() = GetTarget().GetArchitecture();
-
-      // Lookup UUID locally, before attempting dsymForUUID-like action
-      FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
-      module_spec.GetSymbolFileSpec() =
-          Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
-      if (module_spec.GetSymbolFileSpec()) {
-        ModuleSpec executable_module_spec =
-            Symbols::LocateExecutableObjectFile(module_spec);
-        if (FileSystem::Instance().Exists(
-                executable_module_spec.GetFileSpec())) {
-          module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
-        }
-      }
-
-      // Force a a dsymForUUID lookup, if that tool is available.
-      if (!module_spec.GetSymbolFileSpec())
-        Symbols::DownloadObjectAndSymbolFile(module_spec, true);
-
-      // If we found a binary, load it at offset 0 and set our
-      // dyld_plugin to be the static plugin.
-      if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
-        ModuleSP module_sp(new Module(module_spec));
-        if (module_sp.get() && module_sp->GetObjectFile()) {
-          GetTarget().GetImages().AppendIfNeeded(module_sp, true);
-          GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo);
-          found_main_binary_definitively = true;
-          bool changed = true;
-          module_sp->SetLoadAddress(GetTarget(), 0, true, changed);
-          ModuleList added_module;
-          added_module.Append(module_sp, false);
-          GetTarget().ModulesDidLoad(added_module);
-          m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
-          found_main_binary_definitively = true;
-        }
-      }
-    }
+      core_objfile->LoadCoreFileImages(*this)) {
+    m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+    found_main_binary_definitively = true;
   }
 
   if (!found_main_binary_definitively &&
@@ -525,6 +541,11 @@
   if (arch.IsValid())
     GetTarget().SetArchitecture(arch);
 
+  addr_t address_mask = core_objfile->GetAddressMask();
+  if (address_mask != 0) {
+    SetCodeAddressMask(address_mask);
+    SetDataAddressMask(address_mask);
+  }
   return error;
 }
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/src/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 05a48ac..3855574 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -138,10 +138,10 @@
 ///
 /// \param[in] module_sp The module to grab the .text section from.
 ///
-/// \param[in/out] breakpad_uuid A vector that will receive the calculated
+/// \param[in,out] breakpad_uuid A vector that will receive the calculated
 ///                breakpad .text hash.
 ///
-/// \param[in/out] facebook_uuid A vector that will receive the calculated
+/// \param[in,out] facebook_uuid A vector that will receive the calculated
 ///                facebook .text hash.
 ///
 void HashElfTextSection(ModuleSP module_sp, std::vector<uint8_t> &breakpad_uuid,
@@ -548,7 +548,7 @@
 
     // check if the process is wow64 - a 32 bit windows process running on a
     // 64 bit windows
-    if (llvm::StringRef(name).endswith_lower("wow64.dll")) {
+    if (llvm::StringRef(name).endswith_insensitive("wow64.dll")) {
       m_is_wow64 = true;
     }
 
@@ -871,7 +871,7 @@
     m_option_group.Finalize();
   }
 
-  ~CommandObjectProcessMinidumpDump() override {}
+  ~CommandObjectProcessMinidumpDump() override = default;
 
   Options *GetOptions() override { return &m_option_group; }
 
@@ -880,7 +880,6 @@
     if (argc > 0) {
       result.AppendErrorWithFormat("'%s' take no arguments, only options",
                                    m_cmd_name.c_str());
-      result.SetStatus(eReturnStatusFailed);
       return false;
     }
     SetDefaultOptionsIfNoneAreSet();
@@ -1001,7 +1000,7 @@
         CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
   }
 
-  ~CommandObjectMultiwordProcessMinidump() override {}
+  ~CommandObjectMultiwordProcessMinidump() override = default;
 };
 
 CommandObject *ProcessMinidump::GetPluginCommandObject() {
diff --git a/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
index eb48785..7e309e8 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -16,7 +16,7 @@
 #include "lldb/lldb-enumerations.h"
 
 // C includes
-#include <assert.h>
+#include <cassert>
 
 // C++ includes
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
index c7809c5..e2b7c0e 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
@@ -14,7 +14,7 @@
 #include "lldb/lldb-enumerations.h"
 
 // C includes
-#include <assert.h>
+#include <cassert>
 
 // C++ includes
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/src/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
index e146a1a..1fbc528 100644
--- a/src/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -38,7 +38,7 @@
     : Thread(process, td.ThreadId), m_thread_reg_ctx_sp(),
       m_gpregset_data(gpregset_data) {}
 
-ThreadMinidump::~ThreadMinidump() {}
+ThreadMinidump::~ThreadMinidump() = default;
 
 void ThreadMinidump::RefreshStateAfterStop() {}
 
diff --git a/src/llvm-project/lldb/source/Plugins/Process/scripted/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Process/scripted/CMakeLists.txt
new file mode 100644
index 0000000..e2cfd05
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/scripted/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_lldb_library(lldbPluginScriptedProcess PLUGIN
+  ScriptedProcess.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+    lldbUtility
+    lldbPluginProcessUtility
+  LINK_COMPONENTS
+    BinaryFormat
+    Object
+    Support
+  )
diff --git a/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
new file mode 100644
index 0000000..09e9375
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -0,0 +1,313 @@
+//===-- ScriptedProcess.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 "ScriptedProcess.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupBoolean.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/RegisterContext.h"
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/Utility/State.h"
+
+#include <mutex>
+
+LLDB_PLUGIN_DEFINE(ScriptedProcess)
+
+using namespace lldb;
+using namespace lldb_private;
+
+ConstString ScriptedProcess::GetPluginNameStatic() {
+  static ConstString g_name("ScriptedProcess");
+  return g_name;
+}
+
+const char *ScriptedProcess::GetPluginDescriptionStatic() {
+  return "Scripted Process plug-in.";
+}
+
+static constexpr lldb::ScriptLanguage g_supported_script_languages[] = {
+    ScriptLanguage::eScriptLanguagePython,
+};
+
+bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) {
+  llvm::ArrayRef<lldb::ScriptLanguage> supported_languages =
+      llvm::makeArrayRef(g_supported_script_languages);
+
+  return llvm::is_contained(supported_languages, language);
+}
+
+void ScriptedProcess::CheckInterpreterAndScriptObject() const {
+  lldbassert(m_interpreter && "Invalid Script Interpreter.");
+  lldbassert(m_script_object_sp && "Invalid Script Object.");
+}
+
+lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
+                                                lldb::ListenerSP listener_sp,
+                                                const FileSpec *file,
+                                                bool can_connect) {
+  if (!target_sp ||
+      !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage()))
+    return nullptr;
+
+  Status error;
+  ScriptedProcess::ScriptedProcessInfo scripted_process_info(
+      target_sp->GetProcessLaunchInfo());
+
+  auto process_sp = std::make_shared<ScriptedProcess>(
+      target_sp, listener_sp, scripted_process_info, error);
+
+  if (error.Fail() || !process_sp || !process_sp->m_script_object_sp ||
+      !process_sp->m_script_object_sp->IsValid()) {
+    LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS), "%s",
+              error.AsCString());
+    return nullptr;
+  }
+
+  return process_sp;
+}
+
+bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
+                               bool plugin_specified_by_name) {
+  return true;
+}
+
+ScriptedProcess::ScriptedProcess(
+    lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+    const ScriptedProcess::ScriptedProcessInfo &scripted_process_info,
+    Status &error)
+    : Process(target_sp, listener_sp),
+      m_scripted_process_info(scripted_process_info) {
+
+  if (!target_sp) {
+    error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+                                   __FUNCTION__, "Invalid target");
+    return;
+  }
+
+  m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();
+
+  if (!m_interpreter) {
+    error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+                                   __FUNCTION__,
+                                   "Debugger has no Script Interpreter");
+    return;
+  }
+
+  StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject(
+      m_scripted_process_info.GetClassName().c_str(), target_sp,
+      m_scripted_process_info.GetDictionarySP());
+
+  if (!object_sp || !object_sp->IsValid()) {
+    error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s",
+                                   __FUNCTION__,
+                                   "Failed to create valid script object");
+    return;
+  }
+
+  m_script_object_sp = object_sp;
+}
+
+ScriptedProcess::~ScriptedProcess() {
+  Clear();
+  // We need to call finalize on the process before destroying ourselves to
+  // make sure all of the broadcaster cleanup goes as planned. If we destruct
+  // this class, then Process::~Process() might have problems trying to fully
+  // destroy the broadcaster.
+  Finalize();
+}
+
+void ScriptedProcess::Initialize() {
+  static llvm::once_flag g_once_flag;
+
+  llvm::call_once(g_once_flag, []() {
+    PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                  GetPluginDescriptionStatic(), CreateInstance);
+  });
+}
+
+void ScriptedProcess::Terminate() {
+  PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance);
+}
+
+ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t ScriptedProcess::GetPluginVersion() { return 1; }
+
+Status ScriptedProcess::DoLoadCore() {
+  ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();
+
+  return DoLaunch(nullptr, launch_info);
+}
+
+Status ScriptedProcess::DoLaunch(Module *exe_module,
+                                 ProcessLaunchInfo &launch_info) {
+  CheckInterpreterAndScriptObject();
+
+  /* FIXME: This doesn't reflect how lldb actually launches a process.
+           In reality, it attaches to debugserver, then resume the process. */
+  Status error = GetInterface().Launch();
+  SetPrivateState(eStateRunning);
+
+  if (error.Fail())
+    return error;
+
+  // TODO: Fetch next state from stopped event queue then send stop event
+  //  const StateType state = SetThreadStopInfo(response);
+  //  if (state != eStateInvalid) {
+  //    SetPrivateState(state);
+
+  SetPrivateState(eStateStopped);
+
+  UpdateThreadListIfNeeded();
+  GetThreadList();
+
+  return {};
+}
+
+void ScriptedProcess::DidLaunch() {
+  CheckInterpreterAndScriptObject();
+  m_pid = GetInterface().GetProcessID();
+}
+
+Status ScriptedProcess::DoResume() {
+  CheckInterpreterAndScriptObject();
+
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+  // FIXME: Fetch data from thread.
+  const StateType thread_resume_state = eStateRunning;
+  LLDB_LOGF(log, "ScriptedProcess::%s thread_resume_state = %s", __FUNCTION__,
+            StateAsCString(thread_resume_state));
+
+  bool resume = (thread_resume_state == eStateRunning);
+  assert(thread_resume_state == eStateRunning && "invalid thread resume state");
+
+  Status error;
+  if (resume) {
+    LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__);
+
+    SetPrivateState(eStateRunning);
+    SetPrivateState(eStateStopped);
+    error = GetInterface().Resume();
+  }
+
+  return error;
+}
+
+Status ScriptedProcess::DoStop() {
+  CheckInterpreterAndScriptObject();
+
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  if (GetInterface().ShouldStop()) {
+    SetPrivateState(eStateStopped);
+    LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__);
+    return {};
+  }
+
+  LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__);
+  return GetInterface().Stop();
+}
+
+Status ScriptedProcess::DoDestroy() { return Status(); }
+
+bool ScriptedProcess::IsAlive() {
+  if (m_interpreter && m_script_object_sp)
+    return GetInterface().IsAlive();
+  return false;
+}
+
+size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                                     Status &error) {
+
+  auto error_with_message = [&error](llvm::StringRef message) {
+    error.SetErrorString(message);
+    return 0;
+  };
+
+  if (!m_interpreter)
+    return error_with_message("No interpreter.");
+
+  lldb::DataExtractorSP data_extractor_sp =
+      GetInterface().ReadMemoryAtAddress(addr, size, error);
+
+  if (!data_extractor_sp || error.Fail())
+    return 0;
+
+  offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
+      0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder());
+
+  if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
+    return error_with_message("Failed to copy read memory to buffer.");
+
+  return size;
+}
+
+ArchSpec ScriptedProcess::GetArchitecture() {
+  return GetTarget().GetArchitecture();
+}
+
+Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
+                                            MemoryRegionInfo &region) {
+  // TODO: Implement
+  return Status();
+}
+
+Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos &region_list) {
+  CheckInterpreterAndScriptObject();
+
+  lldb::addr_t address = 0;
+  lldb::MemoryRegionInfoSP mem_region_sp = nullptr;
+
+  while ((mem_region_sp =
+              GetInterface().GetMemoryRegionContainingAddress(address))) {
+    auto range = mem_region_sp->GetRange();
+    address += range.GetRangeBase() + range.GetByteSize();
+    region_list.push_back(*mem_region_sp.get());
+  }
+
+  return {};
+}
+
+void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }
+
+bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
+                                         ThreadList &new_thread_list) {
+  // TODO: Implement
+  // This is supposed to get the current set of threads, if any of them are in
+  // old_thread_list then they get copied to new_thread_list, and then any
+  // actually new threads will get added to new_thread_list.
+  return new_thread_list.GetSize(false) > 0;
+}
+
+bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
+  info.Clear();
+  info.SetProcessID(GetID());
+  info.SetArchitecture(GetArchitecture());
+  lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
+  if (module_sp) {
+    const bool add_exe_file_as_first_arg = false;
+    info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
+                           add_exe_file_as_first_arg);
+  }
+  return true;
+}
+
+ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
+  return m_interpreter->GetScriptedProcessInterface();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
new file mode 100644
index 0000000..98c1a1c
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -0,0 +1,119 @@
+//===-- ScriptedProcess.h ------------------------------------- -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
+#define LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
+
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+
+#include <mutex>
+
+namespace lldb_private {
+
+class ScriptedProcess : public Process {
+protected:
+  class ScriptedProcessInfo {
+  public:
+    ScriptedProcessInfo(const ProcessLaunchInfo &launch_info) {
+      m_class_name = launch_info.GetScriptedProcessClassName();
+      m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP();
+    }
+
+    std::string GetClassName() const { return m_class_name; }
+    StructuredData::DictionarySP GetDictionarySP() const {
+      return m_dictionary_sp;
+    }
+
+  private:
+    std::string m_class_name;
+    StructuredData::DictionarySP m_dictionary_sp;
+  };
+
+public:
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener_sp,
+                                        const FileSpec *crash_file_path,
+                                        bool can_connect);
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static ConstString GetPluginNameStatic();
+
+  static const char *GetPluginDescriptionStatic();
+
+  ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+                  const ScriptedProcess::ScriptedProcessInfo &launch_info,
+                  Status &error);
+
+  ~ScriptedProcess() override;
+
+  bool CanDebug(lldb::TargetSP target_sp,
+                bool plugin_specified_by_name) override;
+
+  DynamicLoader *GetDynamicLoader() override { return nullptr; }
+
+  ConstString GetPluginName() override;
+
+  uint32_t GetPluginVersion() override;
+
+  SystemRuntime *GetSystemRuntime() override { return nullptr; }
+
+  Status DoLoadCore() override;
+
+  Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
+
+  void DidLaunch() override;
+
+  Status DoResume() override;
+
+  Status DoDestroy() override;
+
+  void RefreshStateAfterStop() override{};
+
+  bool IsAlive() override;
+
+  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                      Status &error) override;
+
+  ArchSpec GetArchitecture();
+
+  Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+                             MemoryRegionInfo &range_info) override;
+
+  Status
+  GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
+
+  bool GetProcessInfo(ProcessInstanceInfo &info) override;
+
+protected:
+  Status DoStop();
+
+  void Clear();
+
+  bool DoUpdateThreadList(ThreadList &old_thread_list,
+                          ThreadList &new_thread_list) override;
+
+private:
+  void CheckInterpreterAndScriptObject() const;
+  ScriptedProcessInterface &GetInterface() const;
+  static bool IsScriptLanguageSupported(lldb::ScriptLanguage language);
+
+  // Member variables.
+  const ScriptedProcessInfo m_scripted_process_info;
+  lldb_private::ScriptInterpreter *m_interpreter = nullptr;
+  lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr;
+  //@}
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
index f14e273..e99b7b8 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -30,6 +30,9 @@
     lua_State *L, lldb::StackFrameSP stop_frame_sp,
     lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl);
 
+extern "C" llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction(
+    lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp);
+
 #if _MSC_VER
 #pragma warning (pop)
 #endif
@@ -113,6 +116,32 @@
                                                bp_loc_sp, extra_args_impl);
 }
 
+llvm::Error Lua::RegisterWatchpointCallback(void *baton, const char *body) {
+  lua_pushlightuserdata(m_lua_state, baton);
+  const char *fmt_str = "return function(frame, wp, ...) {0} end";
+  std::string func_str = llvm::formatv(fmt_str, body).str();
+  if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) {
+    llvm::Error e = llvm::make_error<llvm::StringError>(
+        llvm::formatv("{0}", lua_tostring(m_lua_state, -1)),
+        llvm::inconvertibleErrorCode());
+    // Pop error message from the stack.
+    lua_pop(m_lua_state, 2);
+    return e;
+  }
+  lua_settable(m_lua_state, LUA_REGISTRYINDEX);
+  return llvm::Error::success();
+}
+
+llvm::Expected<bool>
+Lua::CallWatchpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
+                            lldb::WatchpointSP wp_sp) {
+
+  lua_pushlightuserdata(m_lua_state, baton);
+  lua_gettable(m_lua_state, LUA_REGISTRYINDEX);
+  return LLDBSwigLuaWatchpointCallbackFunction(m_lua_state, stop_frame_sp,
+                                               wp_sp);
+}
+
 llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) {
   int error =
       luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer");
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
index 873440f..5daedf8 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -37,6 +37,10 @@
   CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
                          lldb::BreakpointLocationSP bp_loc_sp,
                          StructuredData::ObjectSP extra_args_sp);
+  llvm::Error RegisterWatchpointCallback(void *baton, const char *body);
+  llvm::Expected<bool> CallWatchpointCallback(void *baton,
+                                              lldb::StackFrameSP stop_frame_sp,
+                                              lldb::WatchpointSP wp_sp);
   llvm::Error LoadModule(llvm::StringRef filename);
   llvm::Error CheckSyntax(llvm::StringRef buffer);
   llvm::Error ChangeIO(FILE *out, FILE *err);
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 920e334..ef46401 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -58,7 +58,13 @@
     const char *instructions = nullptr;
     switch (m_active_io_handler) {
     case eIOHandlerNone:
+      break;
     case eIOHandlerWatchpoint:
+      instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
+                     "The commands are compiled as the body of the following "
+                     "Lua function\n"
+                     "function (frame, wp) end\n";
+      SetPrompt(llvm::StringRef("..> "));
       break;
     case eIOHandlerBreakpoint:
       instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
@@ -78,7 +84,8 @@
                                 StringList &lines) override {
     size_t last = lines.GetSize() - 1;
     if (IsQuitCommand(lines.GetStringAtIndex(last))) {
-      if (m_active_io_handler == eIOHandlerBreakpoint)
+      if (m_active_io_handler == eIOHandlerBreakpoint ||
+          m_active_io_handler == eIOHandlerWatchpoint)
         lines.DeleteStringAtIndex(last);
       return true;
     }
@@ -90,17 +97,19 @@
       // Lua always errors out to incomplete code with '<eof>'
       return error_str.find("<eof>") == std::string::npos;
     }
-    // The breakpoint handler only exits with a explicit 'quit'
-    return m_active_io_handler != eIOHandlerBreakpoint;
+    // The breakpoint and watchpoint handler only exits with a explicit 'quit'
+    return m_active_io_handler != eIOHandlerBreakpoint &&
+           m_active_io_handler != eIOHandlerWatchpoint;
   }
 
   void IOHandlerInputComplete(IOHandler &io_handler,
                               std::string &data) override {
     switch (m_active_io_handler) {
     case eIOHandlerBreakpoint: {
-      auto *bp_options_vec = static_cast<std::vector<BreakpointOptions *> *>(
-          io_handler.GetUserData());
-      for (auto *bp_options : *bp_options_vec) {
+      auto *bp_options_vec =
+          static_cast<std::vector<std::reference_wrapper<BreakpointOptions>> *>(
+              io_handler.GetUserData());
+      for (BreakpointOptions &bp_options : *bp_options_vec) {
         Status error = m_script_interpreter.SetBreakpointCommandCallback(
             bp_options, data.c_str());
         if (error.Fail())
@@ -108,9 +117,13 @@
       }
       io_handler.SetIsDone(true);
     } break;
-    case eIOHandlerWatchpoint:
+    case eIOHandlerWatchpoint: {
+      auto *wp_options =
+          static_cast<WatchpointOptions *>(io_handler.GetUserData());
+      m_script_interpreter.SetWatchpointCommandCallback(wp_options,
+                                                        data.c_str());
       io_handler.SetIsDone(true);
-      break;
+    } break;
     case eIOHandlerNone:
       if (IsQuitCommand(data)) {
         io_handler.SetIsDone(true);
@@ -133,7 +146,7 @@
     : ScriptInterpreter(debugger, eScriptLanguageLua),
       m_lua(std::make_unique<Lua>()) {}
 
-ScriptInterpreterLua::~ScriptInterpreterLua() {}
+ScriptInterpreterLua::~ScriptInterpreterLua() = default;
 
 bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
                                           CommandReturnObject *result,
@@ -194,8 +207,9 @@
 }
 
 bool ScriptInterpreterLua::LoadScriptingModule(
-    const char *filename, bool init_session, lldb_private::Status &error,
-    StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+    const char *filename, const LoadScriptOptions &options,
+    lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+    FileSpec extra_search_dir) {
 
   FileSystem::Instance().Collect(filename);
   if (llvm::Error e = m_lua->LoadModule(filename)) {
@@ -275,8 +289,35 @@
   return *BoolOrErr;
 }
 
+bool ScriptInterpreterLua::WatchpointCallbackFunction(
+    void *baton, StoppointCallbackContext *context, user_id_t watch_id) {
+  assert(context);
+
+  ExecutionContext exe_ctx(context->exe_ctx_ref);
+  Target *target = exe_ctx.GetTargetPtr();
+  if (target == nullptr)
+    return true;
+
+  StackFrameSP stop_frame_sp(exe_ctx.GetFrameSP());
+  WatchpointSP wp_sp = target->GetWatchpointList().FindByID(watch_id);
+
+  Debugger &debugger = target->GetDebugger();
+  ScriptInterpreterLua *lua_interpreter = static_cast<ScriptInterpreterLua *>(
+      debugger.GetScriptInterpreter(true, eScriptLanguageLua));
+  Lua &lua = lua_interpreter->GetLua();
+
+  llvm::Expected<bool> BoolOrErr =
+      lua.CallWatchpointCallback(baton, stop_frame_sp, wp_sp);
+  if (llvm::Error E = BoolOrErr.takeError()) {
+    debugger.GetErrorStream() << toString(std::move(E));
+    return true;
+  }
+
+  return *BoolOrErr;
+}
+
 void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback(
-    std::vector<BreakpointOptions *> &bp_options_vec,
+    std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
     CommandReturnObject &result) {
   IOHandlerSP io_handler_sp(
       new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerBreakpoint));
@@ -284,8 +325,16 @@
   m_debugger.RunIOHandlerAsync(io_handler_sp);
 }
 
+void ScriptInterpreterLua::CollectDataForWatchpointCommandCallback(
+    WatchpointOptions *wp_options, CommandReturnObject &result) {
+  IOHandlerSP io_handler_sp(
+      new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerWatchpoint));
+  io_handler_sp->SetUserData(wp_options);
+  m_debugger.RunIOHandlerAsync(io_handler_sp);
+}
+
 Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction(
-    BreakpointOptions *bp_options, const char *function_name,
+    BreakpointOptions &bp_options, const char *function_name,
     StructuredData::ObjectSP extra_args_sp) {
   const char *fmt_str = "return {0}(frame, bp_loc, ...)";
   std::string oneliner = llvm::formatv(fmt_str, function_name).str();
@@ -294,12 +343,12 @@
 }
 
 Status ScriptInterpreterLua::SetBreakpointCommandCallback(
-    BreakpointOptions *bp_options, const char *command_body_text) {
+    BreakpointOptions &bp_options, const char *command_body_text) {
   return RegisterBreakpointCallback(bp_options, command_body_text, {});
 }
 
 Status ScriptInterpreterLua::RegisterBreakpointCallback(
-    BreakpointOptions *bp_options, const char *command_body_text,
+    BreakpointOptions &bp_options, const char *command_body_text,
     StructuredData::ObjectSP extra_args_sp) {
   Status error;
   auto data_up = std::make_unique<CommandDataLua>(extra_args_sp);
@@ -308,7 +357,27 @@
     return error;
   auto baton_sp =
       std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
-  bp_options->SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction,
+  bp_options.SetCallback(ScriptInterpreterLua::BreakpointCallbackFunction,
+                         baton_sp);
+  return error;
+}
+
+void ScriptInterpreterLua::SetWatchpointCommandCallback(
+    WatchpointOptions *wp_options, const char *command_body_text) {
+  RegisterWatchpointCallback(wp_options, command_body_text, {});
+}
+
+Status ScriptInterpreterLua::RegisterWatchpointCallback(
+    WatchpointOptions *wp_options, const char *command_body_text,
+    StructuredData::ObjectSP extra_args_sp) {
+  Status error;
+  auto data_up = std::make_unique<WatchpointOptions::CommandData>();
+  error = m_lua->RegisterWatchpointCallback(data_up.get(), command_body_text);
+  if (error.Fail())
+    return error;
+  auto baton_sp =
+      std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up));
+  wp_options->SetCallback(ScriptInterpreterLua::WatchpointCallbackFunction,
                           baton_sp);
   return error;
 }
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
index 1130cee..808000b 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -9,6 +9,9 @@
 #ifndef liblldb_ScriptInterpreterLua_h_
 #define liblldb_ScriptInterpreterLua_h_
 
+#include <vector>
+
+#include "lldb/Breakpoint/WatchpointOptions.h"
 #include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
 #include "lldb/Utility/Status.h"
@@ -40,7 +43,8 @@
 
   void ExecuteInterpreterLoop() override;
 
-  bool LoadScriptingModule(const char *filename, bool init_session,
+  bool LoadScriptingModule(const char *filename,
+                           const LoadScriptOptions &options,
                            lldb_private::Status &error,
                            StructuredData::ObjectSP *module_sp = nullptr,
                            FileSpec extra_search_dir = {}) override;
@@ -61,6 +65,10 @@
                                          lldb::user_id_t break_id,
                                          lldb::user_id_t break_loc_id);
 
+  static bool WatchpointCallbackFunction(void *baton,
+                                         StoppointCallbackContext *context,
+                                         lldb::user_id_t watch_id);
+
   // PluginInterface protocol
   lldb_private::ConstString GetPluginName() override;
 
@@ -72,21 +80,32 @@
   llvm::Error LeaveSession();
 
   void CollectDataForBreakpointCommandCallback(
-      std::vector<BreakpointOptions *> &bp_options_vec,
+      std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
       CommandReturnObject &result) override;
 
-  Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+  void
+  CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
+                                          CommandReturnObject &result) override;
+
+  Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
                                       const char *command_body_text) override;
 
+  void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
+                                    const char *command_body_text) override;
+
   Status SetBreakpointCommandCallbackFunction(
-      BreakpointOptions *bp_options, const char *function_name,
+      BreakpointOptions &bp_options, const char *function_name,
       StructuredData::ObjectSP extra_args_sp) override;
 
 private:
   std::unique_ptr<Lua> m_lua;
   bool m_session_is_active = false;
 
-  Status RegisterBreakpointCallback(BreakpointOptions *bp_options,
+  Status RegisterBreakpointCallback(BreakpointOptions &bp_options,
+                                    const char *command_body_text,
+                                    StructuredData::ObjectSP extra_args_sp);
+
+  Status RegisterWatchpointCallback(WatchpointOptions *wp_options,
                                     const char *command_body_text,
                                     StructuredData::ObjectSP extra_args_sp);
 };
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
index d9c32cc..f8a3852 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp
@@ -25,7 +25,7 @@
 ScriptInterpreterNone::ScriptInterpreterNone(Debugger &debugger)
     : ScriptInterpreter(debugger, eScriptLanguageNone) {}
 
-ScriptInterpreterNone::~ScriptInterpreterNone() {}
+ScriptInterpreterNone::~ScriptInterpreterNone() = default;
 
 bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command,
                                            CommandReturnObject *,
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
index 2cbf8bc..84115aa 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
@@ -11,6 +11,8 @@
   PythonDataObjects.cpp
   PythonReadline.cpp
   ScriptInterpreterPython.cpp
+  ScriptedProcessPythonInterface.cpp
+  SWIGPythonBridge.cpp
 
   LINK_LIBS
     lldbBreakpoint
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 7c49502..f51d9b3a 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -24,7 +24,7 @@
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Errno.h"
 
-#include <stdio.h>
+#include <cstdio>
 
 using namespace lldb_private;
 using namespace lldb;
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 22f6c67..4577253 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -229,7 +229,7 @@
 
 class PythonObject {
 public:
-  PythonObject() : m_py_obj(nullptr) {}
+  PythonObject() = default;
 
   PythonObject(PyRefType type, PyObject *py_obj) {
     m_py_obj = py_obj;
@@ -378,7 +378,7 @@
   }
 
 protected:
-  PyObject *m_py_obj;
+  PyObject *m_py_obj = nullptr;
 };
 
 
@@ -421,7 +421,7 @@
       Py_DECREF(py_obj);
   }
 
-  TypedPythonObject() {}
+  TypedPythonObject() = default;
 };
 
 class PythonBytes : public TypedPythonObject<PythonBytes> {
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
index 5f6429f..95a3365 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
@@ -2,7 +2,7 @@
 
 #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
 
-#include <stdio.h>
+#include <cstdio>
 
 #include <editline/readline.h>
 
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
new file mode 100644
index 0000000..7c7c5d7
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.cpp
@@ -0,0 +1,48 @@
+//===-- SWIGPythonBridge.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 "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+
+using namespace lldb;
+
+namespace lldb_private {
+
+template <typename T> const char *GetPythonValueFormatString(T t);
+template <> const char *GetPythonValueFormatString(char *) { return "s"; }
+template <> const char *GetPythonValueFormatString(char) { return "b"; }
+template <> const char *GetPythonValueFormatString(unsigned char) {
+  return "B";
+}
+template <> const char *GetPythonValueFormatString(short) { return "h"; }
+template <> const char *GetPythonValueFormatString(unsigned short) {
+  return "H";
+}
+template <> const char *GetPythonValueFormatString(int) { return "i"; }
+template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
+template <> const char *GetPythonValueFormatString(long) { return "l"; }
+template <> const char *GetPythonValueFormatString(unsigned long) {
+  return "k";
+}
+template <> const char *GetPythonValueFormatString(long long) { return "L"; }
+template <> const char *GetPythonValueFormatString(unsigned long long) {
+  return "K";
+}
+template <> const char *GetPythonValueFormatString(float) { return "f"; }
+template <> const char *GetPythonValueFormatString(double) { return "d"; }
+
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
new file mode 100644
index 0000000..1ef792b
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h
@@ -0,0 +1,56 @@
+//===-- ScriptInterpreterPython.h -------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
+
+#include <string>
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+
+// GetPythonValueFormatString provides a system independent type safe way to
+// convert a variable's type into a python value format. Python value formats
+// are defined in terms of builtin C types and could change from system to as
+// the underlying typedef for uint* types, size_t, off_t and other values
+// change.
+
+template <typename T> const char *GetPythonValueFormatString(T t);
+template <> const char *GetPythonValueFormatString(char *);
+template <> const char *GetPythonValueFormatString(char);
+template <> const char *GetPythonValueFormatString(unsigned char);
+template <> const char *GetPythonValueFormatString(short);
+template <> const char *GetPythonValueFormatString(unsigned short);
+template <> const char *GetPythonValueFormatString(int);
+template <> const char *GetPythonValueFormatString(unsigned int);
+template <> const char *GetPythonValueFormatString(long);
+template <> const char *GetPythonValueFormatString(unsigned long);
+template <> const char *GetPythonValueFormatString(long long);
+template <> const char *GetPythonValueFormatString(unsigned long long);
+template <> const char *GetPythonValueFormatString(float t);
+template <> const char *GetPythonValueFormatString(double t);
+
+extern "C" void *LLDBSwigPythonCreateScriptedProcess(
+    const char *python_class_name, const char *session_dictionary_name,
+    const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl,
+    std::string &error_string);
+
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data);
+extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
+
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 6b53bd3..7ad6372 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -16,7 +16,11 @@
 
 #include "PythonDataObjects.h"
 #include "PythonReadline.h"
+#include "SWIGPythonBridge.h"
 #include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedProcessPythonInterface.h"
+
+#include "lldb/API/SBError.h"
 #include "lldb/API/SBFrame.h"
 #include "lldb/API/SBValue.h"
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -41,10 +45,10 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatAdapters.h"
 
+#include <cstdio>
+#include <cstdlib>
 #include <memory>
 #include <mutex>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string>
 
 using namespace lldb;
@@ -148,8 +152,6 @@
 extern "C" int LLDBSwigPython_GetIndexOfChildWithName(void *implementor,
                                                       const char *child_name);
 
-extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data);
-
 extern lldb::ValueObjectSP
 LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
 
@@ -234,8 +236,7 @@
 // save off initial state at the beginning, and restore it at the end
 struct InitializePythonRAII {
 public:
-  InitializePythonRAII()
-      : m_gil_state(PyGILState_UNLOCKED), m_was_already_initialized(false) {
+  InitializePythonRAII() {
     InitializePythonHome();
 
 #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
@@ -355,8 +356,8 @@
   }
 
   TerminalState m_stdin_tty_state;
-  PyGILState_STATE m_gil_state;
-  bool m_was_already_initialized;
+  PyGILState_STATE m_gil_state = PyGILState_UNLOCKED;
+  bool m_was_already_initialized = false;
 };
 } // namespace
 
@@ -410,6 +411,32 @@
   return g_spec;
 }
 
+void ScriptInterpreterPython::SharedLibraryDirectoryHelper(
+    FileSpec &this_file) {
+  // When we're loaded from python, this_file will point to the file inside the
+  // python package directory. Replace it with the one in the lib directory.
+#ifdef _WIN32
+  // On windows, we need to manually back out of the python tree, and go into
+  // the bin directory. This is pretty much the inverse of what ComputePythonDir
+  // does.
+  if (this_file.GetFileNameExtension() == ConstString(".pyd")) {
+    this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd
+    this_file.RemoveLastPathComponent(); // lldb
+    llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR;
+    for (auto it = llvm::sys::path::begin(libdir),
+              end = llvm::sys::path::end(libdir);
+         it != end; ++it)
+      this_file.RemoveLastPathComponent();
+    this_file.AppendPathComponent("bin");
+    this_file.AppendPathComponent("liblldb.dll");
+  }
+#else
+  // The python file is a symlink, so we can find the real library by resolving
+  // it. We can do this unconditionally.
+  FileSystem::Instance().ResolveSymbolicLink(this_file, this_file);
+#endif
+}
+
 lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() {
   static ConstString g_name("script-python");
   return g_name;
@@ -506,6 +533,9 @@
       m_command_thread_state(nullptr) {
   InitializePrivate();
 
+  m_scripted_process_interface_up =
+      std::make_unique<ScriptedProcessPythonInterface>(*this);
+
   m_dictionary_name.append("_dict");
   StreamString run_string;
   run_string.Printf("%s = dict()", m_dictionary_name.c_str());
@@ -605,11 +635,10 @@
   case eIOHandlerNone:
     break;
   case eIOHandlerBreakpoint: {
-    std::vector<BreakpointOptions *> *bp_options_vec =
-        (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
-    for (auto bp_options : *bp_options_vec) {
-      if (!bp_options)
-        continue;
+    std::vector<std::reference_wrapper<BreakpointOptions>> *bp_options_vec =
+        (std::vector<std::reference_wrapper<BreakpointOptions>> *)
+            io_handler.GetUserData();
+    for (BreakpointOptions &bp_options : *bp_options_vec) {
 
       auto data_up = std::make_unique<CommandDataPython>();
       if (!data_up)
@@ -623,7 +652,7 @@
               .Success()) {
         auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(
             std::move(data_up));
-        bp_options->SetCallback(
+        bp_options.SetCallback(
             ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
       } else if (!batch_mode) {
         StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
@@ -1048,11 +1077,24 @@
     llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
     void *ret_value, const ExecuteScriptOptions &options) {
 
+  llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+      io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+          options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+  if (!io_redirect_or_error) {
+    llvm::consumeError(io_redirect_or_error.takeError());
+    return false;
+  }
+
+  ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
   Locker locker(this,
                 Locker::AcquireLock | Locker::InitSession |
                     (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
                     Locker::NoSTDIN,
-                Locker::FreeAcquiredLock | Locker::TearDownSession);
+                Locker::FreeAcquiredLock | Locker::TearDownSession,
+                io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+                io_redirect.GetErrorFile());
 
   PythonModule &main_module = GetMainModule();
   PythonDictionary globals = main_module.GetDictionary();
@@ -1161,11 +1203,22 @@
   if (in_string == nullptr)
     return Status();
 
+  llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+      io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+          options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+  if (!io_redirect_or_error)
+    return Status(io_redirect_or_error.takeError());
+
+  ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
+
   Locker locker(this,
                 Locker::AcquireLock | Locker::InitSession |
                     (options.GetSetLLDBGlobals() ? Locker::InitGlobals : 0) |
                     Locker::NoSTDIN,
-                Locker::FreeAcquiredLock | Locker::TearDownSession);
+                Locker::FreeAcquiredLock | Locker::TearDownSession,
+                io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+                io_redirect.GetErrorFile());
 
   PythonModule &main_module = GetMainModule();
   PythonDictionary globals = main_module.GetDictionary();
@@ -1196,7 +1249,7 @@
 }
 
 void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
-    std::vector<BreakpointOptions *> &bp_options_vec,
+    std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
     CommandReturnObject &result) {
   m_active_io_handler = eIOHandlerBreakpoint;
   m_debugger.GetCommandInterpreter().GetPythonCommandsFromIOHandler(
@@ -1211,7 +1264,7 @@
 }
 
 Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction(
-    BreakpointOptions *bp_options, const char *function_name,
+    BreakpointOptions &bp_options, const char *function_name,
     StructuredData::ObjectSP extra_args_sp) {
   Status error;
   // For now just cons up a oneliner that calls the provided function.
@@ -1253,7 +1306,7 @@
 }
 
 Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
-    BreakpointOptions *bp_options,
+    BreakpointOptions &bp_options,
     std::unique_ptr<BreakpointOptions::CommandData> &cmd_data_up) {
   Status error;
   error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source,
@@ -1264,21 +1317,20 @@
   }
   auto baton_sp =
       std::make_shared<BreakpointOptions::CommandBaton>(std::move(cmd_data_up));
-  bp_options->SetCallback(
+  bp_options.SetCallback(
       ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
   return error;
 }
 
 Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
-    BreakpointOptions *bp_options, const char *command_body_text) {
+    BreakpointOptions &bp_options, const char *command_body_text) {
   return SetBreakpointCommandCallback(bp_options, command_body_text, {},false);
 }
 
 // Set a Python one-liner as the callback for the breakpoint.
 Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback(
-    BreakpointOptions *bp_options, const char *command_body_text,
-    StructuredData::ObjectSP extra_args_sp,
-    bool uses_extra_args) {
+    BreakpointOptions &bp_options, const char *command_body_text,
+    StructuredData::ObjectSP extra_args_sp, bool uses_extra_args) {
   auto data_up = std::make_unique<CommandDataPython>(extra_args_sp);
   // Split the command_body_text into lines, and pass that to
   // GenerateBreakpointCommandCallbackData.  That will wrap the body in an
@@ -1292,7 +1344,7 @@
   if (error.Success()) {
     auto baton_sp =
         std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up));
-    bp_options->SetCallback(
+    bp_options.SetCallback(
         ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp);
     return error;
   }
@@ -1330,7 +1382,7 @@
 
   Status error = ExecuteMultipleLines(
       function_def_string.c_str(),
-      ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
+      ExecuteScriptOptions().SetEnableIO(false));
   return error;
 }
 
@@ -1678,35 +1730,6 @@
   return StructuredData::ArraySP();
 }
 
-// GetPythonValueFormatString provides a system independent type safe way to
-// convert a variable's type into a python value format. Python value formats
-// are defined in terms of builtin C types and could change from system to as
-// the underlying typedef for uint* types, size_t, off_t and other values
-// change.
-
-template <typename T> const char *GetPythonValueFormatString(T t);
-template <> const char *GetPythonValueFormatString(char *) { return "s"; }
-template <> const char *GetPythonValueFormatString(char) { return "b"; }
-template <> const char *GetPythonValueFormatString(unsigned char) {
-  return "B";
-}
-template <> const char *GetPythonValueFormatString(short) { return "h"; }
-template <> const char *GetPythonValueFormatString(unsigned short) {
-  return "H";
-}
-template <> const char *GetPythonValueFormatString(int) { return "i"; }
-template <> const char *GetPythonValueFormatString(unsigned int) { return "I"; }
-template <> const char *GetPythonValueFormatString(long) { return "l"; }
-template <> const char *GetPythonValueFormatString(unsigned long) {
-  return "k";
-}
-template <> const char *GetPythonValueFormatString(long long) { return "L"; }
-template <> const char *GetPythonValueFormatString(unsigned long long) {
-  return "K";
-}
-template <> const char *GetPythonValueFormatString(float t) { return "f"; }
-template <> const char *GetPythonValueFormatString(double t) { return "d"; }
-
 StructuredData::StringSP
 ScriptInterpreterPythonImpl::OSPlugin_RegisterContextData(
     StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid) {
@@ -2058,7 +2081,10 @@
 
   StructuredData::ObjectSP module_sp;
 
-  if (LoadScriptingModule(file_spec.GetPath().c_str(), true, error, &module_sp))
+  LoadScriptOptions load_script_options =
+      LoadScriptOptions().SetInitSession(true).SetSilent(false);
+  if (LoadScriptingModule(file_spec.GetPath().c_str(), load_script_options,
+                          error, &module_sp))
     return module_sp;
 
   return StructuredData::ObjectSP();
@@ -2733,26 +2759,44 @@
 }
 
 bool ScriptInterpreterPythonImpl::LoadScriptingModule(
-    const char *pathname, bool init_session, lldb_private::Status &error,
-    StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir) {
+    const char *pathname, const LoadScriptOptions &options,
+    lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
+    FileSpec extra_search_dir) {
   namespace fs = llvm::sys::fs;
   namespace path = llvm::sys::path;
 
+  ExecuteScriptOptions exc_options = ExecuteScriptOptions()
+                                         .SetEnableIO(!options.GetSilent())
+                                         .SetSetLLDBGlobals(false);
+
   if (!pathname || !pathname[0]) {
     error.SetErrorString("invalid pathname");
     return false;
   }
 
+  llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
+      io_redirect_or_error = ScriptInterpreterIORedirect::Create(
+          exc_options.GetEnableIO(), m_debugger, /*result=*/nullptr);
+
+  if (!io_redirect_or_error) {
+    error = io_redirect_or_error.takeError();
+    return false;
+  }
+
+  ScriptInterpreterIORedirect &io_redirect = **io_redirect_or_error;
   lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this();
 
   // Before executing Python code, lock the GIL.
   Locker py_lock(this,
                  Locker::AcquireLock |
-                     (init_session ? Locker::InitSession : 0) | Locker::NoSTDIN,
+                     (options.GetInitSession() ? Locker::InitSession : 0) |
+                     Locker::NoSTDIN,
                  Locker::FreeAcquiredLock |
-                     (init_session ? Locker::TearDownSession : 0));
+                     (options.GetInitSession() ? Locker::TearDownSession : 0),
+                 io_redirect.GetInputFile(), io_redirect.GetOutputFile(),
+                 io_redirect.GetErrorFile());
 
-  auto ExtendSysPath = [this](std::string directory) -> llvm::Error {
+  auto ExtendSysPath = [&](std::string directory) -> llvm::Error {
     if (directory.empty()) {
       return llvm::make_error<llvm::StringError>(
           "invalid directory name", llvm::inconvertibleErrorCode());
@@ -2767,11 +2811,7 @@
                           "sys.path.insert(1,'%s');\n\n",
                           directory.c_str(), directory.c_str());
     bool syspath_retval =
-        ExecuteMultipleLines(command_stream.GetData(),
-                             ScriptInterpreter::ExecuteScriptOptions()
-                                 .SetEnableIO(false)
-                                 .SetSetLLDBGlobals(false))
-            .Success();
+        ExecuteMultipleLines(command_stream.GetData(), exc_options).Success();
     if (!syspath_retval) {
       return llvm::make_error<llvm::StringError>(
           "Python sys.path handling failed", llvm::inconvertibleErrorCode());
@@ -2781,6 +2821,7 @@
   };
 
   std::string module_name(pathname);
+  bool possible_package = false;
 
   if (extra_search_dir) {
     if (llvm::Error e = ExtendSysPath(extra_search_dir.GetPath())) {
@@ -2805,6 +2846,7 @@
         return false;
       }
       // Not a filename, probably a package of some sort, let it go through.
+      possible_package = true;
     } else if (is_directory(st) || is_regular_file(st)) {
       if (module_file.GetDirectory().IsEmpty()) {
         error.SetErrorString("invalid directory name");
@@ -2831,35 +2873,39 @@
       module_name.resize(module_name.length() - 4);
   }
 
-  // check if the module is already import-ed
+  if (!possible_package && module_name.find('.') != llvm::StringRef::npos) {
+    error.SetErrorStringWithFormat(
+        "Python does not allow dots in module names: %s", module_name.c_str());
+    return false;
+  }
+
+  if (module_name.find('-') != llvm::StringRef::npos) {
+    error.SetErrorStringWithFormat(
+        "Python discourages dashes in module names: %s", module_name.c_str());
+    return false;
+  }
+
+  // Check if the module is already imported.
   StreamString command_stream;
   command_stream.Clear();
   command_stream.Printf("sys.modules.__contains__('%s')", module_name.c_str());
   bool does_contain = false;
-  // this call will succeed if the module was ever imported in any Debugger
-  // in the lifetime of the process in which this LLDB framework is living
-  bool was_imported_globally =
-      (ExecuteOneLineWithReturn(
-           command_stream.GetData(),
-           ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain,
-           ScriptInterpreter::ExecuteScriptOptions()
-               .SetEnableIO(false)
-               .SetSetLLDBGlobals(false)) &&
-       does_contain);
-  // this call will fail if the module was not imported in this Debugger
-  // before
-  command_stream.Clear();
-  command_stream.Printf("sys.getrefcount(%s)", module_name.c_str());
-  bool was_imported_locally = GetSessionDictionary()
-                                  .GetItemForKey(PythonString(module_name))
-                                  .IsAllocated();
+  // This call will succeed if the module was ever imported in any Debugger in
+  // the lifetime of the process in which this LLDB framework is living.
+  const bool does_contain_executed = ExecuteOneLineWithReturn(
+      command_stream.GetData(),
+      ScriptInterpreterPythonImpl::eScriptReturnTypeBool, &does_contain, exc_options);
 
-  bool was_imported = (was_imported_globally || was_imported_locally);
+  const bool was_imported_globally = does_contain_executed && does_contain;
+  const bool was_imported_locally =
+      GetSessionDictionary()
+          .GetItemForKey(PythonString(module_name))
+          .IsAllocated();
 
   // now actually do the import
   command_stream.Clear();
 
-  if (was_imported) {
+  if (was_imported_globally || was_imported_locally) {
     if (!was_imported_locally)
       command_stream.Printf("import %s ; reload_module(%s)",
                             module_name.c_str(), module_name.c_str());
@@ -2868,10 +2914,7 @@
   } else
     command_stream.Printf("import %s", module_name.c_str());
 
-  error = ExecuteMultipleLines(command_stream.GetData(),
-                               ScriptInterpreter::ExecuteScriptOptions()
-                                   .SetEnableIO(false)
-                                   .SetSetLLDBGlobals(false));
+  error = ExecuteMultipleLines(command_stream.GetData(), exc_options);
   if (error.Fail())
     return false;
 
@@ -2890,7 +2933,8 @@
     void *module_pyobj = nullptr;
     if (ExecuteOneLineWithReturn(
             command_stream.GetData(),
-            ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj) &&
+            ScriptInterpreter::eScriptReturnTypeOpaqueObject, &module_pyobj,
+            exc_options) &&
         module_pyobj)
       *module_sp = std::make_shared<StructuredPythonObject>(module_pyobj);
   }
@@ -3047,7 +3091,7 @@
   if (ExecuteOneLineWithReturn(
           command, ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
           &result_ptr,
-          ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false))) {
+          ExecuteScriptOptions().SetEnableIO(false))) {
     if (result_ptr)
       dest.assign(result_ptr);
     return true;
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index e59fedb..b8b9781 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -13,6 +13,8 @@
 
 #if LLDB_ENABLE_PYTHON
 
+#include "ScriptedProcessPythonInterface.h"
+
 #include "lldb/Breakpoint/BreakpointOptions.h"
 #include "lldb/Core/IOHandler.h"
 #include "lldb/Core/StructuredDataImpl.h"
@@ -51,6 +53,7 @@
   static lldb_private::ConstString GetPluginNameStatic();
   static const char *GetPluginDescriptionStatic();
   static FileSpec GetPythonDir();
+  static void SharedLibraryDirectoryHelper(FileSpec &this_file);
 
 protected:
   static void ComputePythonDirForApple(llvm::SmallVectorImpl<char> &path);
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 45dad42..d1b0b3f 100644
--- a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -6,6 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
+
 #include "lldb/Host/Config.h"
 
 #if LLDB_ENABLE_PYTHON
@@ -231,7 +234,8 @@
   bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
                               std::string &output, Status &error) override;
 
-  bool LoadScriptingModule(const char *filename, bool init_session,
+  bool LoadScriptingModule(const char *filename,
+                           const LoadScriptOptions &options,
                            lldb_private::Status &error,
                            StructuredData::ObjectSP *module_sp = nullptr,
                            FileSpec extra_search_dir = {}) override;
@@ -241,7 +245,7 @@
   std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
 
   void CollectDataForBreakpointCommandCallback(
-      std::vector<BreakpointOptions *> &bp_options_vec,
+      std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
       CommandReturnObject &result) override;
 
   void
@@ -249,20 +253,19 @@
                                           CommandReturnObject &result) override;
 
   /// Set the callback body text into the callback for the breakpoint.
-  Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+  Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
                                       const char *callback_body) override;
 
   Status SetBreakpointCommandCallbackFunction(
-      BreakpointOptions *bp_options,
-      const char *function_name,
+      BreakpointOptions &bp_options, const char *function_name,
       StructuredData::ObjectSP extra_args_sp) override;
 
   /// This one is for deserialization:
   Status SetBreakpointCommandCallback(
-      BreakpointOptions *bp_options,
+      BreakpointOptions &bp_options,
       std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
 
-  Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
+  Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
                                       const char *command_body_text,
                                       StructuredData::ObjectSP extra_args_sp,
                                       bool uses_extra_args);
@@ -416,7 +419,7 @@
       : IOHandler(debugger, IOHandler::Type::PythonInterpreter),
         m_python(python) {}
 
-  ~IOHandlerPythonInterpreter() override {}
+  ~IOHandlerPythonInterpreter() override = default;
 
   ConstString GetControlSequence(char ch) override {
     if (ch == 'd')
@@ -483,4 +486,5 @@
 
 } // namespace lldb_private
 
-#endif
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
new file mode 100644
index 0000000..ce262c9
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -0,0 +1,306 @@
+//===-- ScriptedProcessPythonInterface.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 "lldb/Host/Config.h"
+#include "lldb/lldb-enumerations.h"
+
+#if LLDB_ENABLE_PYTHON
+
+// LLDB Python header must be included first
+#include "lldb-python.h"
+
+#include "SWIGPythonBridge.h"
+#include "ScriptInterpreterPythonImpl.h"
+#include "ScriptedProcessPythonInterface.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::python;
+using Locker = ScriptInterpreterPythonImpl::Locker;
+
+StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject(
+    const llvm::StringRef class_name, lldb::TargetSP target_sp,
+    StructuredData::DictionarySP args_sp) {
+  if (class_name.empty())
+    return {};
+
+  std::string error_string;
+  StructuredDataImpl *args_impl = nullptr;
+  if (args_sp) {
+    args_impl = new StructuredDataImpl();
+    args_impl->SetObjectSP(args_sp);
+  }
+
+  void *ret_val;
+
+  {
+
+    Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                   Locker::FreeLock);
+
+    ret_val = LLDBSwigPythonCreateScriptedProcess(
+        class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp,
+        args_impl, error_string);
+  }
+
+  m_object_instance_sp =
+      StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+
+  return m_object_instance_sp;
+}
+
+Status ScriptedProcessPythonInterface::Launch() {
+  return GetStatusFromMethod("launch");
+}
+
+Status ScriptedProcessPythonInterface::Resume() {
+  return GetStatusFromMethod("resume");
+}
+
+bool ScriptedProcessPythonInterface::ShouldStop() {
+  llvm::Optional<unsigned long long> should_stop =
+      GetGenericInteger("should_stop");
+
+  if (!should_stop)
+    return false;
+
+  return static_cast<bool>(*should_stop);
+}
+
+Status ScriptedProcessPythonInterface::Stop() {
+  return GetStatusFromMethod("stop");
+}
+
+Status ScriptedProcessPythonInterface::GetStatusFromMethod(
+    llvm::StringRef method_name) {
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  if (!m_object_instance_sp)
+    return Status("Python object ill-formed.");
+
+  if (!m_object_instance_sp)
+    return Status("Cannot convert Python object to StructuredData::Generic.");
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+
+  if (!implementor.IsAllocated())
+    return Status("Python implementor not allocated.");
+
+  PythonObject pmeth(
+      PyRefType::Owned,
+      PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  if (!pmeth.IsAllocated())
+    return Status("Python method not allocated.");
+
+  if (PyCallable_Check(pmeth.get()) == 0) {
+    if (PyErr_Occurred())
+      PyErr_Clear();
+    return Status("Python method not callable.");
+  }
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  PythonObject py_return(PyRefType::Owned,
+                         PyObject_CallMethod(implementor.get(),
+                                             method_name.str().c_str(),
+                                             nullptr));
+
+  if (PyErr_Occurred()) {
+    PyErr_Print();
+    PyErr_Clear();
+    return Status("Python method could not be called.");
+  }
+
+  if (PyObject *py_ret_ptr = py_return.get()) {
+    lldb::SBError *sb_error =
+        (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr);
+
+    if (!sb_error)
+      return Status("Couldn't cast lldb::SBError to lldb::Status.");
+
+    Status status = m_interpreter.GetStatusFromSBError(*sb_error);
+
+    if (status.Fail())
+      return Status("error: %s", status.AsCString());
+
+    return status;
+  }
+
+  return Status("Returned object is null.");
+}
+
+llvm::Optional<unsigned long long>
+ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) {
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  if (!m_object_instance_sp)
+    return llvm::None;
+
+  if (!m_object_instance_sp)
+    return llvm::None;
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+
+  if (!implementor.IsAllocated())
+    return llvm::None;
+
+  PythonObject pmeth(
+      PyRefType::Owned,
+      PyObject_GetAttrString(implementor.get(), method_name.str().c_str()));
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  if (!pmeth.IsAllocated())
+    return llvm::None;
+
+  if (PyCallable_Check(pmeth.get()) == 0) {
+    if (PyErr_Occurred())
+      PyErr_Clear();
+    return llvm::None;
+  }
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  PythonObject py_return(PyRefType::Owned,
+                         PyObject_CallMethod(implementor.get(),
+                                             method_name.str().c_str(),
+                                             nullptr));
+
+  if (PyErr_Occurred()) {
+    PyErr_Print();
+    PyErr_Clear();
+  }
+
+  if (!py_return.get())
+    return llvm::None;
+
+  llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong();
+  // FIXME: Handle error.
+  if (!size)
+    return llvm::None;
+
+  return *size;
+}
+
+lldb::MemoryRegionInfoSP
+ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
+    lldb::addr_t address) {
+  // TODO: Implement
+  return nullptr;
+}
+
+StructuredData::DictionarySP
+ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) {
+  // TODO: Implement
+  return nullptr;
+}
+
+StructuredData::DictionarySP
+ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) {
+  // TODO: Implement
+  return nullptr;
+}
+
+lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
+    lldb::addr_t address, size_t size, Status &error) {
+  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
+                 Locker::FreeLock);
+
+  auto error_with_message = [&error](llvm::StringRef message) {
+    error.SetErrorString(message);
+    return nullptr;
+  };
+
+  static char callee_name[] = "read_memory_at_address";
+  std::string param_format = GetPythonValueFormatString(address);
+  param_format += GetPythonValueFormatString(size);
+
+  if (!m_object_instance_sp)
+    return error_with_message("Python object ill-formed.");
+
+  if (!m_object_instance_sp)
+    return error_with_message("Python method not callable.");
+
+  PythonObject implementor(PyRefType::Borrowed,
+                           (PyObject *)m_object_instance_sp->GetValue());
+
+  if (!implementor.IsAllocated())
+    return error_with_message("Python implementor not allocated.");
+
+  PythonObject pmeth(PyRefType::Owned,
+                     PyObject_GetAttrString(implementor.get(), callee_name));
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  if (!pmeth.IsAllocated())
+    return error_with_message("Python method not allocated.");
+
+  if (PyCallable_Check(pmeth.get()) == 0) {
+    if (PyErr_Occurred())
+      PyErr_Clear();
+    return error_with_message("Python method not callable.");
+  }
+
+  if (PyErr_Occurred())
+    PyErr_Clear();
+
+  PythonObject py_return(PyRefType::Owned,
+                         PyObject_CallMethod(implementor.get(), callee_name,
+                                             param_format.c_str(), address,
+                                             size));
+
+  if (PyErr_Occurred()) {
+    PyErr_Print();
+    PyErr_Clear();
+    return error_with_message("Python method could not be called.");
+  }
+
+  if (PyObject *py_ret_ptr = py_return.get()) {
+    lldb::SBData *sb_data =
+        (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr);
+
+    if (!sb_data)
+      return error_with_message(
+          "Couldn't cast lldb::SBData to lldb::DataExtractor.");
+
+    return m_interpreter.GetDataExtractorFromSBData(*sb_data);
+  }
+
+  return error_with_message("Returned object is null.");
+}
+
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() {
+  // TODO: Implement
+  return nullptr;
+}
+
+lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
+  llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id");
+  return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid;
+}
+
+bool ScriptedProcessPythonInterface::IsAlive() {
+  llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive");
+
+  if (!is_alive)
+    return false;
+
+  return static_cast<bool>(*is_alive);
+}
+
+#endif
diff --git a/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
new file mode 100644
index 0000000..30cb5a8
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -0,0 +1,66 @@
+//===-- ScriptedProcessPythonInterface.h ------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
+
+#include "lldb/Host/Config.h"
+
+#if LLDB_ENABLE_PYTHON
+
+#include "lldb/Interpreter/ScriptedProcessInterface.h"
+
+namespace lldb_private {
+class ScriptInterpreterPythonImpl;
+class ScriptedProcessPythonInterface : public ScriptedProcessInterface {
+public:
+  ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter)
+      : ScriptedProcessInterface(), m_interpreter(interpreter) {}
+
+  StructuredData::GenericSP
+  CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp,
+                     StructuredData::DictionarySP args_sp) override;
+
+  Status Launch() override;
+
+  Status Resume() override;
+
+  bool ShouldStop() override;
+
+  Status Stop() override;
+
+  lldb::MemoryRegionInfoSP
+  GetMemoryRegionContainingAddress(lldb::addr_t address) override;
+
+  StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override;
+
+  StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override;
+
+  lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size,
+                                            Status &error) override;
+
+  StructuredData::DictionarySP GetLoadedImages() override;
+
+  lldb::pid_t GetProcessID() override;
+
+  bool IsAlive() override;
+
+protected:
+  llvm::Optional<unsigned long long>
+  GetGenericInteger(llvm::StringRef method_name);
+  Status GetStatusFromMethod(llvm::StringRef method_name);
+
+private:
+  // The lifetime is managed by the ScriptInterpreter
+  ScriptInterpreterPythonImpl &m_interpreter;
+  StructuredData::GenericSP m_object_instance_sp;
+};
+} // namespace lldb_private
+
+#endif // LLDB_ENABLE_PYTHON
+#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSPYTHONINTERFACE_H
diff --git a/src/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/src/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index f669e58..87edf77 100644
--- a/src/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/src/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -8,7 +8,7 @@
 
 #include "StructuredDataDarwinLog.h"
 
-#include <string.h>
+#include <cstring>
 
 #include <memory>
 #include <sstream>
@@ -126,7 +126,7 @@
     m_collection_sp->Initialize(g_darwinlog_properties);
   }
 
-  ~StructuredDataDarwinLogProperties() override {}
+  ~StructuredDataDarwinLogProperties() override = default;
 
   bool GetEnableOnStartup() const {
     const uint32_t idx = ePropertyEnableOnStartup;
@@ -181,7 +181,7 @@
 
 class FilterRule {
 public:
-  virtual ~FilterRule() {}
+  virtual ~FilterRule() = default;
 
   using OperationCreationFunc =
       std::function<FilterRuleSP(bool accept, size_t attribute_index,
@@ -473,13 +473,9 @@
 class EnableOptions : public Options {
 public:
   EnableOptions()
-      : Options(), m_include_debug_level(false), m_include_info_level(false),
-        m_include_any_process(false),
+      : Options(),
         m_filter_fall_through_accepts(DEFAULT_FILTER_FALLTHROUGH_ACCEPTS),
-        m_echo_to_stderr(false), m_display_timestamp_relative(false),
-        m_display_subsystem(false), m_display_category(false),
-        m_display_activity_chain(false), m_broadcast_events(true),
-        m_live_stream(true), m_filter_rules() {}
+        m_filter_rules() {}
 
   void OptionParsingStarting(ExecutionContext *execution_context) override {
     m_include_debug_level = false;
@@ -728,17 +724,17 @@
     return -1;
   }
 
-  bool m_include_debug_level;
-  bool m_include_info_level;
-  bool m_include_any_process;
+  bool m_include_debug_level = false;
+  bool m_include_info_level = false;
+  bool m_include_any_process = false;
   bool m_filter_fall_through_accepts;
-  bool m_echo_to_stderr;
-  bool m_display_timestamp_relative;
-  bool m_display_subsystem;
-  bool m_display_category;
-  bool m_display_activity_chain;
-  bool m_broadcast_events;
-  bool m_live_stream;
+  bool m_echo_to_stderr = false;
+  bool m_display_timestamp_relative = false;
+  bool m_display_subsystem = false;
+  bool m_display_category = false;
+  bool m_display_activity_chain = false;
+  bool m_broadcast_events = true;
+  bool m_live_stream = true;
   FilterRules m_filter_rules;
 };
 
@@ -813,7 +809,6 @@
                        StructuredDataDarwinLog::GetStaticPluginName())) {
       result.AppendError("failed to get StructuredDataPlugin for "
                          "the process");
-      result.SetStatus(eReturnStatusFailed);
     }
     StructuredDataDarwinLog &plugin =
         *static_cast<StructuredDataDarwinLog *>(plugin_sp.get());
@@ -837,7 +832,6 @@
     // Report results.
     if (!error.Success()) {
       result.AppendError(error.AsCString());
-      result.SetStatus(eReturnStatusFailed);
       // Our configuration failed, so we're definitely disabled.
       plugin.SetEnabled(false);
     } else {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index 07e5b28..b815ebb 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -278,7 +278,7 @@
 }
 
 uint32_t SymbolFileBreakpad::ResolveSymbolContext(
-    const FileSpec &file_spec, uint32_t line, bool check_inlines,
+    const SourceLocationSpec &src_location_spec,
     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
   if (!(resolve_scope & eSymbolContextCompUnit))
@@ -287,8 +287,7 @@
   uint32_t old_size = sc_list.GetSize();
   for (size_t i = 0, size = GetNumCompileUnits(); i < size; ++i) {
     CompileUnit &cu = *GetCompileUnitAtIndex(i);
-    cu.ResolveSymbolContext(file_spec, line, check_inlines,
-                            /*exact*/ false, resolve_scope, sc_list);
+    cu.ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
   }
   return sc_list.GetSize() - old_size;
 }
@@ -716,10 +715,10 @@
   llvm::Optional<addr_t> next_addr;
   auto finish_sequence = [&]() {
     LineTable::AppendLineEntryToSequence(
-        line_seq_up.get(), *next_addr, /*line*/ 0, /*column*/ 0,
-        /*file_idx*/ 0, /*is_start_of_statement*/ false,
-        /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
-        /*is_epilogue_begin*/ false, /*is_terminal_entry*/ true);
+        line_seq_up.get(), *next_addr, /*line=*/0, /*column=*/0,
+        /*file_idx=*/0, /*is_start_of_statement=*/false,
+        /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false,
+        /*is_epilogue_begin=*/false, /*is_terminal_entry=*/true);
     sequences.push_back(std::move(line_seq_up));
     line_seq_up = LineTable::CreateLineSequenceContainer();
   };
@@ -739,10 +738,10 @@
       finish_sequence();
     }
     LineTable::AppendLineEntryToSequence(
-        line_seq_up.get(), record->Address, record->LineNum, /*column*/ 0,
-        map[record->FileNum], /*is_start_of_statement*/ true,
-        /*is_start_of_basic_block*/ false, /*is_prologue_end*/ false,
-        /*is_epilogue_begin*/ false, /*is_terminal_entry*/ false);
+        line_seq_up.get(), record->Address, record->LineNum, /*column=*/0,
+        map[record->FileNum], /*is_start_of_statement=*/true,
+        /*is_start_of_basic_block=*/false, /*is_prologue_end=*/false,
+        /*is_epilogue_begin=*/false, /*is_terminal_entry=*/false);
     next_addr = record->Address + record->Size;
   }
   if (next_addr)
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 90dbcc7..b0a35fa 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -51,7 +51,7 @@
   SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp)
       : SymbolFile(std::move(objfile_sp)) {}
 
-  ~SymbolFileBreakpad() override {}
+  ~SymbolFileBreakpad() override = default;
 
   uint32_t CalculateAbilities() override;
 
@@ -101,8 +101,7 @@
                                 lldb::SymbolContextItem resolve_scope,
                                 SymbolContext &sc) override;
 
-  uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
-                                bool check_inlines,
+  uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
                                 lldb::SymbolContextItem resolve_scope,
                                 SymbolContextList &sc_list) override;
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 2e0a7fd..ffe2483 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -24,7 +24,7 @@
 
 class DWARFASTParser {
 public:
-  virtual ~DWARFASTParser() {}
+  virtual ~DWARFASTParser() = default;
 
   virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
                                           const DWARFDIE &die,
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 188a667..46015f7b 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <stdlib.h>
+#include <cstdlib>
 
 #include "DWARFASTParserClang.h"
 #include "DWARFDebugInfo.h"
@@ -49,7 +49,7 @@
 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
 
 #ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
 #else
 #define DEBUG_PRINTF(fmt, ...)
@@ -60,7 +60,7 @@
 DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast)
     : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
 
-DWARFASTParserClang::~DWARFASTParserClang() {}
+DWARFASTParserClang::~DWARFASTParserClang() = default;
 
 static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) {
   switch (dwarf_accessibility) {
@@ -157,7 +157,7 @@
 
   // The type in the Clang module must have the same language as the current CU.
   LanguageSet languages;
-  languages.Insert(SymbolFileDWARF::GetLanguage(*die.GetCU()));
+  languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
   llvm::DenseSet<SymbolFile *> searched_symbol_files;
   clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
                                               searched_symbol_files, pcm_types);
@@ -666,8 +666,7 @@
         // Blocks have a __FuncPtr inside them which is a pointer to a
         // function of the proper type.
 
-        for (DWARFDIE child_die = target_die.GetFirstChild();
-             child_die.IsValid(); child_die = child_die.GetSibling()) {
+        for (DWARFDIE child_die : target_die.children()) {
           if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
                       "__FuncPtr")) {
             DWARFDIE function_pointer_type =
@@ -1226,6 +1225,7 @@
       }
 
       if (!function_decl) {
+        char *name_buf = nullptr;
         llvm::StringRef name = attrs.name.GetStringRef();
 
         // We currently generate function templates with template parameters in
@@ -1233,8 +1233,10 @@
         // we want to strip these from the name when creating the AST.
         if (attrs.mangled_name) {
           llvm::ItaniumPartialDemangler D;
-          if (!D.partialDemangle(attrs.mangled_name))
-            name = D.getFunctionBaseName(nullptr, nullptr);
+          if (!D.partialDemangle(attrs.mangled_name)) {
+            name_buf = D.getFunctionBaseName(nullptr, nullptr);
+            name = name_buf;
+          }
         }
 
         // We just have a function that isn't part of a class
@@ -1243,6 +1245,7 @@
                                       : containing_decl_ctx,
             GetOwningClangModule(die), name, clang_type, attrs.storage,
             attrs.is_inline);
+        std::free(name_buf);
 
         if (has_template_params) {
           TypeSystemClang::TemplateParameterInfos template_param_infos;
@@ -1266,13 +1269,10 @@
           LinkDeclContextToDIE(function_decl, die);
 
           if (!function_param_decls.empty()) {
-            m_ast.SetFunctionParameters(function_decl,
-                                        &function_param_decls.front(),
-                                        function_param_decls.size());
+            m_ast.SetFunctionParameters(function_decl, function_param_decls);
             if (template_function_decl)
               m_ast.SetFunctionParameters(template_function_decl,
-                                          &function_param_decls.front(),
-                                          function_param_decls.size());
+                                          function_param_decls);
           }
 
           ClangASTMetadata metadata;
@@ -1357,7 +1357,7 @@
       dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
 
   CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
-  CompilerType class_clang_type = class_type->GetLayoutCompilerType();
+  CompilerType class_clang_type = class_type->GetForwardCompilerType();
 
   CompilerType clang_type = TypeSystemClang::CreateMemberPointerType(
       class_clang_type, pointee_clang_type);
@@ -1684,14 +1684,18 @@
             die.GetOffset(), attrs.name.GetCString());
       }
 
-      if (tag == DW_TAG_structure_type) // this only applies in C
-      {
+      // If the byte size of the record is specified then overwrite the size
+      // that would be computed by Clang. This is only needed as LLDB's
+      // TypeSystemClang is always in C++ mode, but some compilers such as
+      // GCC and Clang give empty structs a size of 0 in C mode (in contrast to
+      // the size of 1 for empty structs that would be computed in C++ mode).
+      if (attrs.byte_size) {
         clang::RecordDecl *record_decl =
             TypeSystemClang::GetAsRecordDecl(clang_type);
-
         if (record_decl) {
-          GetClangASTImporter().SetRecordLayout(
-              record_decl, ClangASTImporter::LayoutInfo());
+          ClangASTImporter::LayoutInfo layout;
+          layout.bit_size = *attrs.byte_size * 8;
+          GetClangASTImporter().SetRecordLayout(record_decl, layout);
         }
       }
     } else if (clang_type_was_created) {
@@ -1822,8 +1826,7 @@
   case DW_TAG_GNU_template_parameter_pack: {
     template_param_infos.packed_args =
         std::make_unique<TypeSystemClang::TemplateParameterInfos>();
-    for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
-         child_die = child_die.GetSibling()) {
+    for (DWARFDIE child_die : die.children()) {
       if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
         return false;
     }
@@ -1928,8 +1931,7 @@
   if (!parent_die)
     return false;
 
-  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
-       die = die.GetSibling()) {
+  for (DWARFDIE die : parent_die.children()) {
     const dw_tag_t tag = die.Tag();
 
     switch (tag) {
@@ -1978,15 +1980,12 @@
     }
 
     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
-    std::vector<int> member_accessibilities;
-    bool is_a_class = false;
     // Parse members and base classes first
     std::vector<DWARFDIE> member_function_dies;
 
     DelayedPropertyList delayed_properties;
-    ParseChildMembers(die, clang_type, bases, member_accessibilities,
-                      member_function_dies, delayed_properties,
-                      default_accessibility, is_a_class, layout_info);
+    ParseChildMembers(die, clang_type, bases, member_function_dies,
+                      delayed_properties, default_accessibility, layout_info);
 
     // Now parse any methods if there were any...
     for (const DWARFDIE &die : member_function_dies)
@@ -2007,31 +2006,6 @@
       }
     }
 
-    // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
-    // need to tell the clang type it is actually a class.
-    if (!type_is_objc_object_or_interface) {
-      if (is_a_class && tag_decl_kind != clang::TTK_Class)
-        m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
-                             clang::TTK_Class);
-    }
-
-    // Since DW_TAG_structure_type gets used for both classes and
-    // structures, we may need to set any DW_TAG_member fields to have a
-    // "private" access if none was specified. When we parsed the child
-    // members we tracked that actual accessibility value for each
-    // DW_TAG_member in the "member_accessibilities" array. If the value
-    // for the member is zero, then it was set to the
-    // "default_accessibility" which for structs was "public". Below we
-    // correct this by setting any fields to "private" that weren't
-    // correctly set.
-    if (is_a_class && !member_accessibilities.empty()) {
-      // This is a class and all members that didn't have their access
-      // specified are private.
-      m_ast.SetDefaultAccessForRecordFields(
-          m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
-          &member_accessibilities.front(), member_accessibilities.size());
-    }
-
     if (!bases.empty()) {
       // Make sure all base classes refer to complete types and not forward
       // declarations. If we don't do this, clang will crash with an
@@ -2131,8 +2105,7 @@
   for (auto it = m_decl_ctx_to_die.find(opaque_decl_ctx);
        it != m_decl_ctx_to_die.end() && it->first == opaque_decl_ctx;
        it = m_decl_ctx_to_die.erase(it))
-    for (DWARFDIE decl = it->second.GetFirstChild(); decl;
-         decl = decl.GetSibling())
+    for (DWARFDIE decl : it->second.children())
       GetClangDeclForDIE(decl);
 }
 
@@ -2168,8 +2141,7 @@
 
   size_t enumerators_added = 0;
 
-  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
-       die = die.GetSibling()) {
+  for (DWARFDIE die : parent_die.children()) {
     const dw_tag_t tag = die.Tag();
     if (tag == DW_TAG_enumerator) {
       DWARFAttributes attributes;
@@ -2201,7 +2173,8 @@
             case DW_AT_description:
             default:
             case DW_AT_decl_file:
-              decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
+              decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile(
+                  form_value.Unsigned()));
               break;
             case DW_AT_decl_line:
               decl.SetLine(form_value.Unsigned());
@@ -2343,7 +2316,6 @@
 void DWARFASTParserClang::ParseSingleMember(
     const DWARFDIE &die, const DWARFDIE &parent_die,
     const lldb_private::CompilerType &class_clang_type,
-    std::vector<int> &member_accessibilities,
     lldb::AccessType default_accessibility,
     DelayedPropertyList &delayed_properties,
     lldb_private::ClangASTImporter::LayoutInfo &layout_info,
@@ -2533,7 +2505,7 @@
       if (accessibility == eAccessNone)
         accessibility = eAccessPublic;
       TypeSystemClang::AddVariableToRecordType(
-          class_clang_type, name, var_type->GetLayoutCompilerType(),
+          class_clang_type, name, var_type->GetForwardCompilerType(),
           accessibility);
     }
     return;
@@ -2551,7 +2523,6 @@
 
         if (accessibility == eAccessNone)
           accessibility = default_accessibility;
-        member_accessibilities.push_back(accessibility);
 
         uint64_t field_bit_offset =
             (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
@@ -2666,7 +2637,7 @@
           last_field_info.bit_offset = field_bit_offset;
 
           if (llvm::Optional<uint64_t> clang_type_size =
-                  member_clang_type.GetByteSize(nullptr)) {
+                  member_type->GetByteSize(nullptr)) {
             last_field_info.bit_size = *clang_type_size * character_width;
           }
 
@@ -2761,10 +2732,9 @@
 bool DWARFASTParserClang::ParseChildMembers(
     const DWARFDIE &parent_die, CompilerType &class_clang_type,
     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
-    std::vector<int> &member_accessibilities,
     std::vector<DWARFDIE> &member_function_dies,
     DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
-    bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
+    ClangASTImporter::LayoutInfo &layout_info) {
   if (!parent_die)
     return false;
 
@@ -2776,16 +2746,15 @@
   if (ast == nullptr)
     return false;
 
-  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
-       die = die.GetSibling()) {
+  for (DWARFDIE die : parent_die.children()) {
     dw_tag_t tag = die.Tag();
 
     switch (tag) {
     case DW_TAG_member:
     case DW_TAG_APPLE_property:
       ParseSingleMember(die, parent_die, class_clang_type,
-                        member_accessibilities, default_accessibility,
-                        delayed_properties, layout_info, last_field_info);
+                        default_accessibility, delayed_properties, layout_info,
+                        last_field_info);
       break;
 
     case DW_TAG_subprogram:
@@ -2794,9 +2763,6 @@
       break;
 
     case DW_TAG_inheritance: {
-      is_a_class = true;
-      if (default_accessibility == eAccessNone)
-        default_accessibility = eAccessPrivate;
       // TODO: implement DW_TAG_inheritance type parsing
       DWARFAttributes attributes;
       const size_t num_attributes = die.GetAttributes(attributes);
@@ -2926,8 +2892,7 @@
     return 0;
 
   size_t arg_idx = 0;
-  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
-       die = die.GetSibling()) {
+  for (DWARFDIE die : parent_die.children()) {
     const dw_tag_t tag = die.Tag();
     switch (tag) {
     case DW_TAG_formal_parameter: {
@@ -3046,8 +3011,7 @@
   if (!parent_die)
     return llvm::None;
 
-  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
-       die = die.GetSibling()) {
+  for (DWARFDIE die : parent_die.children()) {
     const dw_tag_t tag = die.Tag();
     if (tag != DW_TAG_subrange_type)
       continue;
@@ -3349,8 +3313,7 @@
 }
 
 static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
-  for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid();
-       candidate = candidate.GetSibling()) {
+  for (DWARFDIE candidate : context.children()) {
     if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
       return candidate;
     }
@@ -3514,8 +3477,7 @@
   UniqueCStringMap<DWARFDIE> dst_name_to_die;
   UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
   UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
-  for (src_die = src_class_die.GetFirstChild(); src_die.IsValid();
-       src_die = src_die.GetSibling()) {
+  for (DWARFDIE src_die : src_class_die.children()) {
     if (src_die.Tag() == DW_TAG_subprogram) {
       // Make sure this is a declaration and not a concrete instance by looking
       // for DW_AT_declaration set to 1. Sometimes concrete function instances
@@ -3533,8 +3495,7 @@
       }
     }
   }
-  for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
-       dst_die = dst_die.GetSibling()) {
+  for (DWARFDIE dst_die : dst_class_die.children()) {
     if (dst_die.Tag() == DW_TAG_subprogram) {
       // Make sure this is a declaration and not a concrete instance by looking
       // for DW_AT_declaration set to 1. Sometimes concrete function instances
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index e13716b..9bf6240 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -111,10 +111,9 @@
   bool ParseChildMembers(
       const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
       std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
-      std::vector<int> &member_accessibilities,
       std::vector<DWARFDIE> &member_function_dies,
       DelayedPropertyList &delayed_properties,
-      lldb::AccessType &default_accessibility, bool &is_a_class,
+      lldb::AccessType &default_accessibility,
       lldb_private::ClangASTImporter::LayoutInfo &layout_info);
 
   size_t
@@ -194,7 +193,6 @@
   void
   ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
                     const lldb_private::CompilerType &class_clang_type,
-                    std::vector<int> &member_accessibilities,
                     lldb::AccessType default_accessibility,
                     DelayedPropertyList &delayed_properties,
                     lldb_private::ClangASTImporter::LayoutInfo &layout_info,
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index 0e9370b..2f6b36c 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -17,9 +17,7 @@
 
 using namespace lldb_private;
 
-DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration()
-    : m_code(InvalidCode), m_tag(llvm::dwarf::DW_TAG_null), m_has_children(0),
-      m_attributes() {}
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : m_attributes() {}
 
 DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag,
                                                            uint8_t has_children)
@@ -58,7 +56,7 @@
     DWARFFormValue::ValueType val;
 
     if (form == DW_FORM_implicit_const)
-      val.value.sval = data.GetULEB128(offset_ptr);
+      val.value.sval = data.GetSLEB128(offset_ptr);
 
     m_attributes.push_back(DWARFAttribute(attr, form, val));
   }
@@ -82,9 +80,3 @@
   }
   return DW_INVALID_INDEX;
 }
-
-bool DWARFAbbreviationDeclaration::
-operator==(const DWARFAbbreviationDeclaration &rhs) const {
-  return Tag() == rhs.Tag() && HasChildren() == rhs.HasChildren() &&
-         m_attributes == rhs.m_attributes;
-}
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index f70aa71..378ba88 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -53,12 +53,11 @@
   extract(const lldb_private::DWARFDataExtractor &data,
           lldb::offset_t *offset_ptr);
   bool IsValid();
-  bool operator==(const DWARFAbbreviationDeclaration &rhs) const;
 
 protected:
-  dw_uleb128_t m_code;
-  dw_tag_t m_tag;
-  uint8_t m_has_children;
+  dw_uleb128_t m_code = InvalidCode;
+  dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
+  uint8_t m_has_children = 0;
   DWARFAttribute::collection m_attributes;
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index ef98d7e..134f6b2 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -12,7 +12,7 @@
 
 DWARFAttributes::DWARFAttributes() : m_infos() {}
 
-DWARFAttributes::~DWARFAttributes() {}
+DWARFAttributes::~DWARFAttributes() = default;
 
 uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
   collection::const_iterator end = m_infos.end();
@@ -25,10 +25,11 @@
   return UINT32_MAX;
 }
 
-void DWARFAttributes::Append(DWARFUnit *cu, dw_offset_t attr_die_offset,
-                             dw_attr_t attr, dw_form_t form) {
-  AttributeValue attr_value = {
-      cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}};
+void DWARFAttributes::Append(const DWARFFormValue &form_value,
+                             dw_offset_t attr_die_offset, dw_attr_t attr) {
+  AttributeValue attr_value = {const_cast<DWARFUnit *>(form_value.GetUnit()),
+                               attr_die_offset,
+                               {attr, form_value.Form(), form_value.Value()}};
   m_infos.push_back(attr_value);
 }
 
@@ -37,6 +38,10 @@
   const DWARFUnit *cu = CompileUnitAtIndex(i);
   form_value.SetUnit(cu);
   form_value.SetForm(FormAtIndex(i));
+  if (form_value.Form() == DW_FORM_implicit_const) {
+    form_value.SetValue(ValueAtIndex(i));
+    return true;
+  }
   lldb::offset_t offset = DIEOffsetAtIndex(i);
   return form_value.ExtractValue(cu->GetData(), &offset);
 }
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index 8c21404..a31ee86 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -22,21 +22,15 @@
                  DWARFFormValue::ValueType value)
       : m_attr(attr), m_form(form), m_value(value) {}
 
-  void set(dw_attr_t attr, dw_form_t form) {
-    m_attr = attr;
-    m_form = form;
-  }
   dw_attr_t get_attr() const { return m_attr; }
   dw_form_t get_form() const { return m_form; }
+  DWARFFormValue::ValueType get_value() const { return m_value; }
   void get(dw_attr_t &attr, dw_form_t &form,
            DWARFFormValue::ValueType &val) const {
     attr = m_attr;
     form = m_form;
     val = m_value;
   }
-  bool operator==(const DWARFAttribute &rhs) const {
-    return m_attr == rhs.m_attr && m_form == rhs.m_form;
-  }
   typedef std::vector<DWARFAttribute> collection;
   typedef collection::iterator iterator;
   typedef collection::const_iterator const_iterator;
@@ -52,8 +46,8 @@
   DWARFAttributes();
   ~DWARFAttributes();
 
-  void Append(DWARFUnit *cu, dw_offset_t attr_die_offset, dw_attr_t attr,
-              dw_form_t form);
+  void Append(const DWARFFormValue &form_value, dw_offset_t attr_die_offset,
+              dw_attr_t attr);
   DWARFUnit *CompileUnitAtIndex(uint32_t i) const { return m_infos[i].cu; }
   dw_offset_t DIEOffsetAtIndex(uint32_t i) const {
     return m_infos[i].die_offset;
@@ -62,6 +56,9 @@
     return m_infos[i].attr.get_attr();
   }
   dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); }
+  DWARFFormValue::ValueType ValueAtIndex(uint32_t i) const {
+    return m_infos[i].attr.get_value();
+  }
   bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
   DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const;
   DWARFDIE FormValueAsReference(dw_attr_t attr) const;
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 059b8486..36df980 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -24,7 +24,7 @@
 
 class DWARFBaseDIE {
 public:
-  DWARFBaseDIE() : m_cu(nullptr), m_die(nullptr) {}
+  DWARFBaseDIE() = default;
 
   DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
       : m_cu(cu), m_die(die) {}
@@ -115,8 +115,8 @@
                        Recurse recurse = Recurse::yes) const;
 
 protected:
-  DWARFUnit *m_cu;
-  DWARFDebugInfoEntry *m_die;
+  DWARFUnit *m_cu = nullptr;
+  DWARFDebugInfoEntry *m_die = nullptr;
 };
 
 bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 8e995e6..dda691e 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -54,7 +54,7 @@
   explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {}
 
   /// End marker
-  ElaboratingDIEIterator() {}
+  ElaboratingDIEIterator() = default;
 
   const DWARFDIE &operator*() const { return m_worklist.back(); }
   ElaboratingDIEIterator &operator++() {
@@ -192,7 +192,7 @@
   }
 
   if (check_children) {
-    for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) {
+    for (DWARFDIE child : children()) {
       if (DWARFDIE child_result = child.LookupDeepestBlock(address))
         return child_result;
     }
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 1373728..5615405 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -11,9 +11,11 @@
 
 #include "DWARFBaseDIE.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/iterator_range.h"
 
 class DWARFDIE : public DWARFBaseDIE {
 public:
+  class child_iterator;
   using DWARFBaseDIE::DWARFBaseDIE;
 
   // Tests
@@ -88,6 +90,47 @@
                             int &decl_line, int &decl_column, int &call_file,
                             int &call_line, int &call_column,
                             lldb_private::DWARFExpression *frame_base) const;
+  /// The range of all the children of this DIE.
+  ///
+  /// This is a template just because child_iterator is not completely defined
+  /// at this point.
+  template <typename T = child_iterator>
+  llvm::iterator_range<T> children() const {
+    return llvm::make_range(T(*this), T());
+  }
+};
+
+class DWARFDIE::child_iterator
+    : public llvm::iterator_facade_base<DWARFDIE::child_iterator,
+                                        std::forward_iterator_tag, DWARFDIE> {
+  /// The current child or an invalid DWARFDie.
+  DWARFDIE m_die;
+
+public:
+  child_iterator() = default;
+  child_iterator(const DWARFDIE &parent) : m_die(parent.GetFirstChild()) {}
+  bool operator==(const child_iterator &it) const {
+    // DWARFDIE's operator== differentiates between an invalid DWARFDIE that
+    // has a CU but no DIE and one that has neither CU nor DIE. The 'end'
+    // iterator could be default constructed, so explicitly allow
+    // (CU, (DIE)nullptr) == (nullptr, nullptr) -> true
+    if (!m_die.IsValid() && !it.m_die.IsValid())
+      return true;
+    return m_die == it.m_die;
+  }
+  const DWARFDIE &operator*() const {
+    assert(m_die.IsValid() && "Derefencing invalid iterator?");
+    return m_die;
+  }
+  DWARFDIE &operator*() {
+    assert(m_die.IsValid() && "Derefencing invalid iterator?");
+    return m_die;
+  }
+  child_iterator &operator++() {
+    assert(m_die.IsValid() && "Incrementing invalid iterator?");
+    m_die = m_die.GetSibling();
+    return *this;
+  }
 };
 
 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDIE_H
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 555864f..ec6b93c 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -26,8 +26,7 @@
 
 class DWARFAbbreviationDeclarationSet {
 public:
-  DWARFAbbreviationDeclarationSet()
-      : m_offset(DW_INVALID_OFFSET), m_idx_offset(0), m_decls() {}
+  DWARFAbbreviationDeclarationSet() : m_offset(DW_INVALID_OFFSET), m_decls() {}
 
   DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset)
       : m_offset(offset), m_idx_offset(idx_offset), m_decls() {}
@@ -51,7 +50,7 @@
   /// @}
 private:
   dw_offset_t m_offset;
-  uint32_t m_idx_offset;
+  uint32_t m_idx_offset = 0;
   std::vector<DWARFAbbreviationDeclaration> m_decls;
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
index 728cefe..ce51438 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -8,22 +8,18 @@
 
 #include "DWARFDebugArangeSet.h"
 #include "DWARFDataExtractor.h"
+#include "LogChannelDWARF.h"
 #include "llvm/Object/Error.h"
 #include <cassert>
 
 using namespace lldb_private;
 
 DWARFDebugArangeSet::DWARFDebugArangeSet()
-    : m_offset(DW_INVALID_OFFSET), m_header(), m_arange_descriptors() {
-  m_header.length = 0;
-  m_header.version = 0;
-  m_header.cu_offset = 0;
-  m_header.addr_size = 0;
-  m_header.seg_size = 0;
-}
+    : m_offset(DW_INVALID_OFFSET), m_next_offset(DW_INVALID_OFFSET) {}
 
 void DWARFDebugArangeSet::Clear() {
   m_offset = DW_INVALID_OFFSET;
+  m_next_offset = DW_INVALID_OFFSET;
   m_header.length = 0;
   m_header.version = 0;
   m_header.cu_offset = 0;
@@ -54,6 +50,12 @@
   // consists of an address and a length, each in the size appropriate for an
   // address on the target architecture.
   m_header.length = data.GetDWARFInitialLength(offset_ptr);
+  // The length could be 4 bytes or 12 bytes, so use the current offset to
+  // determine the next offset correctly.
+  if (m_header.length > 0)
+    m_next_offset = *offset_ptr + m_header.length;
+  else
+    m_next_offset = DW_INVALID_OFFSET;
   m_header.version = data.GetU16(offset_ptr);
   m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
   m_header.addr_size = data.GetU8(offset_ptr);
@@ -105,17 +107,45 @@
                 "DWARFDebugArangeSet::Descriptor.address and "
                 "DWARFDebugArangeSet::Descriptor.length must have same size");
 
-  while (data.ValidOffset(*offset_ptr)) {
+  const lldb::offset_t next_offset = GetNextOffset();
+  assert(next_offset != DW_INVALID_OFFSET);
+  uint32_t num_terminators = 0;
+  bool last_was_terminator = false;
+  while (*offset_ptr < next_offset) {
     arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size);
     arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size);
 
     // Each set of tuples is terminated by a 0 for the address and 0 for
-    // the length.
-    if (!arangeDescriptor.address && !arangeDescriptor.length)
-      return llvm::ErrorSuccess();
-
-    m_arange_descriptors.push_back(arangeDescriptor);
+    // the length. Some linkers can emit .debug_aranges with multiple
+    // terminator pair entries that are still withing the length of the
+    // DWARFDebugArangeSet. We want to be sure to parse all entries for
+    // this DWARFDebugArangeSet so that we don't stop parsing early and end up
+    // treating addresses as a header of the next DWARFDebugArangeSet. We also
+    // need to make sure we parse all valid address pairs so we don't omit them
+    // from the aranges result, so we can't stop at the first terminator entry
+    // we find.
+    if (arangeDescriptor.address == 0 && arangeDescriptor.length == 0) {
+      ++num_terminators;
+      last_was_terminator = true;
+    } else {
+      last_was_terminator = false;
+      // Only add .debug_aranges address entries that have a non zero size.
+      // Some linkers will zero out the length field for some .debug_aranges
+      // entries if they were stripped. We also could watch out for multiple
+      // entries at address zero and remove those as well.
+      if (arangeDescriptor.length > 0)
+        m_arange_descriptors.push_back(arangeDescriptor);
+    }
   }
+  if (num_terminators > 1) {
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+    LLDB_LOG(log,
+             "warning: DWARFDebugArangeSet at %#" PRIx64 " contains %u "
+             "terminator entries",
+             m_offset, num_terminators);
+  }
+  if (last_was_terminator)
+    return llvm::ErrorSuccess();
 
   return llvm::make_error<llvm::object::GenericBinaryError>(
       "arange descriptors not terminated by null entry");
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
index 6b5b69a..3c8633e 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -16,18 +16,21 @@
 class DWARFDebugArangeSet {
 public:
   struct Header {
-    uint32_t length;    // The total length of the entries for that set, not
-                        // including the length field itself.
-    uint16_t version;   // The DWARF version number
-    uint32_t cu_offset; // The offset from the beginning of the .debug_info
-                        // section of the compilation unit entry referenced by
-                        // the table.
-    uint8_t addr_size;  // The size in bytes of an address on the target
-                        // architecture. For segmented addressing, this is the
-                        // size of the offset portion of the address
-    uint8_t seg_size; // The size in bytes of a segment descriptor on the target
-                      // architecture. If the target system uses a flat address
-                      // space, this value is 0.
+    /// The total length of the entries for that set, not including the length
+    /// field itself.
+    uint32_t length = 0;
+    /// The DWARF version number.
+    uint16_t version = 0;
+    /// The offset from the beginning of the .debug_info section of the
+    /// compilation unit entry referenced by the table.
+    uint32_t cu_offset = 0;
+    /// The size in bytes of an address on the target architecture. For
+    /// segmented addressing, this is the size of the offset portion of the
+    /// address.
+    uint8_t addr_size = 0;
+    /// The size in bytes of a segment descriptor on the target architecture.
+    /// If the target system uses a flat address space, this value is 0.
+    uint8_t seg_size = 0;
   };
 
   struct Descriptor {
@@ -44,7 +47,7 @@
   dw_offset_t FindAddress(dw_addr_t address) const;
   size_t NumDescriptors() const { return m_arange_descriptors.size(); }
   const Header &GetHeader() const { return m_header; }
-
+  dw_offset_t GetNextOffset() const { return m_next_offset; }
   const Descriptor &GetDescriptorRef(uint32_t i) const {
     return m_arange_descriptors[i];
   }
@@ -54,7 +57,8 @@
   typedef DescriptorColl::iterator DescriptorIter;
   typedef DescriptorColl::const_iterator DescriptorConstIter;
 
-  uint32_t m_offset;
+  dw_offset_t m_offset;
+  dw_offset_t m_next_offset;
   Header m_header;
   DescriptorColl m_arange_descriptors;
 };
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
index 9f190fb..65923cb 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -9,6 +9,7 @@
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugArangeSet.h"
 #include "DWARFUnit.h"
+#include "LogChannelDWARF.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Timer.h"
 
@@ -31,31 +32,40 @@
 };
 
 // Extract
-llvm::Error
-DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
+void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
   lldb::offset_t offset = 0;
 
   DWARFDebugArangeSet set;
   Range range;
   while (debug_aranges_data.ValidOffset(offset)) {
-    llvm::Error error = set.extract(debug_aranges_data, &offset);
-    if (error)
-      return error;
+    const lldb::offset_t set_offset = offset;
+    if (llvm::Error error = set.extract(debug_aranges_data, &offset)) {
+      Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+      LLDB_LOG_ERROR(log, std::move(error),
+                     "DWARFDebugAranges::extract failed to extract "
+                     ".debug_aranges set at offset %#" PRIx64,
+                     set_offset);
+    } else {
+      const uint32_t num_descriptors = set.NumDescriptors();
+      if (num_descriptors > 0) {
+        const dw_offset_t cu_offset = set.GetHeader().cu_offset;
 
-    const uint32_t num_descriptors = set.NumDescriptors();
-    if (num_descriptors > 0) {
-      const dw_offset_t cu_offset = set.GetHeader().cu_offset;
-
-      for (uint32_t i = 0; i < num_descriptors; ++i) {
-        const DWARFDebugArangeSet::Descriptor &descriptor =
-            set.GetDescriptorRef(i);
-        m_aranges.Append(RangeToDIE::Entry(descriptor.address,
-                                           descriptor.length, cu_offset));
+        for (uint32_t i = 0; i < num_descriptors; ++i) {
+          const DWARFDebugArangeSet::Descriptor &descriptor =
+              set.GetDescriptorRef(i);
+          m_aranges.Append(RangeToDIE::Entry(descriptor.address,
+                                             descriptor.length, cu_offset));
+        }
       }
     }
+    // Always use the previous DWARFDebugArangeSet's information to calculate
+    // the offset of the next DWARFDebugArangeSet in case we entouncter an
+    // error in the current DWARFDebugArangeSet and our offset position is
+    // still in the middle of the data. If we do this, we can parse all valid
+    // DWARFDebugArangeSet objects without returning invalid errors.
+    offset = set.GetNextOffset();
     set.Clear();
   }
-  return llvm::ErrorSuccess();
 }
 
 void DWARFDebugAranges::Dump(Log *log) const {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index 96e8261..5ff37e4 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -26,8 +26,7 @@
 
   void Clear() { m_aranges.Clear(); }
 
-  llvm::Error
-  extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
+  void extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
 
   // Use append range multiple times and then call sort
   void AppendRange(dw_offset_t cu_offset, dw_addr_t low_pc, dw_addr_t high_pc);
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 8d393b2..e43afa1 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -34,17 +34,18 @@
                                lldb_private::DWARFContext &context)
     : m_dwarf(dwarf), m_context(context), m_units(), m_cu_aranges_up() {}
 
-llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
+const DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
   if (m_cu_aranges_up)
     return *m_cu_aranges_up;
 
   m_cu_aranges_up = std::make_unique<DWARFDebugAranges>();
   const DWARFDataExtractor &debug_aranges_data =
       m_context.getOrLoadArangesData();
-  if (llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data))
-    return std::move(error);
 
-  // Make a list of all CUs represented by the arange data in the file.
+  // Extract what we can from the .debug_aranges first.
+  m_cu_aranges_up->extract(debug_aranges_data);
+
+  // Make a list of all CUs represented by the .debug_aranges data.
   std::set<dw_offset_t> cus_with_data;
   for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) {
     dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n);
@@ -52,8 +53,7 @@
       cus_with_data.insert(offset);
   }
 
-  // Manually build arange data for everything that wasn't in the
-  // .debug_aranges table.
+  // Manually build arange data for everything that wasn't in .debug_aranges.
   const size_t num_units = GetNumUnits();
   for (size_t idx = 0; idx < num_units; ++idx) {
     DWARFUnit *cu = GetUnitAtIndex(idx);
@@ -72,16 +72,10 @@
   DWARFDataExtractor data = section == DIERef::Section::DebugTypes
                                 ? m_context.getOrLoadDebugTypesData()
                                 : m_context.getOrLoadDebugInfoData();
-  const llvm::DWARFUnitIndex *index = nullptr;
-  if (m_context.isDwo())
-    index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
-                                     section == DIERef::Section::DebugTypes
-                                         ? llvm::DW_SECT_EXT_TYPES
-                                         : llvm::DW_SECT_INFO);
   lldb::offset_t offset = 0;
   while (data.ValidOffset(offset)) {
     llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
-        m_dwarf, m_units.size(), data, section, &offset, index);
+        m_dwarf, m_units.size(), data, section, &offset);
 
     if (!unit_sp) {
       // FIXME: Propagate this error up.
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index bdc718a..46c04d7 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -54,7 +54,7 @@
         (1 << 2) // Show all parent DIEs when dumping single DIEs
   };
 
-  llvm::Expected<DWARFDebugAranges &> GetCompileUnitAranges();
+  const DWARFDebugAranges &GetCompileUnitAranges();
 
 protected:
   typedef std::vector<DWARFUnitSP> UnitColl;
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 4212988..39915aa 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -8,7 +8,7 @@
 
 #include "DWARFDebugInfoEntry.h"
 
-#include <assert.h>
+#include <cassert>
 
 #include <algorithm>
 
@@ -49,156 +49,159 @@
   // assert (fixed_form_sizes);  // For best performance this should be
   // specified!
 
-  if (m_abbr_idx) {
-    lldb::offset_t offset = *offset_ptr;
-    const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
-    if (abbrevDecl == nullptr) {
-      cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
-          "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
-          "attach the file at the start of this error message",
-          m_offset, (unsigned)abbr_idx);
-      // WE can't parse anymore if the DWARF is borked...
-      *offset_ptr = UINT32_MAX;
-      return false;
-    }
-    m_tag = abbrevDecl->Tag();
-    m_has_children = abbrevDecl->HasChildren();
-    // Skip all data in the .debug_info or .debug_types for the attributes
-    const uint32_t numAttributes = abbrevDecl->NumAttributes();
-    uint32_t i;
-    dw_form_t form;
-    for (i = 0; i < numAttributes; ++i) {
-      form = abbrevDecl->GetFormByIndexUnchecked(i);
-      llvm::Optional<uint8_t> fixed_skip_size =
-          DWARFFormValue::GetFixedSize(form, cu);
-      if (fixed_skip_size)
-        offset += *fixed_skip_size;
-      else {
-        bool form_is_indirect = false;
-        do {
-          form_is_indirect = false;
-          uint32_t form_size = 0;
-          switch (form) {
-          // Blocks if inlined data that have a length field and the data bytes
-          // inlined in the .debug_info/.debug_types
-          case DW_FORM_exprloc:
-          case DW_FORM_block:
-            form_size = data.GetULEB128(&offset);
-            break;
-          case DW_FORM_block1:
-            form_size = data.GetU8_unchecked(&offset);
-            break;
-          case DW_FORM_block2:
-            form_size = data.GetU16_unchecked(&offset);
-            break;
-          case DW_FORM_block4:
-            form_size = data.GetU32_unchecked(&offset);
-            break;
-
-          // Inlined NULL terminated C-strings
-          case DW_FORM_string:
-            data.GetCStr(&offset);
-            break;
-
-          // Compile unit address sized values
-          case DW_FORM_addr:
-            form_size = cu->GetAddressByteSize();
-            break;
-          case DW_FORM_ref_addr:
-            if (cu->GetVersion() <= 2)
-              form_size = cu->GetAddressByteSize();
-            else
-              form_size = 4;
-            break;
-
-          // 0 sized form
-          case DW_FORM_flag_present:
-            form_size = 0;
-            break;
-
-          // 1 byte values
-          case DW_FORM_addrx1:
-          case DW_FORM_data1:
-          case DW_FORM_flag:
-          case DW_FORM_ref1:
-          case DW_FORM_strx1:
-            form_size = 1;
-            break;
-
-          // 2 byte values
-          case DW_FORM_addrx2:
-          case DW_FORM_data2:
-          case DW_FORM_ref2:
-          case DW_FORM_strx2:
-            form_size = 2;
-            break;
-
-          // 3 byte values
-          case DW_FORM_addrx3:
-          case DW_FORM_strx3:
-            form_size = 3;
-            break;
-
-          // 4 byte values
-          case DW_FORM_addrx4:
-          case DW_FORM_data4:
-          case DW_FORM_ref4:
-          case DW_FORM_strx4:
-            form_size = 4;
-            break;
-
-          // 8 byte values
-          case DW_FORM_data8:
-          case DW_FORM_ref8:
-          case DW_FORM_ref_sig8:
-            form_size = 8;
-            break;
-
-          // signed or unsigned LEB 128 values
-          case DW_FORM_addrx:
-          case DW_FORM_loclistx:
-          case DW_FORM_rnglistx:
-          case DW_FORM_sdata:
-          case DW_FORM_udata:
-          case DW_FORM_ref_udata:
-          case DW_FORM_GNU_addr_index:
-          case DW_FORM_GNU_str_index:
-          case DW_FORM_strx:
-            data.Skip_LEB128(&offset);
-            break;
-
-          case DW_FORM_indirect:
-            form_is_indirect = true;
-            form = data.GetULEB128(&offset);
-            break;
-
-          case DW_FORM_strp:
-          case DW_FORM_sec_offset:
-            data.GetU32(&offset);
-            break;
-
-          case DW_FORM_implicit_const:
-            form_size = 0;
-            break;
-
-          default:
-            *offset_ptr = m_offset;
-            return false;
-          }
-          offset += form_size;
-
-        } while (form_is_indirect);
-      }
-    }
-    *offset_ptr = offset;
-    return true;
-  } else {
+  if (m_abbr_idx == 0) {
     m_tag = llvm::dwarf::DW_TAG_null;
     m_has_children = false;
     return true; // NULL debug tag entry
   }
 
-  return false;
+  lldb::offset_t offset = *offset_ptr;
+  const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
+  if (abbrevDecl == nullptr) {
+    cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+        "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
+        "attach the file at the start of this error message",
+        m_offset, (unsigned)abbr_idx);
+    // WE can't parse anymore if the DWARF is borked...
+    *offset_ptr = UINT32_MAX;
+    return false;
+  }
+  m_tag = abbrevDecl->Tag();
+  m_has_children = abbrevDecl->HasChildren();
+  // Skip all data in the .debug_info or .debug_types for the attributes
+  const uint32_t numAttributes = abbrevDecl->NumAttributes();
+  uint32_t i;
+  dw_form_t form;
+  for (i = 0; i < numAttributes; ++i) {
+    form = abbrevDecl->GetFormByIndexUnchecked(i);
+    llvm::Optional<uint8_t> fixed_skip_size =
+        DWARFFormValue::GetFixedSize(form, cu);
+    if (fixed_skip_size)
+      offset += *fixed_skip_size;
+    else {
+      bool form_is_indirect = false;
+      do {
+        form_is_indirect = false;
+        uint32_t form_size = 0;
+        switch (form) {
+        // Blocks if inlined data that have a length field and the data bytes
+        // inlined in the .debug_info/.debug_types
+        case DW_FORM_exprloc:
+        case DW_FORM_block:
+          form_size = data.GetULEB128(&offset);
+          break;
+        case DW_FORM_block1:
+          form_size = data.GetU8_unchecked(&offset);
+          break;
+        case DW_FORM_block2:
+          form_size = data.GetU16_unchecked(&offset);
+          break;
+        case DW_FORM_block4:
+          form_size = data.GetU32_unchecked(&offset);
+          break;
+
+        // Inlined NULL terminated C-strings
+        case DW_FORM_string:
+          data.GetCStr(&offset);
+          break;
+
+        // Compile unit address sized values
+        case DW_FORM_addr:
+          form_size = cu->GetAddressByteSize();
+          break;
+        case DW_FORM_ref_addr:
+          if (cu->GetVersion() <= 2)
+            form_size = cu->GetAddressByteSize();
+          else
+            form_size = 4;
+          break;
+
+        // 0 sized form
+        case DW_FORM_flag_present:
+          form_size = 0;
+          break;
+
+        // 1 byte values
+        case DW_FORM_addrx1:
+        case DW_FORM_data1:
+        case DW_FORM_flag:
+        case DW_FORM_ref1:
+        case DW_FORM_strx1:
+          form_size = 1;
+          break;
+
+        // 2 byte values
+        case DW_FORM_addrx2:
+        case DW_FORM_data2:
+        case DW_FORM_ref2:
+        case DW_FORM_strx2:
+          form_size = 2;
+          break;
+
+        // 3 byte values
+        case DW_FORM_addrx3:
+        case DW_FORM_strx3:
+          form_size = 3;
+          break;
+
+        // 4 byte values
+        case DW_FORM_addrx4:
+        case DW_FORM_data4:
+        case DW_FORM_ref4:
+        case DW_FORM_strx4:
+          form_size = 4;
+          break;
+
+        // 8 byte values
+        case DW_FORM_data8:
+        case DW_FORM_ref8:
+        case DW_FORM_ref_sig8:
+          form_size = 8;
+          break;
+
+        // signed or unsigned LEB 128 values
+        case DW_FORM_addrx:
+        case DW_FORM_loclistx:
+        case DW_FORM_rnglistx:
+        case DW_FORM_sdata:
+        case DW_FORM_udata:
+        case DW_FORM_ref_udata:
+        case DW_FORM_GNU_addr_index:
+        case DW_FORM_GNU_str_index:
+        case DW_FORM_strx:
+          data.Skip_LEB128(&offset);
+          break;
+
+        case DW_FORM_indirect:
+          form_is_indirect = true;
+          form = data.GetULEB128(&offset);
+          break;
+
+        case DW_FORM_strp:
+        case DW_FORM_line_strp:
+        case DW_FORM_sec_offset:
+          data.GetU32(&offset);
+          break;
+
+        case DW_FORM_implicit_const:
+          form_size = 0;
+          break;
+
+        default:
+          cu->GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+              "{0x%8.8x}: Unsupported DW_FORM_0x%x, please file a bug and "
+              "attach the file at the start of this error message",
+              m_offset, (unsigned)form);
+          *offset_ptr = m_offset;
+          return false;
+        }
+        offset += form_size;
+
+      } while (form_is_indirect);
+    }
+  }
+  *offset_ptr = offset;
+  return true;
 }
 
 static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
@@ -211,11 +214,12 @@
   if (expected_ranges)
     return std::move(*expected_ranges);
   unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
-      "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
+      "{0x%8.8x}: DIE has DW_AT_ranges(%s 0x%" PRIx64 ") attribute, but "
       "range extraction failed (%s), please file a bug "
       "and attach the file at the start of this error message",
-      die.GetOffset(), value.Unsigned(),
-      toString(expected_ranges.takeError()).c_str());
+      die.GetOffset(),
+      llvm::dwarf::FormEncodingString(value.Form()).str().c_str(),
+      value.Unsigned(), toString(expected_ranges.takeError()).c_str());
   return DWARFRangeList();
 }
 
@@ -429,7 +433,7 @@
         }
         LLVM_FALLTHROUGH;
       default:
-        attributes.Append(cu, offset, attr, form);
+        attributes.Append(form_value, offset, attr);
         break;
       }
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 0ba56a0..64e86c7 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -35,8 +35,7 @@
   typedef collection::const_iterator const_iterator;
 
   DWARFDebugInfoEntry()
-      : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
-        m_has_children(false), m_abbr_idx(0), m_tag(llvm::dwarf::DW_TAG_null) {}
+      : m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {}
 
   explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
   bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -167,14 +166,14 @@
   GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
 
   dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
-  uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
-                         // If zero this die has no parent
+  uint32_t m_parent_idx = 0;   // How many to subtract from "this" to get the
+                               // parent. If zero this die has no parent
   uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
       // If it is zero, then the DIE doesn't have children, or the
       // DWARF claimed it had children but the DIE only contained
       // a single NULL terminating child.
       m_has_children : 1;
-  uint16_t m_abbr_idx;
+  uint16_t m_abbr_idx = 0;
   /// A copy of the DW_TAG value so we don't have to go through the compile
   /// unit abbrev table
   dw_tag_t m_tag = llvm::dwarf::DW_TAG_null;
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 9072b2d..e466944 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -23,7 +23,7 @@
 class DWARFDeclContext {
 public:
   struct Entry {
-    Entry() : tag(llvm::dwarf::DW_TAG_null), name(nullptr) {}
+    Entry() = default;
     Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
 
     bool NameMatches(const Entry &rhs) const {
@@ -37,11 +37,11 @@
     // Test operator
     explicit operator bool() const { return tag != 0; }
 
-    dw_tag_t tag;
-    const char *name;
+    dw_tag_t tag = llvm::dwarf::DW_TAG_null;
+    const char *name = nullptr;
   };
 
-  DWARFDeclContext() : m_entries(), m_language(lldb::eLanguageTypeUnknown) {}
+  DWARFDeclContext() : m_entries() {}
 
   void AppendDeclContext(dw_tag_t tag, const char *name) {
     m_entries.push_back(Entry(tag, name));
@@ -83,7 +83,7 @@
   typedef std::vector<Entry> collection;
   collection m_entries;
   mutable std::string m_qualified_name;
-  lldb::LanguageType m_language;
+  lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index 1b7102c..2d0d5ca 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -10,7 +10,7 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEFINES_H
 
 #include "lldb/Core/dwarf.h"
-#include <stdint.h>
+#include <cstdint>
 
 namespace lldb_private {
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 305f1cb..4c49870 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include <assert.h>
+#include <cassert>
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/dwarf.h"
@@ -150,40 +150,40 @@
   uint8_t valid:1, size:7;
 };
 static FormSize g_form_sizes[] = {
-  {0,0}, // 0x00 unused
-  {0,0}, // 0x01 DW_FORM_addr
-  {0,0}, // 0x02 unused
-  {0,0}, // 0x03 DW_FORM_block2
-  {0,0}, // 0x04 DW_FORM_block4
-  {1,2}, // 0x05 DW_FORM_data2
-  {1,4}, // 0x06 DW_FORM_data4
-  {1,8}, // 0x07 DW_FORM_data8
-  {0,0}, // 0x08 DW_FORM_string
-  {0,0}, // 0x09 DW_FORM_block
-  {0,0}, // 0x0a DW_FORM_block1
-  {1,1}, // 0x0b DW_FORM_data1
-  {1,1}, // 0x0c DW_FORM_flag
-  {0,0}, // 0x0d DW_FORM_sdata
-  {1,4}, // 0x0e DW_FORM_strp
-  {0,0}, // 0x0f DW_FORM_udata
-  {0,0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes for
-         // DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
-  {1,1}, // 0x11 DW_FORM_ref1
-  {1,2}, // 0x12 DW_FORM_ref2
-  {1,4}, // 0x13 DW_FORM_ref4
-  {1,8}, // 0x14 DW_FORM_ref8
-  {0,0}, // 0x15 DW_FORM_ref_udata
-  {0,0}, // 0x16 DW_FORM_indirect
-  {1,4}, // 0x17 DW_FORM_sec_offset
-  {0,0}, // 0x18 DW_FORM_exprloc
-  {1,0}, // 0x19 DW_FORM_flag_present
-  {0,0}, // 0x1a
-  {0,0}, // 0x1b
-  {0,0}, // 0x1c
-  {0,0}, // 0x1d
-  {0,0}, // 0x1e
-  {0,0}, // 0x1f
-  {1,8}, // 0x20 DW_FORM_ref_sig8
+    {0, 0}, // 0x00 unused
+    {0, 0}, // 0x01 DW_FORM_addr
+    {0, 0}, // 0x02 unused
+    {0, 0}, // 0x03 DW_FORM_block2
+    {0, 0}, // 0x04 DW_FORM_block4
+    {1, 2}, // 0x05 DW_FORM_data2
+    {1, 4}, // 0x06 DW_FORM_data4
+    {1, 8}, // 0x07 DW_FORM_data8
+    {0, 0}, // 0x08 DW_FORM_string
+    {0, 0}, // 0x09 DW_FORM_block
+    {0, 0}, // 0x0a DW_FORM_block1
+    {1, 1}, // 0x0b DW_FORM_data1
+    {1, 1}, // 0x0c DW_FORM_flag
+    {0, 0}, // 0x0d DW_FORM_sdata
+    {1, 4}, // 0x0e DW_FORM_strp
+    {0, 0}, // 0x0f DW_FORM_udata
+    {0, 0}, // 0x10 DW_FORM_ref_addr (addr size for DWARF2 and earlier, 4 bytes
+            // for DWARF32, 8 bytes for DWARF32 in DWARF 3 and later
+    {1, 1},  // 0x11 DW_FORM_ref1
+    {1, 2},  // 0x12 DW_FORM_ref2
+    {1, 4},  // 0x13 DW_FORM_ref4
+    {1, 8},  // 0x14 DW_FORM_ref8
+    {0, 0},  // 0x15 DW_FORM_ref_udata
+    {0, 0},  // 0x16 DW_FORM_indirect
+    {1, 4},  // 0x17 DW_FORM_sec_offset
+    {0, 0},  // 0x18 DW_FORM_exprloc
+    {1, 0},  // 0x19 DW_FORM_flag_present
+    {0, 0},  // 0x1a DW_FORM_strx (ULEB128)
+    {0, 0},  // 0x1b DW_FORM_addrx (ULEB128)
+    {1, 4},  // 0x1c DW_FORM_ref_sup4
+    {0, 0},  // 0x1d DW_FORM_strp_sup (4 bytes for DWARF32, 8 bytes for DWARF64)
+    {1, 16}, // 0x1e DW_FORM_data16
+    {1, 4},  // 0x1f DW_FORM_line_strp
+    {1, 8},  // 0x20 DW_FORM_ref_sig8
 };
 
 llvm::Optional<uint8_t>
@@ -286,6 +286,7 @@
     // 32 bit for DWARF 32, 64 for DWARF 64
     case DW_FORM_sec_offset:
     case DW_FORM_strp:
+    case DW_FORM_line_strp:
       *offset_ptr += 4;
       return true;
 
@@ -398,7 +399,8 @@
   case DW_FORM_udata:
     s.PutULEB128(uvalue);
     break;
-  case DW_FORM_strp: {
+  case DW_FORM_strp:
+  case DW_FORM_line_strp: {
     const char *dbg_str = AsCString();
     if (dbg_str) {
       s.QuotedCString(dbg_str);
@@ -606,6 +608,7 @@
     case DW_FORM_flag:
     case DW_FORM_sdata:
     case DW_FORM_strp:
+    case DW_FORM_line_strp:
     case DW_FORM_strx:
     case DW_FORM_strx1:
     case DW_FORM_strx2:
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index fe6a555..9406bcf 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -10,8 +10,8 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFFORMVALUE_H
 
 #include "DWARFDataExtractor.h"
-#include <stddef.h>
 #include "llvm/ADT/Optional.h"
+#include <cstddef>
 
 class DWARFUnit;
 class SymbolFileDWARF;
@@ -20,14 +20,14 @@
 class DWARFFormValue {
 public:
   typedef struct ValueTypeTag {
-    ValueTypeTag() : value(), data(nullptr) { value.uval = 0; }
+    ValueTypeTag() : value() { value.uval = 0; }
 
     union {
       uint64_t uval;
       int64_t sval;
       const char *cstr;
     } value;
-    const uint8_t *data;
+    const uint8_t *data = nullptr;
   } ValueType;
 
   enum {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index a761dd3..824e438 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -236,6 +236,11 @@
   }
 
   if (!m_die_array.empty()) {
+    // The last die cannot have children (if it did, it wouldn't be the last one).
+    // This only makes a difference for malformed dwarf that does not have a
+    // terminating null die.
+    m_die_array.back().SetHasChildren(false);
+
     if (m_first_die) {
       // Only needed for the assertion.
       m_first_die.SetHasChildren(m_die_array.front().HasChildren());
@@ -292,8 +297,7 @@
 
 // m_die_array_mutex must be already held as read/write.
 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
-  llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base,
-      gnu_ranges_base;
+  llvm::Optional<uint64_t> addr_base, gnu_addr_base, gnu_ranges_base;
 
   DWARFAttributes attributes;
   size_t num_attributes = cu_die.GetAttributes(this, attributes);
@@ -320,8 +324,7 @@
       SetLoclistsBase(form_value.Unsigned());
       break;
     case DW_AT_rnglists_base:
-      ranges_base = form_value.Unsigned();
-      SetRangesBase(*ranges_base);
+      SetRangesBase(form_value.Unsigned());
       break;
     case DW_AT_str_offsets_base:
       SetStrOffsetsBase(form_value.Unsigned());
@@ -482,19 +485,46 @@
 }
 
 void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
+  lldbassert(!m_rnglist_table_done);
+
   m_ranges_base = ranges_base;
+}
 
-  if (GetVersion() < 5)
-    return;
+const llvm::Optional<llvm::DWARFDebugRnglistTable> &
+DWARFUnit::GetRnglistTable() {
+  if (GetVersion() >= 5 && !m_rnglist_table_done) {
+    m_rnglist_table_done = true;
+    if (auto table_or_error =
+            ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
+                m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
+                m_ranges_base, DWARF32))
+      m_rnglist_table = std::move(table_or_error.get());
+    else
+      GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+          "Failed to extract range list table at offset 0x%" PRIx64 ": %s",
+          m_ranges_base, toString(table_or_error.takeError()).c_str());
+  }
+  return m_rnglist_table;
+}
 
-  if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
-          m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
-          ranges_base, DWARF32))
-    m_rnglist_table = std::move(table_or_error.get());
-  else
-    GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
-        "Failed to extract range list table at offset 0x%" PRIx64 ": %s",
-        ranges_base, toString(table_or_error.takeError()).c_str());
+// This function is called only for DW_FORM_rnglistx.
+llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) {
+  if (!GetRnglistTable())
+    return llvm::createStringError(errc::invalid_argument,
+                                   "missing or invalid range list table");
+  if (!m_ranges_base)
+    return llvm::createStringError(errc::invalid_argument,
+                                   "DW_FORM_rnglistx cannot be used without "
+                                   "DW_AT_rnglists_base for CU at 0x%8.8x",
+                                   GetOffset());
+  if (llvm::Optional<uint64_t> off = GetRnglistTable()->getOffsetEntry(
+          m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index))
+    return *off + m_ranges_base;
+  return llvm::createStringError(
+      errc::invalid_argument,
+      "invalid range list table index %u; OffsetEntryCount is %u, "
+      "DW_AT_rnglists_base is %" PRIu64,
+      Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base);
 }
 
 void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
@@ -784,12 +814,11 @@
 
 llvm::Expected<DWARFUnitHeader>
 DWARFUnitHeader::extract(const DWARFDataExtractor &data,
-                         DIERef::Section section, lldb::offset_t *offset_ptr,
-                         const llvm::DWARFUnitIndex *index) {
+                         DIERef::Section section,
+                         lldb_private::DWARFContext &context,
+                         lldb::offset_t *offset_ptr) {
   DWARFUnitHeader header;
   header.m_offset = *offset_ptr;
-  if (index)
-    header.m_index_entry = index->getFromOffset(*offset_ptr);
   header.m_length = data.GetDWARFInitialLength(offset_ptr);
   header.m_version = data.GetU16(offset_ptr);
   if (header.m_version == 5) {
@@ -806,6 +835,16 @@
         section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
   }
 
+  if (context.isDwo()) {
+    if (header.IsTypeUnit()) {
+      header.m_index_entry =
+          context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset);
+    } else {
+      header.m_index_entry =
+          context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset);
+    }
+  }
+
   if (header.m_index_entry) {
     if (header.m_abbr_offset) {
       return llvm::createStringError(
@@ -856,12 +895,11 @@
 llvm::Expected<DWARFUnitSP>
 DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
                    const DWARFDataExtractor &debug_info,
-                   DIERef::Section section, lldb::offset_t *offset_ptr,
-                   const llvm::DWARFUnitIndex *index) {
+                   DIERef::Section section, lldb::offset_t *offset_ptr) {
   assert(debug_info.ValidOffset(*offset_ptr));
 
-  auto expected_header =
-      DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
+  auto expected_header = DWARFUnitHeader::extract(
+      debug_info, section, dwarf.GetDWARFContext(), offset_ptr);
   if (!expected_header)
     return expected_header.takeError();
 
@@ -930,11 +968,11 @@
     return ranges;
   }
 
-  if (!m_rnglist_table)
+  if (!GetRnglistTable())
     return llvm::createStringError(errc::invalid_argument,
                                    "missing or invalid range list table");
 
-  auto range_list_or_error = m_rnglist_table->findList(
+  auto range_list_or_error = GetRnglistTable()->findList(
       m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset);
   if (!range_list_or_error)
     return range_list_or_error.takeError();
@@ -963,12 +1001,8 @@
 
 llvm::Expected<DWARFRangeList>
 DWARFUnit::FindRnglistFromIndex(uint32_t index) {
-  if (llvm::Optional<uint64_t> offset = GetRnglistOffset(index))
-    return FindRnglistFromOffset(*offset);
-  if (m_rnglist_table)
-    return llvm::createStringError(errc::invalid_argument,
-                                   "invalid range list table index %d", index);
-
-  return llvm::createStringError(errc::invalid_argument,
-                                 "missing or invalid range list table");
+  llvm::Expected<uint64_t> maybe_offset = GetRnglistOffset(index);
+  if (!maybe_offset)
+    return maybe_offset.takeError();
+  return FindRnglistFromOffset(*maybe_offset);
 }
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 5739c36..da79a6a 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -73,7 +73,8 @@
 
   static llvm::Expected<DWARFUnitHeader>
   extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
-          lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
+          lldb_private::DWARFContext &dwarf_context,
+          lldb::offset_t *offset_ptr);
 };
 
 class DWARFUnit : public lldb_private::UserID {
@@ -84,8 +85,7 @@
   static llvm::Expected<DWARFUnitSP>
   extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
           const lldb_private::DWARFDataExtractor &debug_info,
-          DIERef::Section section, lldb::offset_t *offset_ptr,
-          const llvm::DWARFUnitIndex *index);
+          DIERef::Section section, lldb::offset_t *offset_ptr);
   virtual ~DWARFUnit();
 
   bool IsDWOUnit() { return m_is_dwo; }
@@ -235,15 +235,7 @@
   /// Return a rangelist's offset based on an index. The index designates
   /// an entry in the rangelist table's offset array and is supplied by
   /// DW_FORM_rnglistx.
-  llvm::Optional<uint64_t> GetRnglistOffset(uint32_t Index) const {
-    if (!m_rnglist_table)
-      return llvm::None;
-    if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry(
-            m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
-            Index))
-      return *off + m_ranges_base;
-    return llvm::None;
-  }
+  llvm::Expected<uint64_t> GetRnglistOffset(uint32_t Index);
 
   llvm::Optional<uint64_t> GetLoclistOffset(uint32_t Index) {
     if (!m_loclist_table_header)
@@ -291,6 +283,8 @@
     return &m_die_array[0];
   }
 
+  const llvm::Optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable();
+
   SymbolFileDWARF &m_dwarf;
   std::shared_ptr<DWARFUnit> m_dwo;
   DWARFUnitHeader m_header;
@@ -331,6 +325,7 @@
   dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
 
   llvm::Optional<llvm::DWARFDebugRnglistTable> m_rnglist_table;
+  bool m_rnglist_table_done = false;
   llvm::Optional<llvm::DWARFListTableHeader> m_loclist_table_header;
 
   const DIERef::Section m_section;
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index d36f2a8..ce71281 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -130,8 +130,7 @@
     : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {}
 
 DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset)
-    : die_base_offset(_die_base_offset), atoms(), atom_mask(0),
-      min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) {
+    : die_base_offset(_die_base_offset), atoms() {
   // Define an array of DIE offsets by first defining an array, and then define
   // the atom type for the array, in this case we have an array of DIE offsets.
   AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4);
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
index ad178fc..efc08e4 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -101,9 +101,9 @@
     /// DIE offset base so die offsets in hash_data can be CU relative.
     dw_offset_t die_base_offset;
     AtomArray atoms;
-    uint32_t atom_mask;
-    size_t min_hash_data_byte_size;
-    bool hash_data_has_fixed_byte_size;
+    uint32_t atom_mask = 0;
+    size_t min_hash_data_byte_size = 0;
+    bool hash_data_has_fixed_byte_size = true;
   };
 
   class Header : public MappedHash::Header<Prologue> {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
index dda599b..1f40d88 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -13,9 +13,11 @@
 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/Timer.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ThreadPool.h"
 
 using namespace lldb_private;
@@ -56,6 +58,17 @@
   if (units_to_index.empty())
     return;
 
+  StreamString module_desc;
+  m_module.GetDescription(module_desc.AsRawOstream(),
+                          lldb::eDescriptionLevelBrief);
+
+  // Include 2 passes per unit to index for extracting DIEs from the unit and
+  // indexing the unit, and then 8 extra entries for finalizing each index set.
+  const uint64_t total_progress = units_to_index.size() * 2 + 8;
+  Progress progress(
+      llvm::formatv("Manually indexing DWARF for {0}", module_desc.GetData()),
+      total_progress);
+
   std::vector<IndexSet> sets(units_to_index.size());
 
   // Keep memory down by clearing DIEs for any units if indexing
@@ -64,10 +77,12 @@
       units_to_index.size());
   auto parser_fn = [&](size_t cu_idx) {
     IndexUnit(*units_to_index[cu_idx], dwp_dwarf, sets[cu_idx]);
+    progress.Increment();
   };
 
-  auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
+  auto extract_fn = [&](size_t cu_idx) {
     clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
+    progress.Increment();
   };
 
   // Share one thread pool across operations to avoid the overhead of
@@ -92,11 +107,12 @@
     pool.async(parser_fn, i);
   pool.wait();
 
-  auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) {
+  auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) {
     NameToDIE &result = m_set.*index;
     for (auto &set : sets)
       result.Append(set.*index);
     result.Finalize();
+    progress.Increment();
   };
 
   pool.async(finalize_fn, &IndexSet::function_basenames);
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index 5aa841c..a6863f6 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -22,7 +22,7 @@
 public:
   NameToDIE() : m_map() {}
 
-  ~NameToDIE() {}
+  ~NameToDIE() = default;
 
   void Dump(lldb_private::Stream *s);
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 3656c73..ccaf313 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/Value.h"
@@ -74,18 +75,19 @@
 
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
 
 #include <algorithm>
 #include <map>
 #include <memory>
 
-#include <ctype.h>
-#include <string.h>
+#include <cctype>
+#include <cstring>
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
 
 #ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
+#include <cstdio>
 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
 #else
 #define DEBUG_PRINTF(fmt, ...)
@@ -238,9 +240,12 @@
   const size_t number_of_files = prologue.FileNames.size();
   for (size_t idx = first_file; idx <= number_of_files; ++idx) {
     std::string remapped_file;
-    if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style))
-      if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file))
+    if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) {
+      if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path)))
+        remapped_file = *remapped;
+      else
         remapped_file = std::move(*file_path);
+    }
 
     // Unconditionally add an entry, so the indices match up.
     support_files.EmplaceBack(remapped_file, style);
@@ -358,8 +363,7 @@
       }
     }
 
-    for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
-         child_die = child_die.GetSibling()) {
+    for (DWARFDIE child_die : die.children()) {
       GetTypes(child_die, min_die_offset, max_die_offset, type_mask, type_set);
     }
   }
@@ -435,7 +439,7 @@
       m_fetched_external_modules(false),
       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
 
-SymbolFileDWARF::~SymbolFileDWARF() {}
+SymbolFileDWARF::~SymbolFileDWARF() = default;
 
 static ConstString GetDWARFMachOSegmentName() {
   static ConstString g_dwarf_section_name("__DWARF");
@@ -467,22 +471,32 @@
   Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
 
   if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
+    StreamString module_desc;
+    GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
+                                                 lldb::eDescriptionLevelBrief);
     DWARFDataExtractor apple_names, apple_namespaces, apple_types, apple_objc;
     LoadSectionData(eSectionTypeDWARFAppleNames, apple_names);
     LoadSectionData(eSectionTypeDWARFAppleNamespaces, apple_namespaces);
     LoadSectionData(eSectionTypeDWARFAppleTypes, apple_types);
     LoadSectionData(eSectionTypeDWARFAppleObjC, apple_objc);
 
-    m_index = AppleDWARFIndex::Create(
-        *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
-        apple_types, apple_objc, m_context.getOrLoadStrData());
+    if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
+        apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
+      Progress progress(llvm::formatv("Loading Apple DWARF index for {0}",
+                                      module_desc.GetData()));
+      m_index = AppleDWARFIndex::Create(
+          *GetObjectFile()->GetModule(), apple_names, apple_namespaces,
+          apple_types, apple_objc, m_context.getOrLoadStrData());
 
-    if (m_index)
-      return;
+      if (m_index)
+        return;
+    }
 
     DWARFDataExtractor debug_names;
     LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
     if (debug_names.GetByteSize() > 0) {
+      Progress progress(
+          llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()));
       llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
           DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
                                        debug_names,
@@ -669,9 +683,8 @@
   // files are NFS mounted.
   file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
 
-  std::string remapped_file;
-  if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
-    file_spec.SetFile(remapped_file, FileSpec::Style::native);
+  if (auto remapped_file = module_sp->RemapSourceFile(file_spec.GetPath()))
+    file_spec.SetFile(*remapped_file, FileSpec::Style::native);
 }
 
 lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
@@ -973,8 +986,7 @@
   if (!die)
     return false;
 
-  for (DWARFDIE child_die = die.GetFirstChild(); child_die;
-       child_die = child_die.GetSibling()) {
+  for (DWARFDIE child_die : die.children()) {
     if (child_die.Tag() != DW_TAG_imported_declaration)
       continue;
 
@@ -1233,8 +1245,7 @@
 
 bool SymbolFileDWARF::ClassOrStructIsVirtual(const DWARFDIE &parent_die) {
   if (parent_die) {
-    for (DWARFDIE die = parent_die.GetFirstChild(); die;
-         die = die.GetSibling()) {
+    for (DWARFDIE die : parent_die.children()) {
       dw_tag_t tag = die.Tag();
       bool check_virtuality = false;
       switch (tag) {
@@ -1639,6 +1650,13 @@
       return nullptr;
 
     dwo_file.SetFile(comp_dir, FileSpec::Style::native);
+    if (dwo_file.IsRelative()) {
+      // if DW_AT_comp_dir is relative, it should be relative to the location
+      // of the executable, not to the location from which the debugger was
+      // launched.
+      dwo_file.PrependPathComponent(
+          m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+    }
     FileSystem::Instance().Resolve(dwo_file);
     dwo_file.AppendPathComponent(dwo_name);
   }
@@ -1784,7 +1802,7 @@
                 if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
                                       nullptr, location_result, &error)) {
                   if (location_result.GetValueType() ==
-                      Value::eValueTypeFileAddress) {
+                      Value::ValueType::FileAddress) {
                     lldb::addr_t file_addr =
                         location_result.GetScalar().ULongLong();
                     lldb::addr_t byte_size = 1;
@@ -1850,17 +1868,8 @@
     lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
 
     DWARFDebugInfo &debug_info = DebugInfo();
-    llvm::Expected<DWARFDebugAranges &> aranges =
-        debug_info.GetCompileUnitAranges();
-    if (!aranges) {
-      Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
-      LLDB_LOG_ERROR(log, aranges.takeError(),
-                     "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
-                     "aranges.  {0}");
-      return 0;
-    }
-
-    const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
+    const DWARFDebugAranges &aranges = debug_info.GetCompileUnitAranges();
+    const dw_offset_t cu_offset = aranges.FindAddress(file_vm_addr);
     if (cu_offset == DW_INVALID_OFFSET) {
       // Global variables are not in the compile unit address ranges. The only
       // way to currently find global variables is to iterate over the
@@ -1949,12 +1958,11 @@
   return resolved;
 }
 
-uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
-                                               uint32_t line,
-                                               bool check_inlines,
-                                               SymbolContextItem resolve_scope,
-                                               SymbolContextList &sc_list) {
+uint32_t SymbolFileDWARF::ResolveSymbolContext(
+    const SourceLocationSpec &src_location_spec,
+    SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+  const bool check_inlines = src_location_spec.GetCheckInlines();
   const uint32_t prev_size = sc_list.GetSize();
   if (resolve_scope & eSymbolContextCompUnit) {
     for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
@@ -1963,69 +1971,10 @@
       if (!dc_cu)
         continue;
 
-      bool file_spec_matches_cu_file_spec =
-          FileSpec::Match(file_spec, dc_cu->GetPrimaryFile());
+      bool file_spec_matches_cu_file_spec = FileSpec::Match(
+          src_location_spec.GetFileSpec(), dc_cu->GetPrimaryFile());
       if (check_inlines || file_spec_matches_cu_file_spec) {
-        SymbolContext sc(m_objfile_sp->GetModule());
-        sc.comp_unit = dc_cu;
-        uint32_t file_idx = UINT32_MAX;
-
-        // If we are looking for inline functions only and we don't find it
-        // in the support files, we are done.
-        if (check_inlines) {
-          file_idx =
-              sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true);
-          if (file_idx == UINT32_MAX)
-            continue;
-        }
-
-        if (line != 0) {
-          LineTable *line_table = sc.comp_unit->GetLineTable();
-
-          if (line_table != nullptr && line != 0) {
-            // We will have already looked up the file index if we are
-            // searching for inline entries.
-            if (!check_inlines)
-              file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
-                  1, file_spec, true);
-
-            if (file_idx != UINT32_MAX) {
-              uint32_t found_line;
-              uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
-                  0, file_idx, line, false, &sc.line_entry);
-              found_line = sc.line_entry.line;
-
-              while (line_idx != UINT32_MAX) {
-                sc.function = nullptr;
-                sc.block = nullptr;
-                if (resolve_scope &
-                    (eSymbolContextFunction | eSymbolContextBlock)) {
-                  const lldb::addr_t file_vm_addr =
-                      sc.line_entry.range.GetBaseAddress().GetFileAddress();
-                  if (file_vm_addr != LLDB_INVALID_ADDRESS) {
-                    ResolveFunctionAndBlock(
-                        file_vm_addr, resolve_scope & eSymbolContextBlock, sc);
-                  }
-                }
-
-                sc_list.Append(sc);
-                line_idx = line_table->FindLineEntryIndexByFileIndex(
-                    line_idx + 1, file_idx, found_line, true, &sc.line_entry);
-              }
-            }
-          } else if (file_spec_matches_cu_file_spec && !check_inlines) {
-            // only append the context if we aren't looking for inline call
-            // sites by file and line and if the file spec matches that of
-            // the compile unit
-            sc_list.Append(sc);
-          }
-        } else if (file_spec_matches_cu_file_spec && !check_inlines) {
-          // only append the context if we aren't looking for inline call
-          // sites by file and line and if the file spec matches that of
-          // the compile unit
-          sc_list.Append(sc);
-        }
-
+        dc_cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list);
         if (!check_inlines)
           break;
       }
@@ -2462,7 +2411,7 @@
     return;
 
   m_index->GetTypes(name, [&](DWARFDIE die) {
-    if (!languages[GetLanguage(*die.GetCU())])
+    if (!languages[GetLanguageFamily(*die.GetCU())])
       return true;
 
     llvm::SmallVector<CompilerContext, 4> die_context;
@@ -3126,8 +3075,8 @@
       continue;
     switch (attr) {
     case DW_AT_decl_file:
-      decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-          form_value.Unsigned()));
+      decl.SetFile(
+          attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned()));
       break;
     case DW_AT_decl_line:
       decl.SetLine(form_value.Unsigned());
@@ -3469,8 +3418,7 @@
     // Give the concrete function die specified by "func_die_offset", find the
     // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
     // to "spec_block_die_offset"
-    for (DWARFDIE child_die = die.GetFirstChild(); child_die;
-         child_die = child_die.GetSibling()) {
+    for (DWARFDIE child_die : die.children()) {
       DWARFDIE result_die =
           FindBlockContainingSpecification(child_die, spec_block_die_offset);
       if (result_die)
@@ -3599,8 +3547,7 @@
 static CallSiteParameterArray
 CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
   CallSiteParameterArray parameters;
-  for (DWARFDIE child = call_site_die.GetFirstChild(); child.IsValid();
-       child = child.GetSibling()) {
+  for (DWARFDIE child : call_site_die.children()) {
     if (child.Tag() != DW_TAG_call_site_parameter &&
         child.Tag() != DW_TAG_GNU_call_site_parameter)
       continue;
@@ -3665,8 +3612,7 @@
   // For now, assume that all entries are nested directly under the subprogram
   // (this is the kind of DWARF LLVM produces) and parse them eagerly.
   std::vector<std::unique_ptr<CallEdge>> call_edges;
-  for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid();
-       child = child.GetSibling()) {
+  for (DWARFDIE child : function_die.children()) {
     if (child.Tag() != DW_TAG_call_site && child.Tag() != DW_TAG_GNU_call_site)
       continue;
 
@@ -3842,7 +3788,7 @@
 }
 
 SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
-  if (m_debug_map_symfile == nullptr && !m_debug_map_module_wp.expired()) {
+  if (m_debug_map_symfile == nullptr) {
     lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
     if (module_sp) {
       m_debug_map_symfile =
@@ -3936,3 +3882,10 @@
 LanguageType SymbolFileDWARF::GetLanguage(DWARFUnit &unit) {
   return LanguageTypeFromDWARF(unit.GetDWARFLanguageType());
 }
+
+LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
+  auto lang = (llvm::dwarf::SourceLanguage)unit.GetDWARFLanguageType();
+  if (llvm::dwarf::isCPlusPlus(lang))
+    lang = DW_LANG_C_plus_plus;
+  return LanguageTypeFromDWARF(lang);
+}
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 019f76c..d9feeef 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -161,11 +161,10 @@
                                 lldb::SymbolContextItem resolve_scope,
                                 lldb_private::SymbolContext &sc) override;
 
-  uint32_t
-  ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
-                       bool check_inlines,
-                       lldb::SymbolContextItem resolve_scope,
-                       lldb_private::SymbolContextList &sc_list) override;
+  uint32_t ResolveSymbolContext(
+      const lldb_private::SourceLocationSpec &src_location_spec,
+      lldb::SymbolContextItem resolve_scope,
+      lldb_private::SymbolContextList &sc_list) override;
 
   void
   FindGlobalVariables(lldb_private::ConstString name,
@@ -318,6 +317,8 @@
   static lldb::LanguageType LanguageTypeFromDWARF(uint64_t val);
 
   static lldb::LanguageType GetLanguage(DWARFUnit &unit);
+  /// Same as GetLanguage() but reports all C++ versions as C++ (no version).
+  static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
 
 protected:
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index fa24f97..4e2e5e1 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -16,7 +16,6 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/Timer.h"
 
 //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
 #if defined(DEBUG_OSO_DMAP)
@@ -34,6 +33,9 @@
 #include "LogChannelDWARF.h"
 #include "SymbolFileDWARF.h"
 
+// Work around the fact that Timer.h pulls in the system Mach-O headers.
+#include "lldb/Utility/Timer.h"
+
 #include <memory>
 
 using namespace lldb;
@@ -246,7 +248,7 @@
       m_func_indexes(), m_glob_indexes(),
       m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
 
-SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
+SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default;
 
 void SymbolFileDWARFDebugMap::InitializeObject() {}
 
@@ -806,7 +808,7 @@
 }
 
 uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
-    const FileSpec &file_spec, uint32_t line, bool check_inlines,
+    const SourceLocationSpec &src_location_spec,
     SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
   const uint32_t initial = sc_list.GetSize();
@@ -815,18 +817,19 @@
   for (uint32_t i = 0; i < cu_count; ++i) {
     // If we are checking for inlines, then we need to look through all compile
     // units no matter if "file_spec" matches.
-    bool resolve = check_inlines;
+    bool resolve = src_location_spec.GetCheckInlines();
 
     if (!resolve) {
       FileSpec so_file_spec;
       if (GetFileSpecForSO(i, so_file_spec))
-        resolve = FileSpec::Match(file_spec, so_file_spec);
+        resolve =
+            FileSpec::Match(src_location_spec.GetFileSpec(), so_file_spec);
     }
     if (resolve) {
       SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
       if (oso_dwarf)
-        oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines,
-                                        resolve_scope, sc_list);
+        oso_dwarf->ResolveSymbolContext(src_location_spec, resolve_scope,
+                                        sc_list);
     }
   }
   return sc_list.GetSize() - initial;
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 06f0d48..8b6624e 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -97,11 +97,10 @@
   uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
                                 lldb::SymbolContextItem resolve_scope,
                                 lldb_private::SymbolContext &sc) override;
-  uint32_t
-  ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
-                       bool check_inlines,
-                       lldb::SymbolContextItem resolve_scope,
-                       lldb_private::SymbolContextList &sc_list) override;
+  uint32_t ResolveSymbolContext(
+      const lldb_private::SourceLocationSpec &src_location_spec,
+      lldb::SymbolContextItem resolve_scope,
+      lldb_private::SymbolContextList &sc_list) override;
   void
   FindGlobalVariables(lldb_private::ConstString name,
                       const lldb_private::CompilerDeclContext &parent_decl_ctx,
@@ -171,18 +170,17 @@
     llvm::sys::TimePoint<> oso_mod_time;
     OSOInfoSP oso_sp;
     lldb::CompUnitSP compile_unit_sp;
-    uint32_t first_symbol_index;
-    uint32_t last_symbol_index;
-    uint32_t first_symbol_id;
-    uint32_t last_symbol_id;
+    uint32_t first_symbol_index = UINT32_MAX;
+    uint32_t last_symbol_index = UINT32_MAX;
+    uint32_t first_symbol_id = UINT32_MAX;
+    uint32_t last_symbol_id = UINT32_MAX;
     FileRangeMap file_range_map;
-    bool file_range_map_valid;
+    bool file_range_map_valid = false;
 
     CompileUnitInfo()
         : so_file(), oso_path(), oso_mod_time(), oso_sp(), compile_unit_sp(),
-          first_symbol_index(UINT32_MAX), last_symbol_index(UINT32_MAX),
-          first_symbol_id(UINT32_MAX), last_symbol_id(UINT32_MAX),
-          file_range_map(), file_range_map_valid(false) {}
+
+          file_range_map() {}
 
     const FileRangeMap &GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
   };
@@ -280,8 +278,7 @@
   // OSOEntry
   class OSOEntry {
   public:
-    OSOEntry()
-        : m_exe_sym_idx(UINT32_MAX), m_oso_file_addr(LLDB_INVALID_ADDRESS) {}
+    OSOEntry() = default;
 
     OSOEntry(uint32_t exe_sym_idx, lldb::addr_t oso_file_addr)
         : m_exe_sym_idx(exe_sym_idx), m_oso_file_addr(oso_file_addr) {}
@@ -299,8 +296,8 @@
     }
 
   protected:
-    uint32_t m_exe_sym_idx;
-    lldb::addr_t m_oso_file_addr;
+    uint32_t m_exe_sym_idx = UINT32_MAX;
+    lldb::addr_t m_oso_file_addr = LLDB_INVALID_ADDRESS;
   };
 
   typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry>
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 2181989..34ff236 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -8,7 +8,7 @@
 
 #include "UniqueDWARFASTType.h"
 
-#include "lldb/Symbol/Declaration.h"
+#include "lldb/Core/Declaration.h"
 
 bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
                                   const lldb_private::Declaration &decl,
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index a1b1a30..0947d1e 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -14,16 +14,12 @@
 #include "llvm/ADT/DenseMap.h"
 
 #include "DWARFDIE.h"
-#include "lldb/Symbol/Declaration.h"
+#include "lldb/Core/Declaration.h"
 
 class UniqueDWARFASTType {
 public:
   // Constructors and Destructors
-  UniqueDWARFASTType()
-      : m_type_sp(), m_die(), m_declaration(),
-        m_byte_size(
-            -1) // Set to negative value to make sure we have a valid value
-  {}
+  UniqueDWARFASTType() : m_type_sp(), m_die(), m_declaration() {}
 
   UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
                      const lldb_private::Declaration &decl, int32_t byte_size)
@@ -34,7 +30,7 @@
       : m_type_sp(rhs.m_type_sp), m_die(rhs.m_die),
         m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
 
-  ~UniqueDWARFASTType() {}
+  ~UniqueDWARFASTType() = default;
 
   UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) {
     if (this != &rhs) {
@@ -49,14 +45,14 @@
   lldb::TypeSP m_type_sp;
   DWARFDIE m_die;
   lldb_private::Declaration m_declaration;
-  int32_t m_byte_size;
+  int32_t m_byte_size = -1;
 };
 
 class UniqueDWARFASTTypeList {
 public:
   UniqueDWARFASTTypeList() : m_collection() {}
 
-  ~UniqueDWARFASTTypeList() {}
+  ~UniqueDWARFASTTypeList() = default;
 
   uint32_t GetSize() { return (uint32_t)m_collection.size(); }
 
@@ -76,7 +72,7 @@
 public:
   UniqueDWARFASTTypeMap() : m_collection() {}
 
-  ~UniqueDWARFASTTypeMap() {}
+  ~UniqueDWARFASTTypeMap() = default;
 
   void Insert(lldb_private::ConstString name,
               const UniqueDWARFASTType &entry) {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
index f25dc84..9f09c0a 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -43,7 +43,7 @@
 
   llvm::SmallString<64> normalized(other);
   llvm::sys::path::native(normalized);
-  return main.equals_lower(normalized);
+  return main.equals_insensitive(normalized);
 }
 
 static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 5b4ab78..43cf262 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1093,7 +1093,7 @@
   }
 
   if (!params.empty())
-    m_clang.SetFunctionParameters(&function_decl, params.data(), params.size());
+    m_clang.SetFunctionParameters(&function_decl, params);
 }
 
 clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
index ecae767..4f570d5e 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -41,7 +41,7 @@
   auto it = llvm::find_if(
       register_names,
       [&reg_name](const llvm::EnumEntry<uint16_t> &register_entry) {
-        return reg_name.compare_lower(register_entry.Name) == 0;
+        return reg_name.compare_insensitive(register_entry.Name) == 0;
       });
 
   if (it == register_names.end())
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 24b4c64..b9b075d 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -256,7 +256,7 @@
 SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp)
     : SymbolFile(std::move(objfile_sp)) {}
 
-SymbolFileNativePDB::~SymbolFileNativePDB() {}
+SymbolFileNativePDB::~SymbolFileNativePDB() = default;
 
 uint32_t SymbolFileNativePDB::CalculateAbilities() {
   uint32_t abilities = 0;
@@ -1001,7 +1001,7 @@
 }
 
 uint32_t SymbolFileNativePDB::ResolveSymbolContext(
-    const FileSpec &file_spec, uint32_t line, bool check_inlines,
+    const SourceLocationSpec &src_location_spec,
     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
   return 0;
 }
@@ -1039,7 +1039,7 @@
   table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
                                   last_line, 0, file_number, false, false,
                                   false, false, true);
-  table.InsertSequence(seq.release());
+  table.InsertSequence(seq.get());
 }
 
 bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 61c1d77..def0995 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -120,8 +120,7 @@
   uint32_t ResolveSymbolContext(const Address &so_addr,
                                 lldb::SymbolContextItem resolve_scope,
                                 SymbolContext &sc) override;
-  uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
-                                bool check_inlines,
+  uint32_t ResolveSymbolContext(const SourceLocationSpec &src_location_spec,
                                 lldb::SymbolContextItem resolve_scope,
                                 SymbolContextList &sc_list) override;
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index f9c12e6..78a0d09 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -17,8 +17,8 @@
 #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
 #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Core/Declaration.h"
 #include "lldb/Core/Module.h"
-#include "lldb/Symbol/Declaration.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/TypeSystem.h"
@@ -326,7 +326,7 @@
   if (result.empty())
     return nullptr;
 
-  return result[0];
+  return *result.begin();
 }
 
 static bool IsAnonymousNamespaceName(llvm::StringRef name) {
@@ -355,7 +355,7 @@
 
 PDBASTParser::PDBASTParser(lldb_private::TypeSystemClang &ast) : m_ast(ast) {}
 
-PDBASTParser::~PDBASTParser() {}
+PDBASTParser::~PDBASTParser() = default;
 
 // DebugInfoASTParser interface
 
@@ -534,8 +534,12 @@
     auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
     assert(type_def);
 
+    SymbolFile *symbol_file = m_ast.GetSymbolFile();
+    if (!symbol_file)
+      return nullptr;
+
     lldb_private::Type *target_type =
-        m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+        symbol_file->ResolveTypeUID(type_def->getTypeId());
     if (!target_type)
       return nullptr;
 
@@ -609,8 +613,13 @@
       auto arg = arg_enum->getChildAtIndex(arg_idx);
       if (!arg)
         break;
+
+      SymbolFile *symbol_file = m_ast.GetSymbolFile();
+      if (!symbol_file)
+        return nullptr;
+
       lldb_private::Type *arg_type =
-          m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId());
+          symbol_file->ResolveTypeUID(arg->getSymIndexId());
       // If there's some error looking up one of the dependent types of this
       // function signature, bail.
       if (!arg_type)
@@ -621,8 +630,12 @@
     lldbassert(arg_list.size() <= num_args);
 
     auto pdb_return_type = func_sig->getReturnType();
+    SymbolFile *symbol_file = m_ast.GetSymbolFile();
+    if (!symbol_file)
+      return nullptr;
+
     lldb_private::Type *return_type =
-        m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId());
+        symbol_file->ResolveTypeUID(pdb_return_type->getSymIndexId());
     // If there's some error looking up one of the dependent types of this
     // function signature, bail.
     if (!return_type)
@@ -654,10 +667,13 @@
     if (uint64_t size = array_type->getLength())
       bytes = size;
 
+    SymbolFile *symbol_file = m_ast.GetSymbolFile();
+    if (!symbol_file)
+      return nullptr;
+
     // If array rank > 0, PDB gives the element type at N=0. So element type
     // will parsed in the order N=0, N=1,..., N=rank sequentially.
-    lldb_private::Type *element_type =
-        m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+    lldb_private::Type *element_type = symbol_file->ResolveTypeUID(element_uid);
     if (!element_type)
       return nullptr;
 
@@ -711,7 +727,12 @@
   case PDB_SymType::PointerType: {
     auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
     assert(pointer_type);
-    Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID(
+
+    SymbolFile *symbol_file = m_ast.GetSymbolFile();
+    if (!symbol_file)
+      return nullptr;
+
+    Type *pointee_type = symbol_file->ResolveTypeUID(
         pointer_type->getPointeeType()->getSymIndexId());
     if (!pointee_type)
       return nullptr;
@@ -719,8 +740,7 @@
     if (pointer_type->isPointerToDataMember() ||
         pointer_type->isPointerToMemberFunction()) {
       auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
-      auto class_parent_type =
-          m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid);
+      auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_uid);
       assert(class_parent_type);
 
       CompilerType pointer_ast_type;
@@ -950,7 +970,7 @@
       }
     }
     if (params.size())
-      m_ast.SetFunctionParameters(decl, params.data(), params.size());
+      m_ast.SetFunctionParameters(decl, params);
 
     m_uid_to_decl[sym_id] = decl;
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index befc081..6b30ad2 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -84,8 +84,10 @@
 static bool ShouldUseNativeReader() {
 #if defined(_WIN32)
   llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
-  return use_native.equals_lower("on") || use_native.equals_lower("yes") ||
-         use_native.equals_lower("1") || use_native.equals_lower("true");
+  return use_native.equals_insensitive("on") ||
+         use_native.equals_insensitive("yes") ||
+         use_native.equals_insensitive("1") ||
+         use_native.equals_insensitive("true");
 #else
   return true;
 #endif
@@ -128,7 +130,7 @@
 SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
     : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
 
-SymbolFilePDB::~SymbolFilePDB() {}
+SymbolFilePDB::~SymbolFilePDB() = default;
 
 uint32_t SymbolFilePDB::CalculateAbilities() {
   uint32_t abilities = 0;
@@ -784,10 +786,12 @@
 }
 
 uint32_t SymbolFilePDB::ResolveSymbolContext(
-    const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
+    const lldb_private::SourceLocationSpec &src_location_spec,
     SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
   const size_t old_size = sc_list.GetSize();
+  const FileSpec &file_spec = src_location_spec.GetFileSpec();
+  const uint32_t line = src_location_spec.GetLine().getValueOr(0);
   if (resolve_scope & lldb::eSymbolContextCompUnit) {
     // Locate all compilation units with line numbers referencing the specified
     // file.  For example, if `file_spec` is <vector>, then this should return
@@ -806,7 +810,7 @@
       // this file unless the FileSpec matches. For inline functions, we don't
       // have to match the FileSpec since they could be defined in headers
       // other than file specified in FileSpec.
-      if (!check_inlines) {
+      if (!src_location_spec.GetCheckInlines()) {
         std::string source_file = compiland->getSourceFileFullPath();
         if (source_file.empty())
           continue;
@@ -1813,7 +1817,7 @@
             sequence.get(), prev_addr + prev_length, prev_line, 0,
             prev_source_idx, false, false, false, false, true);
 
-        line_table->InsertSequence(sequence.release());
+        line_table->InsertSequence(sequence.get());
         sequence = line_table->CreateLineSequenceContainer();
       }
 
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 928cbff..2171b7f 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/src/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -104,11 +104,10 @@
                                 lldb::SymbolContextItem resolve_scope,
                                 lldb_private::SymbolContext &sc) override;
 
-  uint32_t
-  ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
-                       bool check_inlines,
-                       lldb::SymbolContextItem resolve_scope,
-                       lldb_private::SymbolContextList &sc_list) override;
+  uint32_t ResolveSymbolContext(
+      const lldb_private::SourceLocationSpec &src_location_spec,
+      lldb::SymbolContextItem resolve_scope,
+      lldb_private::SymbolContextList &sc_list) override;
 
   void
   FindGlobalVariables(lldb_private::ConstString name,
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/src/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index 4df5140..9130eed 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -8,7 +8,7 @@
 
 #include "SymbolVendorELF.h"
 
-#include <string.h>
+#include <cstring>
 
 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "lldb/Core/Module.h"
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/src/llvm-project/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index 605a35d..cd1aceb 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -8,7 +8,7 @@
 
 #include "SymbolVendorMacOSX.h"
 
-#include <string.h>
+#include <cstring>
 
 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "lldb/Core/Module.h"
diff --git a/src/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/src/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
index 67a1ef5..2b28407 100644
--- a/src/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
@@ -8,7 +8,7 @@
 
 #include "SymbolVendorWasm.h"
 
-#include <string.h>
+#include <cstring>
 
 #include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
 #include "lldb/Core/Module.h"
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index 989247b..7ece7f5 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -98,7 +98,7 @@
       m_get_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
       m_get_item_info_retbuffer_mutex() {}
 
-AppleGetItemInfoHandler::~AppleGetItemInfoHandler() {}
+AppleGetItemInfoHandler::~AppleGetItemInfoHandler() = default;
 
 void AppleGetItemInfoHandler::Detach() {
 
@@ -258,26 +258,26 @@
   CompilerType clang_void_ptr_type =
       clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
   Value return_buffer_ptr_value;
-  return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+  return_buffer_ptr_value.SetValueType(Value::ValueType::Scalar);
   return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
 
   CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
   Value debug_value;
-  debug_value.SetValueType(Value::eValueTypeScalar);
+  debug_value.SetValueType(Value::ValueType::Scalar);
   debug_value.SetCompilerType(clang_int_type);
 
   CompilerType clang_uint64_type =
       clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
   Value item_value;
-  item_value.SetValueType(Value::eValueTypeScalar);
+  item_value.SetValueType(Value::ValueType::Scalar);
   item_value.SetCompilerType(clang_uint64_type);
 
   Value page_to_free_value;
-  page_to_free_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_value.SetCompilerType(clang_void_ptr_type);
 
   Value page_to_free_size_value;
-  page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_size_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_size_value.SetCompilerType(clang_uint64_type);
 
   std::lock_guard<std::mutex> guard(m_get_item_info_retbuffer_mutex);
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
index f1119a9..04cfbae 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
@@ -46,13 +46,12 @@
   ~AppleGetItemInfoHandler();
 
   struct GetItemInfoReturnInfo {
-    lldb::addr_t item_buffer_ptr;  /* the address of the item buffer from
-                                      libBacktraceRecording */
-    lldb::addr_t item_buffer_size; /* the size of the item buffer from
+    lldb::addr_t item_buffer_ptr = LLDB_INVALID_ADDRESS; /* the address of the
+                                     item buffer from libBacktraceRecording */
+    lldb::addr_t item_buffer_size = 0; /* the size of the item buffer from
                                       libBacktraceRecording */
 
-    GetItemInfoReturnInfo()
-        : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+    GetItemInfoReturnInfo() = default;
   };
 
   /// Get the information about a work item by calling
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index 7bf158e..82b71b8 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -102,7 +102,7 @@
       m_get_pending_items_return_buffer_addr(LLDB_INVALID_ADDRESS),
       m_get_pending_items_retbuffer_mutex() {}
 
-AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler() {}
+AppleGetPendingItemsHandler::~AppleGetPendingItemsHandler() = default;
 
 void AppleGetPendingItemsHandler::Detach() {
   if (m_process && m_process->IsAlive() &&
@@ -261,26 +261,26 @@
   CompilerType clang_void_ptr_type =
       clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
   Value return_buffer_ptr_value;
-  return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+  return_buffer_ptr_value.SetValueType(Value::ValueType::Scalar);
   return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
 
   CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
   Value debug_value;
-  debug_value.SetValueType(Value::eValueTypeScalar);
+  debug_value.SetValueType(Value::ValueType::Scalar);
   debug_value.SetCompilerType(clang_int_type);
 
   CompilerType clang_uint64_type =
       clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
   Value queue_value;
-  queue_value.SetValueType(Value::eValueTypeScalar);
+  queue_value.SetValueType(Value::ValueType::Scalar);
   queue_value.SetCompilerType(clang_uint64_type);
 
   Value page_to_free_value;
-  page_to_free_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_value.SetCompilerType(clang_void_ptr_type);
 
   Value page_to_free_size_value;
-  page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_size_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_size_value.SetCompilerType(clang_uint64_type);
 
   std::lock_guard<std::mutex> guard(m_get_pending_items_retbuffer_mutex);
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
index 20895ca..fe02526 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
@@ -48,16 +48,14 @@
   ~AppleGetPendingItemsHandler();
 
   struct GetPendingItemsReturnInfo {
-    lldb::addr_t items_buffer_ptr; /* the address of the pending items buffer
-                                      from libBacktraceRecording */
-    lldb::addr_t
-        items_buffer_size; /* the size of the pending items buffer from
-                              libBacktraceRecording */
-    uint64_t count; /* the number of pending items included in the buffer */
+    lldb::addr_t items_buffer_ptr =
+        LLDB_INVALID_ADDRESS; /* the address of the pending items buffer
+          from libBacktraceRecording */
+    lldb::addr_t items_buffer_size = 0; /* the size of the pending items buffer
+                                       from libBacktraceRecording */
+    uint64_t count = 0; /* the number of pending items included in the buffer */
 
-    GetPendingItemsReturnInfo()
-        : items_buffer_ptr(LLDB_INVALID_ADDRESS), items_buffer_size(0),
-          count(0) {}
+    GetPendingItemsReturnInfo() = default;
   };
 
   /// Get the list of pending items for a given queue via a call to
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index 6e65211..f471871 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -99,7 +99,7 @@
       m_get_queues_return_buffer_addr(LLDB_INVALID_ADDRESS),
       m_get_queues_retbuffer_mutex() {}
 
-AppleGetQueuesHandler::~AppleGetQueuesHandler() {}
+AppleGetQueuesHandler::~AppleGetQueuesHandler() = default;
 
 void AppleGetQueuesHandler::Detach() {
 
@@ -264,22 +264,22 @@
   CompilerType clang_void_ptr_type =
       clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
   Value return_buffer_ptr_value;
-  return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+  return_buffer_ptr_value.SetValueType(Value::ValueType::Scalar);
   return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
 
   CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
   Value debug_value;
-  debug_value.SetValueType(Value::eValueTypeScalar);
+  debug_value.SetValueType(Value::ValueType::Scalar);
   debug_value.SetCompilerType(clang_int_type);
 
   Value page_to_free_value;
-  page_to_free_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_value.SetCompilerType(clang_void_ptr_type);
 
   CompilerType clang_uint64_type =
       clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
   Value page_to_free_size_value;
-  page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_size_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_size_value.SetCompilerType(clang_uint64_type);
 
   std::lock_guard<std::mutex> guard(m_get_queues_retbuffer_mutex);
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
index 0c828d7..b33e6186 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
@@ -45,15 +45,14 @@
   ~AppleGetQueuesHandler();
 
   struct GetQueuesReturnInfo {
-    lldb::addr_t queues_buffer_ptr;  /* the address of the queues buffer from
+    lldb::addr_t queues_buffer_ptr =
+        LLDB_INVALID_ADDRESS; /* the address of the queues buffer from
+          libBacktraceRecording */
+    lldb::addr_t queues_buffer_size = 0; /* the size of the queues buffer from
                                         libBacktraceRecording */
-    lldb::addr_t queues_buffer_size; /* the size of the queues buffer from
-                                        libBacktraceRecording */
-    uint64_t count; /* the number of queues included in the queues buffer */
+    uint64_t count = 0; /* the number of queues included in the queues buffer */
 
-    GetQueuesReturnInfo()
-        : queues_buffer_ptr(LLDB_INVALID_ADDRESS), queues_buffer_size(0),
-          count(0) {}
+    GetQueuesReturnInfo() = default;
   };
 
   /// Get the list of queues that exist (with any active or pending items) via
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index 77fb0be..7837dca 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -107,7 +107,7 @@
       m_get_thread_item_info_return_buffer_addr(LLDB_INVALID_ADDRESS),
       m_get_thread_item_info_retbuffer_mutex() {}
 
-AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() {}
+AppleGetThreadItemInfoHandler::~AppleGetThreadItemInfoHandler() = default;
 
 void AppleGetThreadItemInfoHandler::Detach() {
 
@@ -262,26 +262,26 @@
   CompilerType clang_void_ptr_type =
       clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
   Value return_buffer_ptr_value;
-  return_buffer_ptr_value.SetValueType(Value::eValueTypeScalar);
+  return_buffer_ptr_value.SetValueType(Value::ValueType::Scalar);
   return_buffer_ptr_value.SetCompilerType(clang_void_ptr_type);
 
   CompilerType clang_int_type = clang_ast_context->GetBasicType(eBasicTypeInt);
   Value debug_value;
-  debug_value.SetValueType(Value::eValueTypeScalar);
+  debug_value.SetValueType(Value::ValueType::Scalar);
   debug_value.SetCompilerType(clang_int_type);
 
   CompilerType clang_uint64_type =
       clang_ast_context->GetBasicType(eBasicTypeUnsignedLongLong);
   Value thread_id_value;
-  thread_id_value.SetValueType(Value::eValueTypeScalar);
+  thread_id_value.SetValueType(Value::ValueType::Scalar);
   thread_id_value.SetCompilerType(clang_uint64_type);
 
   Value page_to_free_value;
-  page_to_free_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_value.SetCompilerType(clang_void_ptr_type);
 
   Value page_to_free_size_value;
-  page_to_free_size_value.SetValueType(Value::eValueTypeScalar);
+  page_to_free_size_value.SetValueType(Value::ValueType::Scalar);
   page_to_free_size_value.SetCompilerType(clang_uint64_type);
 
   std::lock_guard<std::mutex> guard(m_get_thread_item_info_retbuffer_mutex);
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
index 0f7201a..9b2005f 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
@@ -47,13 +47,12 @@
   ~AppleGetThreadItemInfoHandler();
 
   struct GetThreadItemInfoReturnInfo {
-    lldb::addr_t item_buffer_ptr;  /* the address of the item buffer from
-                                      libBacktraceRecording */
-    lldb::addr_t item_buffer_size; /* the size of the item buffer from
+    lldb::addr_t item_buffer_ptr = LLDB_INVALID_ADDRESS; /* the address of the
+                                     item buffer from libBacktraceRecording */
+    lldb::addr_t item_buffer_size = 0; /* the size of the item buffer from
                                       libBacktraceRecording */
 
-    GetThreadItemInfoReturnInfo()
-        : item_buffer_ptr(LLDB_INVALID_ADDRESS), item_buffer_size(0) {}
+    GetThreadItemInfoReturnInfo() = default;
   };
 
   /// Get the information about a work item by calling
diff --git a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
index 844682e..877a2ad 100644
--- a/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
+++ b/src/llvm-project/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
@@ -108,14 +108,12 @@
 
 private:
   struct libBacktraceRecording_info {
-    uint16_t queue_info_version;
-    uint16_t queue_info_data_offset;
-    uint16_t item_info_version;
-    uint16_t item_info_data_offset;
+    uint16_t queue_info_version = 0;
+    uint16_t queue_info_data_offset = 0;
+    uint16_t item_info_version = 0;
+    uint16_t item_info_data_offset = 0;
 
-    libBacktraceRecording_info()
-        : queue_info_version(0), queue_info_data_offset(0),
-          item_info_version(0), item_info_data_offset(0) {}
+    libBacktraceRecording_info() = default;
   };
 
   // A structure which reflects the data recorded in the
@@ -186,44 +184,35 @@
   };
 
   struct LibdispatchVoucherOffsets {
-    uint16_t vo_version;
-    uint16_t vo_activity_ids_count;
-    uint16_t vo_activity_ids_count_size;
-    uint16_t vo_activity_ids_array;
-    uint16_t vo_activity_ids_array_entry_size;
+    uint16_t vo_version = UINT16_MAX;
+    uint16_t vo_activity_ids_count = UINT16_MAX;
+    uint16_t vo_activity_ids_count_size = UINT16_MAX;
+    uint16_t vo_activity_ids_array = UINT16_MAX;
+    uint16_t vo_activity_ids_array_entry_size = UINT16_MAX;
 
-    LibdispatchVoucherOffsets()
-        : vo_version(UINT16_MAX), vo_activity_ids_count(UINT16_MAX),
-          vo_activity_ids_count_size(UINT16_MAX),
-          vo_activity_ids_array(UINT16_MAX),
-          vo_activity_ids_array_entry_size(UINT16_MAX) {}
+    LibdispatchVoucherOffsets() = default;
 
     bool IsValid() { return vo_version != UINT16_MAX; }
   };
 
   struct LibdispatchTSDIndexes {
-    uint16_t dti_version;
-    uint64_t dti_queue_index;
-    uint64_t dti_voucher_index;
-    uint64_t dti_qos_class_index;
+    uint16_t dti_version = UINT16_MAX;
+    uint64_t dti_queue_index = UINT64_MAX;
+    uint64_t dti_voucher_index = UINT64_MAX;
+    uint64_t dti_qos_class_index = UINT64_MAX;
 
-    LibdispatchTSDIndexes()
-        : dti_version(UINT16_MAX), dti_queue_index(UINT64_MAX),
-          dti_voucher_index(UINT64_MAX), dti_qos_class_index(UINT64_MAX) {}
+    LibdispatchTSDIndexes() = default;
 
     bool IsValid() { return dti_version != UINT16_MAX; }
   };
 
   struct LibpthreadOffsets {
-    uint16_t plo_version;
-    uint16_t plo_pthread_tsd_base_offset;
-    uint16_t plo_pthread_tsd_base_address_offset;
-    uint16_t plo_pthread_tsd_entry_size;
+    uint16_t plo_version = UINT16_MAX;
+    uint16_t plo_pthread_tsd_base_offset = UINT16_MAX;
+    uint16_t plo_pthread_tsd_base_address_offset = UINT16_MAX;
+    uint16_t plo_pthread_tsd_entry_size = UINT16_MAX;
 
-    LibpthreadOffsets()
-        : plo_version(UINT16_MAX), plo_pthread_tsd_base_offset(UINT16_MAX),
-          plo_pthread_tsd_base_address_offset(UINT16_MAX),
-          plo_pthread_tsd_entry_size(UINT16_MAX) {}
+    LibpthreadOffsets() = default;
 
     bool IsValid() { return plo_version != UINT16_MAX; }
   };
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Trace/CMakeLists.txt
index edbb5f1..955f88c 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Trace/CMakeLists.txt
@@ -1,5 +1,7 @@
 option(LLDB_BUILD_INTEL_PT "Enable Building of Intel(R) Processor Trace Tool" OFF)
 
+add_subdirectory(common)
+
 if (LLDB_BUILD_INTEL_PT)
   add_subdirectory(intel-pt)
 endif()
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/common/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Trace/common/CMakeLists.txt
new file mode 100644
index 0000000..604ddb6
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/common/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_lldb_library(lldbPluginTraceCommon
+  ThreadPostMortemTrace.cpp
+  TraceSessionFileParser.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+  )
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp b/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp
new file mode 100644
index 0000000..45d6f3b
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.cpp
@@ -0,0 +1,41 @@
+//===-- ThreadPostMortemTrace.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 "ThreadPostMortemTrace.h"
+
+#include <memory>
+
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void ThreadPostMortemTrace::RefreshStateAfterStop() {}
+
+RegisterContextSP ThreadPostMortemTrace::GetRegisterContext() {
+  if (!m_reg_context_sp)
+    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+
+  return m_reg_context_sp;
+}
+
+RegisterContextSP
+ThreadPostMortemTrace::CreateRegisterContextForFrame(StackFrame *frame) {
+  // Eventually this will calculate the register context based on the current
+  // trace position.
+  return std::make_shared<RegisterContextHistory>(
+      *this, 0, GetProcess()->GetAddressByteSize(), LLDB_INVALID_ADDRESS);
+}
+
+bool ThreadPostMortemTrace::CalculateStopInfo() { return false; }
+
+const FileSpec &ThreadPostMortemTrace::GetTraceFile() const {
+  return m_trace_file;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h b/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h
new file mode 100644
index 0000000..9cfe754
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/common/ThreadPostMortemTrace.h
@@ -0,0 +1,60 @@
+//===-- ThreadPostMortemTrace.h ---------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_THREADPOSTMORTEMTRACE_H
+#define LLDB_TARGET_THREADPOSTMORTEMTRACE_H
+
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+/// \class ThreadPostMortemTrace ThreadPostMortemTrace.h
+///
+/// Thread implementation used for representing threads gotten from trace
+/// session files, which are similar to threads from core files.
+///
+/// See \a TraceSessionFileParser for more information regarding trace session
+/// files.
+class ThreadPostMortemTrace : public Thread {
+public:
+  /// \param[in] process
+  ///     The process who owns this thread.
+  ///
+  /// \param[in] tid
+  ///     The tid of this thread.
+  ///
+  /// \param[in] trace_file
+  ///     The file that contains the list of instructions that were traced when
+  ///     this thread was being executed.
+  ThreadPostMortemTrace(Process &process, lldb::tid_t tid,
+                        const FileSpec &trace_file)
+      : Thread(process, tid), m_trace_file(trace_file) {}
+
+  void RefreshStateAfterStop() override;
+
+  lldb::RegisterContextSP GetRegisterContext() override;
+
+  lldb::RegisterContextSP
+  CreateRegisterContextForFrame(StackFrame *frame) override;
+
+  /// \return
+  ///   The trace file of this thread.
+  const FileSpec &GetTraceFile() const;
+
+protected:
+  bool CalculateStopInfo() override;
+
+  lldb::RegisterContextSP m_thread_reg_ctx_sp;
+
+private:
+  FileSpec m_trace_file;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_THREADPOSTMORTEMTRACE_H
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp b/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
new file mode 100644
index 0000000..c88ad9d
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp
@@ -0,0 +1,224 @@
+//===-- TraceSessionFileParser.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 "TraceSessionFileParser.h"
+#include "ThreadPostMortemTrace.h"
+
+#include <sstream>
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+void TraceSessionFileParser::NormalizePath(lldb_private::FileSpec &file_spec) {
+  if (file_spec.IsRelative())
+    file_spec.PrependPathComponent(m_session_file_dir);
+}
+
+Error TraceSessionFileParser::ParseModule(lldb::TargetSP &target_sp,
+                                          const JSONModule &module) {
+  FileSpec system_file_spec(module.system_path);
+  NormalizePath(system_file_spec);
+
+  FileSpec local_file_spec(module.file.hasValue() ? *module.file
+                                                  : module.system_path);
+  NormalizePath(local_file_spec);
+
+  ModuleSpec module_spec;
+  module_spec.GetFileSpec() = local_file_spec;
+  module_spec.GetPlatformFileSpec() = system_file_spec;
+
+  if (module.uuid.hasValue())
+    module_spec.GetUUID().SetFromStringRef(*module.uuid);
+
+  Status error;
+  ModuleSP module_sp =
+      target_sp->GetOrCreateModule(module_spec, /*notify*/ false, &error);
+
+  if (error.Fail())
+    return error.ToError();
+
+  bool load_addr_changed = false;
+  module_sp->SetLoadAddress(*target_sp, module.load_address.value, false,
+                            load_addr_changed);
+  return llvm::Error::success();
+}
+
+Error TraceSessionFileParser::CreateJSONError(json::Path::Root &root,
+                                              const json::Value &value) {
+  std::string err;
+  raw_string_ostream os(err);
+  root.printErrorContext(value, os);
+  return createStringError(
+      std::errc::invalid_argument, "%s\n\nContext:\n%s\n\nSchema:\n%s",
+      toString(root.getError()).c_str(), os.str().c_str(), m_schema.data());
+}
+
+std::string TraceSessionFileParser::BuildSchema(StringRef plugin_schema) {
+  std::ostringstream schema_builder;
+  schema_builder << "{\n  \"trace\": ";
+  schema_builder << plugin_schema.data() << ",";
+  schema_builder << R"(
+  "processes": [
+    {
+      "pid": integer,
+      "triple": string, // llvm-triple
+      "threads": [
+        {
+          "tid": integer,
+          "traceFile": string
+        }
+      ],
+      "modules": [
+        {
+          "systemPath": string, // original path of the module at runtime
+          "file"?: string, // copy of the file if not available at "systemPath"
+          "loadAddress": string, // string address in hex or decimal form
+          "uuid"?: string,
+        }
+      ]
+    }
+  ]
+  // Notes:
+  // All paths are either absolute or relative to the session file.
+}
+)";
+  return schema_builder.str();
+}
+
+ThreadPostMortemTraceSP
+TraceSessionFileParser::ParseThread(ProcessSP &process_sp,
+                                    const JSONThread &thread) {
+  lldb::tid_t tid = static_cast<lldb::tid_t>(thread.tid);
+
+  FileSpec trace_file(thread.trace_file);
+  NormalizePath(trace_file);
+
+  ThreadPostMortemTraceSP thread_sp =
+      std::make_shared<ThreadPostMortemTrace>(*process_sp, tid, trace_file);
+  process_sp->GetThreadList().AddThread(thread_sp);
+  return thread_sp;
+}
+
+Expected<TraceSessionFileParser::ParsedProcess>
+TraceSessionFileParser::ParseProcess(const JSONProcess &process) {
+  TargetSP target_sp;
+  Status error = m_debugger.GetTargetList().CreateTarget(
+      m_debugger, /*user_exe_path*/ StringRef(), process.triple,
+      eLoadDependentsNo,
+      /*platform_options*/ nullptr, target_sp);
+
+  if (!target_sp)
+    return error.ToError();
+
+  ParsedProcess parsed_process;
+  parsed_process.target_sp = target_sp;
+
+  ProcessSP process_sp = target_sp->CreateProcess(
+      /*listener*/ nullptr, "trace",
+      /*crash_file*/ nullptr,
+      /*can_connect*/ false);
+
+  process_sp->SetID(static_cast<lldb::pid_t>(process.pid));
+
+  for (const JSONThread &thread : process.threads)
+    parsed_process.threads.push_back(ParseThread(process_sp, thread));
+
+  for (const JSONModule &module : process.modules)
+    if (Error err = ParseModule(target_sp, module))
+      return std::move(err);
+
+  if (!process.threads.empty())
+    process_sp->GetThreadList().SetSelectedThreadByIndexID(0);
+
+  // We invoke DidAttach to create a correct stopped state for the process and
+  // its threads.
+  ArchSpec process_arch;
+  process_sp->DidAttach(process_arch);
+
+  return parsed_process;
+}
+
+Expected<std::vector<TraceSessionFileParser::ParsedProcess>>
+TraceSessionFileParser::ParseCommonSessionFile(
+    const JSONTraceSessionBase &session) {
+  std::vector<ParsedProcess> parsed_processes;
+
+  auto onError = [&]() {
+    // Delete all targets that were created so far in case of failures
+    for (ParsedProcess &parsed_process : parsed_processes)
+      m_debugger.GetTargetList().DeleteTarget(parsed_process.target_sp);
+  };
+
+  for (const JSONProcess &process : session.processes) {
+    if (Expected<ParsedProcess> parsed_process = ParseProcess(process))
+      parsed_processes.push_back(std::move(*parsed_process));
+    else {
+      onError();
+      return parsed_process.takeError();
+    }
+  }
+  return parsed_processes;
+}
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONAddress &address,
+              Path path) {
+  Optional<StringRef> s = value.getAsString();
+  if (s.hasValue() && !s->getAsInteger(0, address.value))
+    return true;
+
+  path.report("expected numeric string");
+  return false;
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONModule &module,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("systemPath", module.system_path) &&
+         o.map("file", module.file) &&
+         o.map("loadAddress", module.load_address) &&
+         o.map("uuid", module.uuid);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONThread &thread,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file);
+}
+
+bool fromJSON(const Value &value, TraceSessionFileParser::JSONProcess &process,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("pid", process.pid) && o.map("triple", process.triple) &&
+         o.map("threads", process.threads) && o.map("modules", process.modules);
+}
+
+bool fromJSON(const Value &value,
+              TraceSessionFileParser::JSONTracePluginSettings &plugin_settings,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("type", plugin_settings.type);
+}
+
+bool fromJSON(const Value &value,
+              TraceSessionFileParser::JSONTraceSessionBase &session,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("processes", session.processes);
+}
+
+} // namespace json
+} // namespace llvm
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h b/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
new file mode 100644
index 0000000..6abaffc
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h
@@ -0,0 +1,179 @@
+//===-- TraceSessionFileParser.h --------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_TRACESESSIONPARSER_H
+#define LLDB_TARGET_TRACESESSIONPARSER_H
+
+#include "llvm/Support/JSON.h"
+
+#include "ThreadPostMortemTrace.h"
+
+namespace lldb_private {
+
+/// \class TraceSessionFileParser TraceSessionFileParser.h
+///
+/// Base class for parsing the common information of JSON trace session files.
+/// Contains the basic C++ structs that represent the JSON data, which include
+/// \a JSONTraceSession as the root object.
+///
+/// See \a Trace::FindPlugin for more information regarding these JSON files.
+class TraceSessionFileParser {
+public:
+  /// C++ structs representing the JSON trace session.
+  /// \{
+  struct JSONAddress {
+    lldb::addr_t value;
+  };
+
+  struct JSONModule {
+    std::string system_path;
+    llvm::Optional<std::string> file;
+    JSONAddress load_address;
+    llvm::Optional<std::string> uuid;
+  };
+
+  struct JSONThread {
+    int64_t tid;
+    std::string trace_file;
+  };
+
+  struct JSONProcess {
+    int64_t pid;
+    std::string triple;
+    std::vector<JSONThread> threads;
+    std::vector<JSONModule> modules;
+  };
+
+  struct JSONTracePluginSettings {
+    std::string type;
+  };
+
+  struct JSONTraceSessionBase {
+    std::vector<JSONProcess> processes;
+  };
+
+  /// The trace plug-in implementation should provide its own TPluginSettings,
+  /// which corresponds to the "trace" section of the schema.
+  template <class TPluginSettings>
+  struct JSONTraceSession : JSONTraceSessionBase {
+    TPluginSettings trace;
+  };
+  /// \}
+
+  /// Helper struct holding the objects created when parsing a process
+  struct ParsedProcess {
+    lldb::TargetSP target_sp;
+    std::vector<lldb::ThreadPostMortemTraceSP> threads;
+  };
+
+  TraceSessionFileParser(Debugger &debugger, llvm::StringRef session_file_dir,
+                         llvm::StringRef schema)
+      : m_debugger(debugger), m_session_file_dir(session_file_dir),
+        m_schema(schema) {}
+
+  /// Build the full schema for a Trace plug-in.
+  ///
+  /// \param[in] plugin_schema
+  ///   The subschema that corresponds to the "trace" section of the schema.
+  ///
+  /// \return
+  ///   The full schema containing the common attributes and the plug-in
+  ///   specific attributes.
+  static std::string BuildSchema(llvm::StringRef plugin_schema);
+
+  /// Parse the fields common to all trace session schemas.
+  ///
+  /// \param[in] session
+  ///     The session json objects already deserialized.
+  ///
+  /// \return
+  ///     A list of \a ParsedProcess containing all threads and targets created
+  ///     during the parsing, or an error in case of failures. In case of
+  ///     errors, no side effects are produced.
+  llvm::Expected<std::vector<ParsedProcess>>
+  ParseCommonSessionFile(const JSONTraceSessionBase &session);
+
+protected:
+  /// Resolve non-absolute paths relative to the session file folder. It
+  /// modifies the given file_spec.
+  void NormalizePath(lldb_private::FileSpec &file_spec);
+
+  lldb::ThreadPostMortemTraceSP ParseThread(lldb::ProcessSP &process_sp,
+                                            const JSONThread &thread);
+
+  llvm::Expected<ParsedProcess> ParseProcess(const JSONProcess &process);
+
+  llvm::Error ParseModule(lldb::TargetSP &target_sp, const JSONModule &module);
+
+  /// Create a user-friendly error message upon a JSON-parsing failure using the
+  /// \a json::ObjectMapper functionality.
+  ///
+  /// \param[in] root
+  ///   The \a llvm::json::Path::Root used to parse the JSON \a value.
+  ///
+  /// \param[in] value
+  ///   The json value that failed to parse.
+  ///
+  /// \return
+  ///   An \a llvm::Error containing the user-friendly error message.
+  llvm::Error CreateJSONError(llvm::json::Path::Root &root,
+                              const llvm::json::Value &value);
+
+  Debugger &m_debugger;
+  std::string m_session_file_dir;
+  llvm::StringRef m_schema;
+};
+} // namespace lldb_private
+
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value,
+              lldb_private::TraceSessionFileParser::JSONAddress &address,
+              Path path);
+
+bool fromJSON(const Value &value,
+              lldb_private::TraceSessionFileParser::JSONModule &module,
+              Path path);
+
+bool fromJSON(const Value &value,
+              lldb_private::TraceSessionFileParser::JSONThread &thread,
+              Path path);
+
+bool fromJSON(const Value &value,
+              lldb_private::TraceSessionFileParser::JSONProcess &process,
+              Path path);
+
+bool fromJSON(const Value &value,
+              lldb_private::TraceSessionFileParser::JSONTracePluginSettings
+                  &plugin_settings,
+              Path path);
+
+bool fromJSON(
+    const Value &value,
+    lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session,
+    Path path);
+
+template <class TPluginSettings>
+bool fromJSON(
+    const Value &value,
+    lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings>
+        &session,
+    Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("trace", session.trace) &&
+         fromJSON(value,
+                  (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &)
+                      session,
+                  path);
+}
+
+} // namespace json
+} // namespace llvm
+
+#endif // LLDB_TARGET_TRACESESSIONPARSER_H
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
index a75d967..7ecc9b7 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CMakeLists.txt
@@ -17,6 +17,7 @@
   CommandObjectTraceStartIntelPT.cpp
   DecodedThread.cpp
   IntelPTDecoder.cpp
+  TraceCursorIntelPT.cpp
   TraceIntelPT.cpp
   TraceIntelPTSessionFileParser.cpp
 
@@ -24,6 +25,7 @@
     lldbCore
     lldbSymbol
     lldbTarget
+    lldbPluginTraceCommon
     ${LIBIPT_LIBRARY}
   LINK_COMPONENTS
     Support
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
index e1758df..5650af6 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
@@ -8,7 +8,10 @@
 
 #include "CommandObjectTraceStartIntelPT.h"
 
+#include "TraceIntelPT.h"
+#include "TraceIntelPTConstants.h"
 #include "lldb/Host/OptionParser.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/Trace.h"
 
 using namespace lldb;
@@ -16,10 +19,12 @@
 using namespace lldb_private::trace_intel_pt;
 using namespace llvm;
 
+// CommandObjectThreadTraceStartIntelPT
+
 #define LLDB_OPTIONS_thread_trace_start_intel_pt
 #include "TraceIntelPTCommandOptions.inc"
 
-Status CommandObjectTraceStartIntelPT::CommandOptions::SetOptionValue(
+Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue(
     uint32_t option_idx, llvm::StringRef option_arg,
     ExecutionContext *execution_context) {
   Status error;
@@ -27,23 +32,27 @@
 
   switch (short_option) {
   case 's': {
-    int32_t size_in_kb;
-    if (option_arg.empty() || option_arg.getAsInteger(0, size_in_kb) ||
-        size_in_kb < 0)
+    int64_t thread_buffer_size;
+    if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
+        thread_buffer_size < 0)
       error.SetErrorStringWithFormat("invalid integer value for option '%s'",
                                      option_arg.str().c_str());
     else
-      m_size_in_kb = size_in_kb;
+      m_thread_buffer_size = thread_buffer_size;
     break;
   }
-  case 'c': {
-    int32_t custom_config;
-    if (option_arg.empty() || option_arg.getAsInteger(0, custom_config) ||
-        custom_config < 0)
+  case 't': {
+    m_enable_tsc = true;
+    break;
+  }
+  case 'p': {
+    int64_t psb_period;
+    if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) ||
+        psb_period < 0)
       error.SetErrorStringWithFormat("invalid integer value for option '%s'",
                                      option_arg.str().c_str());
     else
-      m_custom_config = custom_config;
+      m_psb_period = psb_period;
     break;
   }
   default:
@@ -52,22 +61,104 @@
   return error;
 }
 
-void CommandObjectTraceStartIntelPT::CommandOptions::OptionParsingStarting(
-    ExecutionContext *execution_context) {
-  m_size_in_kb = 4;
-  m_custom_config = 0;
+void CommandObjectThreadTraceStartIntelPT::CommandOptions::
+    OptionParsingStarting(ExecutionContext *execution_context) {
+  m_thread_buffer_size = kDefaultThreadBufferSize;
+  m_enable_tsc = kDefaultEnableTscValue;
+  m_psb_period = kDefaultPsbPeriod;
 }
 
 llvm::ArrayRef<OptionDefinition>
-CommandObjectTraceStartIntelPT::CommandOptions::GetDefinitions() {
+CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() {
   return llvm::makeArrayRef(g_thread_trace_start_intel_pt_options);
 }
 
-bool CommandObjectTraceStartIntelPT::HandleOneThread(
-    lldb::tid_t tid, CommandReturnObject &result) {
-  result.AppendMessageWithFormat(
-      "would trace tid %" PRIu64 " with size_in_kb %zu and custom_config %d\n",
-      tid, m_options.m_size_in_kb, m_options.m_custom_config);
-  result.SetStatus(eReturnStatusSuccessFinishResult);
+bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads(
+    Args &command, CommandReturnObject &result,
+    llvm::ArrayRef<lldb::tid_t> tids) {
+  if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size,
+                                m_options.m_enable_tsc, m_options.m_psb_period))
+    result.SetError(Status(std::move(err)));
+  else
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+
+  return result.Succeeded();
+}
+
+/// CommandObjectProcessTraceStartIntelPT
+
+#define LLDB_OPTIONS_process_trace_start_intel_pt
+#include "TraceIntelPTCommandOptions.inc"
+
+Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue(
+    uint32_t option_idx, llvm::StringRef option_arg,
+    ExecutionContext *execution_context) {
+  Status error;
+  const int short_option = m_getopt_table[option_idx].val;
+
+  switch (short_option) {
+  case 's': {
+    int64_t thread_buffer_size;
+    if (option_arg.empty() || option_arg.getAsInteger(0, thread_buffer_size) ||
+        thread_buffer_size < 0)
+      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+                                     option_arg.str().c_str());
+    else
+      m_thread_buffer_size = thread_buffer_size;
+    break;
+  }
+  case 'l': {
+    int64_t process_buffer_size_limit;
+    if (option_arg.empty() ||
+        option_arg.getAsInteger(0, process_buffer_size_limit) ||
+        process_buffer_size_limit < 0)
+      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+                                     option_arg.str().c_str());
+    else
+      m_process_buffer_size_limit = process_buffer_size_limit;
+    break;
+  }
+  case 't': {
+    m_enable_tsc = true;
+    break;
+  }
+  case 'p': {
+    int64_t psb_period;
+    if (option_arg.empty() || option_arg.getAsInteger(0, psb_period) ||
+        psb_period < 0)
+      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+                                     option_arg.str().c_str());
+    else
+      m_psb_period = psb_period;
+    break;
+  }
+  default:
+    llvm_unreachable("Unimplemented option");
+  }
+  return error;
+}
+
+void CommandObjectProcessTraceStartIntelPT::CommandOptions::
+    OptionParsingStarting(ExecutionContext *execution_context) {
+  m_thread_buffer_size = kDefaultThreadBufferSize;
+  m_process_buffer_size_limit = kDefaultProcessBufferSizeLimit;
+  m_enable_tsc = kDefaultEnableTscValue;
+  m_psb_period = kDefaultPsbPeriod;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectProcessTraceStartIntelPT::CommandOptions::GetDefinitions() {
+  return llvm::makeArrayRef(g_process_trace_start_intel_pt_options);
+}
+
+bool CommandObjectProcessTraceStartIntelPT::DoExecute(
+    Args &command, CommandReturnObject &result) {
+  if (Error err = m_trace.Start(m_options.m_thread_buffer_size,
+                                m_options.m_process_buffer_size_limit,
+                                m_options.m_enable_tsc, m_options.m_psb_period))
+    result.SetError(Status(std::move(err)));
+  else
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+
   return result.Succeeded();
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
index 265569c5..2f3d53a8 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
@@ -9,21 +9,21 @@
 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTRACESTARTINTELPT_H
 
-#include "../../../../source/Commands/CommandObjectThreadUtil.h"
+#include "../../../../source/Commands/CommandObjectTrace.h"
+#include "TraceIntelPT.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 
 namespace lldb_private {
 namespace trace_intel_pt {
 
-class CommandObjectTraceStartIntelPT : public CommandObjectIterateOverThreads {
+class CommandObjectThreadTraceStartIntelPT
+    : public CommandObjectMultipleThreads {
 public:
   class CommandOptions : public Options {
   public:
     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
 
-    ~CommandOptions() override = default;
-
     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                           ExecutionContext *execution_context) override;
 
@@ -31,31 +31,76 @@
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
 
-    size_t m_size_in_kb;
-    uint32_t m_custom_config;
+    size_t m_thread_buffer_size;
+    bool m_enable_tsc;
+    llvm::Optional<size_t> m_psb_period;
   };
 
-  CommandObjectTraceStartIntelPT(CommandInterpreter &interpreter)
-      : CommandObjectIterateOverThreads(
+  CommandObjectThreadTraceStartIntelPT(TraceIntelPT &trace,
+                                       CommandInterpreter &interpreter)
+      : CommandObjectMultipleThreads(
             interpreter, "thread trace start",
             "Start tracing one or more threads with intel-pt. "
             "Defaults to the current thread. Thread indices can be "
             "specified as arguments.\n Use the thread-index \"all\" to trace "
-            "all threads.",
+            "all threads including future threads.",
             "thread trace start [<thread-index> <thread-index> ...] "
             "[<intel-pt-options>]",
             lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
                 lldb::eCommandProcessMustBeLaunched |
                 lldb::eCommandProcessMustBePaused),
-        m_options() {}
-
-  ~CommandObjectTraceStartIntelPT() override = default;
+        m_trace(trace), m_options() {}
 
   Options *GetOptions() override { return &m_options; }
 
 protected:
-  bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override;
+  bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
+                          llvm::ArrayRef<lldb::tid_t> tids) override;
 
+  TraceIntelPT &m_trace;
+  CommandOptions m_options;
+};
+
+class CommandObjectProcessTraceStartIntelPT : public CommandObjectParsed {
+public:
+  class CommandOptions : public Options {
+  public:
+    CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override;
+
+    void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+    llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+    size_t m_thread_buffer_size;
+    size_t m_process_buffer_size_limit;
+    bool m_enable_tsc;
+    llvm::Optional<size_t> m_psb_period;
+  };
+
+  CommandObjectProcessTraceStartIntelPT(TraceIntelPT &trace,
+                                        CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "process trace start",
+            "Start tracing this process with intel-pt, including future "
+            "threads. "
+            "This is implemented by tracing each thread independently. "
+            "Threads traced with the \"thread trace start\" command are left "
+            "unaffected ant not retraced.",
+            "process trace start [<intel-pt-options>]",
+            lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+                lldb::eCommandProcessMustBeLaunched |
+                lldb::eCommandProcessMustBePaused),
+        m_trace(trace), m_options() {}
+
+  Options *GetOptions() override { return &m_options; }
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+  TraceIntelPT &m_trace;
   CommandOptions m_options;
 };
 
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
index 6b8b065..4822a78 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
@@ -8,8 +8,13 @@
 
 #include "DecodedThread.h"
 
+#include <intel-pt.h>
+#include <memory>
+
+#include "TraceCursorIntelPT.h"
 #include "lldb/Utility/StreamString.h"
 
+using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::trace_intel_pt;
 using namespace llvm;
@@ -30,12 +35,21 @@
   OS << "error: " << libipt_error_message;
 }
 
+IntelPTInstruction::IntelPTInstruction(llvm::Error err) {
+  llvm::handleAllErrors(std::move(err),
+                        [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
+                          m_error = std::move(info);
+                        });
+  m_pt_insn.ip = LLDB_INVALID_ADDRESS;
+  m_pt_insn.iclass = ptic_error;
+}
+
 bool IntelPTInstruction::IsError() const { return (bool)m_error; }
 
-Expected<lldb::addr_t> IntelPTInstruction::GetLoadAddress() const {
-  if (IsError())
-    return ToError();
-  return m_pt_insn.ip;
+lldb::addr_t IntelPTInstruction::GetLoadAddress() const { return m_pt_insn.ip; }
+
+Optional<uint64_t> IntelPTInstruction::GetTimestampCounter() const {
+  return m_timestamp;
 }
 
 Error IntelPTInstruction::ToError() const {
@@ -47,18 +61,58 @@
   return make_error<StringError>(m_error->message(),
                                  m_error->convertToErrorCode());
 }
+size_t DecodedThread::GetRawTraceSize() const { return m_raw_trace_size; }
 
-size_t DecodedThread::GetLastPosition() const {
-  return m_instructions.empty() ? 0 : m_instructions.size() - 1;
+TraceInstructionControlFlowType
+IntelPTInstruction::GetControlFlowType(lldb::addr_t next_load_address) const {
+  if (IsError())
+    return (TraceInstructionControlFlowType)0;
+
+  TraceInstructionControlFlowType mask =
+      eTraceInstructionControlFlowTypeInstruction;
+
+  switch (m_pt_insn.iclass) {
+  case ptic_cond_jump:
+  case ptic_jump:
+  case ptic_far_jump:
+    mask |= eTraceInstructionControlFlowTypeBranch;
+    if (m_pt_insn.ip + m_pt_insn.size != next_load_address)
+      mask |= eTraceInstructionControlFlowTypeTakenBranch;
+    break;
+  case ptic_return:
+  case ptic_far_return:
+    mask |= eTraceInstructionControlFlowTypeReturn;
+    break;
+  case ptic_call:
+  case ptic_far_call:
+    mask |= eTraceInstructionControlFlowTypeCall;
+    break;
+  default:
+    break;
+  }
+
+  return mask;
 }
 
 ArrayRef<IntelPTInstruction> DecodedThread::GetInstructions() const {
   return makeArrayRef(m_instructions);
 }
 
-size_t DecodedThread::GetCursorPosition() const { return m_position; }
+DecodedThread::DecodedThread(ThreadSP thread_sp, Error error)
+    : m_thread_sp(thread_sp) {
+  m_instructions.emplace_back(std::move(error));
+}
 
-size_t DecodedThread::SetCursorPosition(size_t new_position) {
-  m_position = std::min(new_position, GetLastPosition());
-  return m_position;
+DecodedThread::DecodedThread(ThreadSP thread_sp,
+                             std::vector<IntelPTInstruction> &&instructions,
+                             size_t raw_trace_size)
+    : m_thread_sp(thread_sp), m_instructions(std::move(instructions)),
+      m_raw_trace_size(raw_trace_size) {
+  if (m_instructions.empty())
+    m_instructions.emplace_back(
+        createStringError(inconvertibleErrorCode(), "empty trace"));
+}
+
+lldb::TraceCursorUP DecodedThread::GetCursor() {
+  return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this());
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
index 3c7e030..592c402 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
@@ -15,6 +15,7 @@
 #include "llvm/Support/Error.h"
 
 #include "lldb/Target/Trace.h"
+#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
 
 #include "intel-pt.h"
 
@@ -60,17 +61,15 @@
 /// As mentioned, any gap is represented as an error in this class.
 class IntelPTInstruction {
 public:
+  IntelPTInstruction(const pt_insn &pt_insn, uint64_t timestamp)
+      : m_pt_insn(pt_insn), m_timestamp(timestamp) {}
+
   IntelPTInstruction(const pt_insn &pt_insn) : m_pt_insn(pt_insn) {}
 
   /// Error constructor
   ///
   /// libipt errors should use the underlying \a IntelPTError class.
-  IntelPTInstruction(llvm::Error err) {
-    llvm::handleAllErrors(std::move(err),
-                          [&](std::unique_ptr<llvm::ErrorInfoBase> info) {
-                            m_error = std::move(info);
-                          });
-  }
+  IntelPTInstruction(llvm::Error err);
 
   /// Check if this object represents an error (i.e. a gap).
   ///
@@ -79,15 +78,34 @@
   bool IsError() const;
 
   /// \return
-  ///     The instruction pointer address, or an \a llvm::Error if it is an
-  ///     error.
-  llvm::Expected<lldb::addr_t> GetLoadAddress() const;
+  ///     The instruction pointer address, or \a LLDB_INVALID_ADDRESS if it is
+  ///     an error.
+  lldb::addr_t GetLoadAddress() const;
 
   /// \return
   ///     An \a llvm::Error object if this class corresponds to an Error, or an
   ///     \a llvm::Error::success otherwise.
   llvm::Error ToError() const;
 
+  /// Get the timestamp associated with the current instruction. The timestamp
+  /// is similar to what a rdtsc instruction would return.
+  ///
+  /// \return
+  ///     The timestamp or \b llvm::None if not available.
+  llvm::Optional<uint64_t> GetTimestampCounter() const;
+
+  /// Get the \a lldb::TraceInstructionControlFlowType categories of the
+  /// instruction.
+  ///
+  /// \param[in] next_load_address
+  ///     The address of the next instruction in the trace or \b
+  ///     LLDB_INVALID_ADDRESS if not available.
+  ///
+  /// \return
+  ///     The control flow categories, or \b 0 if the instruction is an error.
+  lldb::TraceInstructionControlFlowType
+  GetControlFlowType(lldb::addr_t next_load_address) const;
+
   IntelPTInstruction(IntelPTInstruction &&other) = default;
 
 private:
@@ -95,6 +113,7 @@
   const IntelPTInstruction &operator=(const IntelPTInstruction &other) = delete;
 
   pt_insn m_pt_insn;
+  llvm::Optional<uint64_t> m_timestamp;
   std::unique_ptr<llvm::ErrorInfoBase> m_error;
 };
 
@@ -105,11 +124,15 @@
 ///
 /// Each decoded thread contains a cursor to the current position the user is
 /// stopped at. See \a Trace::GetCursorPosition for more information.
-class DecodedThread {
+class DecodedThread : public std::enable_shared_from_this<DecodedThread> {
 public:
-  DecodedThread(std::vector<IntelPTInstruction> &&instructions)
-      : m_instructions(std::move(instructions)), m_position(GetLastPosition()) {
-  }
+  DecodedThread(lldb::ThreadSP thread_sp,
+                std::vector<IntelPTInstruction> &&instructions,
+                size_t raw_trace_size);
+
+  /// Constructor with a single error signaling a complete failure of the
+  /// decoding process.
+  DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error);
 
   /// Get the instructions from the decoded trace. Some of them might indicate
   /// errors (i.e. gaps) in the trace.
@@ -118,28 +141,23 @@
   ///   The instructions of the trace.
   llvm::ArrayRef<IntelPTInstruction> GetInstructions() const;
 
-  /// \return
-  ///   The current position of the cursor of this trace, or 0 if there are no
-  ///   instructions.
-  size_t GetCursorPosition() const;
+  /// Get a new cursor for the decoded thread.
+  lldb::TraceCursorUP GetCursor();
 
-  /// Change the position of the cursor of this trace. If this value is to high,
-  /// the new position will be set as the last instruction of the trace.
+  /// Get the size in bytes of the corresponding Intel PT raw trace
   ///
   /// \return
-  ///     The effective new position.
-  size_t SetCursorPosition(size_t new_position);
-  /// \}
+  ///   The size of the trace.
+  size_t GetRawTraceSize() const;
 
 private:
-  /// \return
-  ///     The index of the last element of the trace, or 0 if empty.
-  size_t GetLastPosition() const;
-
+  lldb::ThreadSP m_thread_sp;
   std::vector<IntelPTInstruction> m_instructions;
-  size_t m_position;
+  size_t m_raw_trace_size;
 };
 
+using DecodedThreadSP = std::shared_ptr<DecodedThread>;
+
 } // namespace trace_intel_pt
 } // namespace lldb_private
 
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
index b6e8ae8..3827881 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -1,5 +1,4 @@
-//===-- IntelPTDecoder.cpp --------------------------------------*- C++ -*-===//
-//
+//===-- IntelPTDecoder.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
@@ -10,10 +9,13 @@
 
 #include "llvm/Support/MemoryBuffer.h"
 
+#include "../common/ThreadPostMortemTrace.h"
+#include "DecodedThread.h"
+#include "TraceIntelPT.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadTrace.h"
+#include "lldb/Utility/StringExtractor.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -85,7 +87,7 @@
       return errcode;
   }
   return 0;
-};
+}
 
 /// Decode all the instructions from a configured decoder.
 /// The decoding flow is based on
@@ -135,7 +137,23 @@
         break;
       }
 
-      instructions.emplace_back(insn);
+      uint64_t time;
+      int time_error = pt_insn_time(&decoder, &time, nullptr, nullptr);
+      if (time_error == -pte_invalid) {
+        // This happens if we invoke the pt_insn_time method incorrectly,
+        // but the instruction is good though.
+        instructions.emplace_back(
+            make_error<IntelPTError>(time_error, insn.ip));
+        instructions.emplace_back(insn);
+        break;
+      }
+      if (time_error == -pte_no_time) {
+        // We simply don't have time information, i.e. None of TSC, MTC or CYC
+        // was enabled.
+        instructions.emplace_back(insn);
+      } else {
+        instructions.emplace_back(insn, time);
+      }
     }
   }
 
@@ -158,39 +176,26 @@
   return bytes_read;
 }
 
-static std::vector<IntelPTInstruction> makeInstructionListFromError(Error err) {
-  std::vector<IntelPTInstruction> instructions;
-  instructions.emplace_back(std::move(err));
-  return instructions;
-}
-
-static std::vector<IntelPTInstruction>
-CreateDecoderAndDecode(Process &process, const pt_cpu &pt_cpu,
-                       const FileSpec &trace_file) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
-      MemoryBuffer::getFile(trace_file.GetPath());
-  if (std::error_code err = trace_or_error.getError())
-    return makeInstructionListFromError(errorCodeToError(err));
-
-  MemoryBuffer &trace = **trace_or_error;
+static Expected<std::vector<IntelPTInstruction>>
+DecodeInMemoryTrace(Process &process, TraceIntelPT &trace_intel_pt,
+                    MutableArrayRef<uint8_t> buffer) {
+  Expected<pt_cpu> cpu_info = trace_intel_pt.GetCPUInfo();
+  if (!cpu_info)
+    return cpu_info.takeError();
 
   pt_config config;
   pt_config_init(&config);
-  config.cpu = pt_cpu;
+  config.cpu = *cpu_info;
 
   if (int errcode = pt_cpu_errata(&config.errata, &config.cpu))
-    return makeInstructionListFromError(make_error<IntelPTError>(errcode));
+    return make_error<IntelPTError>(errcode);
 
-  // The libipt library does not modify the trace buffer, hence the following
-  // cast is safe.
-  config.begin =
-      reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart()));
-  config.end =
-      reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferEnd()));
+  config.begin = buffer.data();
+  config.end = buffer.data() + buffer.size();
 
   pt_insn_decoder *decoder = pt_insn_alloc_decoder(&config);
   if (!decoder)
-    return makeInstructionListFromError(make_error<IntelPTError>(-pte_nomem));
+    return make_error<IntelPTError>(-pte_nomem);
 
   pt_image *image = pt_insn_get_image(decoder);
 
@@ -204,12 +209,71 @@
   return instructions;
 }
 
-const DecodedThread &ThreadTraceDecoder::Decode() {
-  if (!m_decoded_thread.hasValue()) {
-    m_decoded_thread = DecodedThread(
-        CreateDecoderAndDecode(*m_trace_thread->GetProcess(), m_pt_cpu,
-                               m_trace_thread->GetTraceFile()));
-  }
+static Expected<std::vector<IntelPTInstruction>>
+DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt,
+                const FileSpec &trace_file, size_t &raw_trace_size) {
+  ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
+      MemoryBuffer::getFile(trace_file.GetPath());
+  if (std::error_code err = trace_or_error.getError())
+    return errorCodeToError(err);
 
+  MemoryBuffer &trace = **trace_or_error;
+  MutableArrayRef<uint8_t> trace_data(
+      // The libipt library does not modify the trace buffer, hence the
+      // following cast is safe.
+      reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())),
+      trace.getBufferSize());
+  raw_trace_size = trace_data.size();
+  return DecodeInMemoryTrace(process, trace_intel_pt, trace_data);
+}
+
+static Expected<std::vector<IntelPTInstruction>>
+DecodeLiveThread(Thread &thread, TraceIntelPT &trace, size_t &raw_trace_size) {
+  Expected<std::vector<uint8_t>> buffer =
+      trace.GetLiveThreadBuffer(thread.GetID());
+  if (!buffer)
+    return buffer.takeError();
+  raw_trace_size = buffer->size();
+  if (Expected<pt_cpu> cpu_info = trace.GetCPUInfo())
+    return DecodeInMemoryTrace(*thread.GetProcess(), trace,
+                               MutableArrayRef<uint8_t>(*buffer));
+  else
+    return cpu_info.takeError();
+}
+
+DecodedThreadSP ThreadDecoder::Decode() {
+  if (!m_decoded_thread.hasValue())
+    m_decoded_thread = DoDecode();
   return *m_decoded_thread;
 }
+
+PostMortemThreadDecoder::PostMortemThreadDecoder(
+    const lldb::ThreadPostMortemTraceSP &trace_thread, TraceIntelPT &trace)
+    : m_trace_thread(trace_thread), m_trace(trace) {}
+
+DecodedThreadSP PostMortemThreadDecoder::DoDecode() {
+  size_t raw_trace_size = 0;
+  if (Expected<std::vector<IntelPTInstruction>> instructions =
+          DecodeTraceFile(*m_trace_thread->GetProcess(), m_trace,
+                          m_trace_thread->GetTraceFile(), raw_trace_size))
+    return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
+                                           std::move(*instructions),
+                                           raw_trace_size);
+  else
+    return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
+                                           instructions.takeError());
+}
+
+LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace)
+    : m_thread_sp(thread.shared_from_this()), m_trace(trace) {}
+
+DecodedThreadSP LiveThreadDecoder::DoDecode() {
+  size_t raw_trace_size = 0;
+  if (Expected<std::vector<IntelPTInstruction>> instructions =
+          DecodeLiveThread(*m_thread_sp, m_trace, raw_trace_size))
+    return std::make_shared<DecodedThread>(
+        m_thread_sp, std::move(*instructions), raw_trace_size);
+  else
+    return std::make_shared<DecodedThread>(m_thread_sp,
+                                           instructions.takeError());
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
index 2e67f9b..e969db5 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.h
@@ -12,38 +12,73 @@
 #include "intel-pt.h"
 
 #include "DecodedThread.h"
+#include "forward-declarations.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/FileSpec.h"
 
 namespace lldb_private {
 namespace trace_intel_pt {
 
-/// \a lldb_private::ThreadTrace decoder that stores the output from decoding,
-/// avoiding recomputations, as decoding is expensive.
-class ThreadTraceDecoder {
+/// Base class that handles the decoding of a thread and caches the result.
+class ThreadDecoder {
+public:
+  virtual ~ThreadDecoder() = default;
+
+  ThreadDecoder() = default;
+
+  /// Decode the thread and store the result internally, to avoid
+  /// recomputations.
+  ///
+  /// \return
+  ///     A \a DecodedThread instance.
+  DecodedThreadSP Decode();
+
+  ThreadDecoder(const ThreadDecoder &other) = delete;
+  ThreadDecoder &operator=(const ThreadDecoder &other) = delete;
+
+protected:
+  /// Decode the thread.
+  ///
+  /// \return
+  ///     A \a DecodedThread instance.
+  virtual DecodedThreadSP DoDecode() = 0;
+
+  llvm::Optional<DecodedThreadSP> m_decoded_thread;
+};
+
+/// Decoder implementation for \a lldb_private::ThreadPostMortemTrace, which are
+/// non-live processes that come trace session files.
+class PostMortemThreadDecoder : public ThreadDecoder {
 public:
   /// \param[in] trace_thread
   ///     The thread whose trace file will be decoded.
   ///
-  /// \param[in] pt_cpu
-  ///     The libipt cpu used when recording the trace.
-  ThreadTraceDecoder(const std::shared_ptr<ThreadTrace> &trace_thread,
-                     const pt_cpu &pt_cpu)
-      : m_trace_thread(trace_thread), m_pt_cpu(pt_cpu), m_decoded_thread() {}
-
-  /// Decode the thread and store the result internally.
-  ///
-  /// \return
-  ///     A \a DecodedThread instance.
-  const DecodedThread &Decode();
+  /// \param[in] trace
+  ///     The main Trace object who owns this decoder and its data.
+  PostMortemThreadDecoder(const lldb::ThreadPostMortemTraceSP &trace_thread,
+                          TraceIntelPT &trace);
 
 private:
-  ThreadTraceDecoder(const ThreadTraceDecoder &other) = delete;
-  ThreadTraceDecoder &operator=(const ThreadTraceDecoder &other) = delete;
+  DecodedThreadSP DoDecode() override;
 
-  std::shared_ptr<ThreadTrace> m_trace_thread;
-  pt_cpu m_pt_cpu;
-  llvm::Optional<DecodedThread> m_decoded_thread;
+  lldb::ThreadPostMortemTraceSP m_trace_thread;
+  TraceIntelPT &m_trace;
+};
+
+class LiveThreadDecoder : public ThreadDecoder {
+public:
+  /// \param[in] thread
+  ///     The thread whose traces will be decoded.
+  ///
+  /// \param[in] trace
+  ///     The main Trace object who owns this decoder and its data.
+  LiveThreadDecoder(Thread &thread, TraceIntelPT &trace);
+
+private:
+  DecodedThreadSP DoDecode() override;
+
+  lldb::ThreadSP m_thread_sp;
+  TraceIntelPT &m_trace;
 };
 
 } // namespace trace_intel_pt
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
new file mode 100644
index 0000000..edefdd0
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
@@ -0,0 +1,100 @@
+//===-- TraceCursorIntelPT.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 "TraceCursorIntelPT.h"
+#include "DecodedThread.h"
+#include "TraceIntelPT.h"
+
+#include <cstdlib>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::trace_intel_pt;
+using namespace llvm;
+
+TraceCursorIntelPT::TraceCursorIntelPT(ThreadSP thread_sp,
+                                       DecodedThreadSP decoded_thread_sp)
+    : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp) {
+  assert(!m_decoded_thread_sp->GetInstructions().empty() &&
+         "a trace should have at least one instruction or error");
+  m_pos = m_decoded_thread_sp->GetInstructions().size() - 1;
+}
+
+size_t TraceCursorIntelPT::GetInternalInstructionSize() {
+  return m_decoded_thread_sp->GetInstructions().size();
+}
+
+bool TraceCursorIntelPT::Next() {
+  auto canMoveOne = [&]() {
+    if (IsForwards())
+      return m_pos + 1 < GetInternalInstructionSize();
+    return m_pos > 0;
+  };
+
+  size_t initial_pos = m_pos;
+
+  while (canMoveOne()) {
+    m_pos += IsForwards() ? 1 : -1;
+    if (!m_ignore_errors && IsError())
+      return true;
+    if (GetInstructionControlFlowType() & m_granularity)
+      return true;
+  }
+
+  // Didn't find any matching instructions
+  m_pos = initial_pos;
+  return false;
+}
+
+size_t TraceCursorIntelPT::Seek(int64_t offset, SeekType origin) {
+  int64_t last_index = GetInternalInstructionSize() - 1;
+
+  auto fitPosToBounds = [&](int64_t raw_pos) -> int64_t {
+    return std::min(std::max((int64_t)0, raw_pos), last_index);
+  };
+
+  switch (origin) {
+  case TraceCursor::SeekType::Set:
+    m_pos = fitPosToBounds(offset);
+    return m_pos;
+  case TraceCursor::SeekType::End:
+    m_pos = fitPosToBounds(offset + last_index);
+    return last_index - m_pos;
+  case TraceCursor::SeekType::Current:
+    int64_t new_pos = fitPosToBounds(offset + m_pos);
+    int64_t dist = m_pos - new_pos;
+    m_pos = new_pos;
+    return std::abs(dist);
+  }
+}
+
+bool TraceCursorIntelPT::IsError() {
+  return m_decoded_thread_sp->GetInstructions()[m_pos].IsError();
+}
+
+Error TraceCursorIntelPT::GetError() {
+  return m_decoded_thread_sp->GetInstructions()[m_pos].ToError();
+}
+
+lldb::addr_t TraceCursorIntelPT::GetLoadAddress() {
+  return m_decoded_thread_sp->GetInstructions()[m_pos].GetLoadAddress();
+}
+
+Optional<uint64_t> TraceCursorIntelPT::GetTimestampCounter() {
+  return m_decoded_thread_sp->GetInstructions()[m_pos].GetTimestampCounter();
+}
+
+TraceInstructionControlFlowType
+TraceCursorIntelPT::GetInstructionControlFlowType() {
+  lldb::addr_t next_load_address =
+      m_pos + 1 < GetInternalInstructionSize()
+          ? m_decoded_thread_sp->GetInstructions()[m_pos + 1].GetLoadAddress()
+          : LLDB_INVALID_ADDRESS;
+  return m_decoded_thread_sp->GetInstructions()[m_pos].GetControlFlowType(
+      next_load_address);
+}
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
new file mode 100644
index 0000000..29d3792
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
@@ -0,0 +1,50 @@
+//===-- TraceCursorIntelPT.h ------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
+
+#include "IntelPTDecoder.h"
+#include "TraceIntelPTSessionFileParser.h"
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceCursorIntelPT : public TraceCursor {
+public:
+  TraceCursorIntelPT(lldb::ThreadSP thread_sp,
+                     DecodedThreadSP decoded_thread_sp);
+
+  size_t Seek(int64_t offset, SeekType origin) override;
+
+  virtual bool Next() override;
+
+  llvm::Error GetError() override;
+
+  lldb::addr_t GetLoadAddress() override;
+
+  llvm::Optional<uint64_t> GetTimestampCounter() override;
+
+  lldb::TraceInstructionControlFlowType
+  GetInstructionControlFlowType() override;
+
+  bool IsError() override;
+
+private:
+  size_t GetInternalInstructionSize();
+
+  /// Storage of the actual instructions
+  DecodedThreadSP m_decoded_thread_sp;
+  /// Internal instruction index currently pointing at.
+  size_t m_pos;
+};
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACECURSORINTELPT_H
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
index 63a8b2d..c12bcd3 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -8,12 +8,14 @@
 
 #include "TraceIntelPT.h"
 
+#include "../common/ThreadPostMortemTrace.h"
 #include "CommandObjectTraceStartIntelPT.h"
+#include "DecodedThread.h"
+#include "TraceIntelPTConstants.h"
 #include "TraceIntelPTSessionFileParser.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadTrace.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -22,18 +24,27 @@
 
 LLDB_PLUGIN_DEFINE(TraceIntelPT)
 
-CommandObjectSP GetStartCommand(CommandInterpreter &interpreter) {
-  return CommandObjectSP(new CommandObjectTraceStartIntelPT(interpreter));
+lldb::CommandObjectSP
+TraceIntelPT::GetProcessTraceStartCommand(CommandInterpreter &interpreter) {
+  return CommandObjectSP(
+      new CommandObjectProcessTraceStartIntelPT(*this, interpreter));
+}
+
+lldb::CommandObjectSP
+TraceIntelPT::GetThreadTraceStartCommand(CommandInterpreter &interpreter) {
+  return CommandObjectSP(
+      new CommandObjectThreadTraceStartIntelPT(*this, interpreter));
 }
 
 void TraceIntelPT::Initialize() {
-  PluginManager::RegisterPlugin(
-      GetPluginNameStatic(), "Intel Processor Trace", CreateInstance,
-      TraceIntelPTSessionFileParser::GetSchema(), GetStartCommand);
+  PluginManager::RegisterPlugin(GetPluginNameStatic(), "Intel Processor Trace",
+                                CreateInstanceForSessionFile,
+                                CreateInstanceForLiveProcess,
+                                TraceIntelPTSessionFileParser::GetSchema());
 }
 
 void TraceIntelPT::Terminate() {
-  PluginManager::UnregisterPlugin(CreateInstance);
+  PluginManager::UnregisterPlugin(CreateInstanceForSessionFile);
 }
 
 ConstString TraceIntelPT::GetPluginNameStatic() {
@@ -55,60 +66,278 @@
 
 void TraceIntelPT::Dump(Stream *s) const {}
 
-Expected<TraceSP>
-TraceIntelPT::CreateInstance(const json::Value &trace_session_file,
-                             StringRef session_file_dir, Debugger &debugger) {
+Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile(
+    const json::Value &trace_session_file, StringRef session_file_dir,
+    Debugger &debugger) {
   return TraceIntelPTSessionFileParser(debugger, trace_session_file,
                                        session_file_dir)
       .Parse();
 }
 
+Expected<TraceSP> TraceIntelPT::CreateInstanceForLiveProcess(Process &process) {
+  TraceSP instance(new TraceIntelPT(process));
+  process.GetTarget().SetTrace(instance);
+  return instance;
+}
+
 TraceIntelPT::TraceIntelPT(
-    const pt_cpu &pt_cpu,
-    const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads)
-    : m_pt_cpu(pt_cpu) {
-  for (const std::shared_ptr<ThreadTrace> &thread : traced_threads)
-    m_trace_threads.emplace(
-        std::piecewise_construct,
-        std::forward_as_tuple(thread->GetProcess()->GetID(), thread->GetID()),
-        std::forward_as_tuple(thread, pt_cpu));
+    const pt_cpu &cpu_info,
+    const std::vector<ThreadPostMortemTraceSP> &traced_threads)
+    : m_cpu_info(cpu_info) {
+  for (const ThreadPostMortemTraceSP &thread : traced_threads)
+    m_thread_decoders.emplace(
+        thread.get(), std::make_unique<PostMortemThreadDecoder>(thread, *this));
 }
 
-const DecodedThread *TraceIntelPT::Decode(const Thread &thread) {
-  auto it = m_trace_threads.find(
-      std::make_pair(thread.GetProcess()->GetID(), thread.GetID()));
-  if (it == m_trace_threads.end())
-    return nullptr;
-  return &it->second.Decode();
+DecodedThreadSP TraceIntelPT::Decode(Thread &thread) {
+  RefreshLiveProcessState();
+  if (m_live_refresh_error.hasValue())
+    return std::make_shared<DecodedThread>(
+        thread.shared_from_this(),
+        createStringError(inconvertibleErrorCode(), *m_live_refresh_error));
+
+  auto it = m_thread_decoders.find(&thread);
+  if (it == m_thread_decoders.end())
+    return std::make_shared<DecodedThread>(
+        thread.shared_from_this(),
+        createStringError(inconvertibleErrorCode(), "thread not traced"));
+  return it->second->Decode();
 }
 
-size_t TraceIntelPT::GetCursorPosition(const Thread &thread) {
-  const DecodedThread *decoded_thread = Decode(thread);
-  if (!decoded_thread)
-    return 0;
-  return decoded_thread->GetCursorPosition();
+lldb::TraceCursorUP TraceIntelPT::GetCursor(Thread &thread) {
+  return Decode(thread)->GetCursor();
 }
 
-void TraceIntelPT::TraverseInstructions(
-    const Thread &thread, size_t position, TraceDirection direction,
-    std::function<bool(size_t index, Expected<lldb::addr_t> load_addr)>
-        callback) {
-  const DecodedThread *decoded_thread = Decode(thread);
-  if (!decoded_thread)
+void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) {
+  Optional<size_t> raw_size = GetRawTraceSize(thread);
+  s.Printf("\nthread #%u: tid = %" PRIu64, thread.GetIndexID(), thread.GetID());
+  if (!raw_size) {
+    s.Printf(", not traced\n");
     return;
-
-  ArrayRef<IntelPTInstruction> instructions = decoded_thread->GetInstructions();
-
-  ssize_t delta = direction == TraceDirection::Forwards ? 1 : -1;
-  for (ssize_t i = position; i < (ssize_t)instructions.size() && i >= 0;
-       i += delta)
-    if (!callback(i, instructions[i].GetLoadAddress()))
-      break;
+  }
+  s.Printf("\n  Raw trace size: %zu bytes\n", *raw_size);
+  return;
 }
 
-size_t TraceIntelPT::GetInstructionCount(const Thread &thread) {
-  if (const DecodedThread *decoded_thread = Decode(thread))
-    return decoded_thread->GetInstructions().size();
+Optional<size_t> TraceIntelPT::GetRawTraceSize(Thread &thread) {
+  if (IsTraced(thread))
+    return Decode(thread)->GetRawTraceSize();
   else
-    return 0;
+    return None;
+}
+
+Expected<pt_cpu> TraceIntelPT::GetCPUInfoForLiveProcess() {
+  Expected<std::vector<uint8_t>> cpu_info = GetLiveProcessBinaryData("cpuInfo");
+  if (!cpu_info)
+    return cpu_info.takeError();
+
+  int64_t cpu_family = -1;
+  int64_t model = -1;
+  int64_t stepping = -1;
+  std::string vendor_id;
+
+  StringRef rest(reinterpret_cast<const char *>(cpu_info->data()),
+                 cpu_info->size());
+  while (!rest.empty()) {
+    StringRef line;
+    std::tie(line, rest) = rest.split('\n');
+
+    SmallVector<StringRef, 2> columns;
+    line.split(columns, StringRef(":"), -1, false);
+
+    if (columns.size() < 2)
+      continue; // continue searching
+
+    columns[1] = columns[1].trim(" ");
+    if (columns[0].contains("cpu family") &&
+        columns[1].getAsInteger(10, cpu_family))
+      continue;
+
+    else if (columns[0].contains("model") && columns[1].getAsInteger(10, model))
+      continue;
+
+    else if (columns[0].contains("stepping") &&
+             columns[1].getAsInteger(10, stepping))
+      continue;
+
+    else if (columns[0].contains("vendor_id")) {
+      vendor_id = columns[1].str();
+      if (!vendor_id.empty())
+        continue;
+    }
+
+    if ((cpu_family != -1) && (model != -1) && (stepping != -1) &&
+        (!vendor_id.empty())) {
+      return pt_cpu{vendor_id == "GenuineIntel" ? pcv_intel : pcv_unknown,
+                    static_cast<uint16_t>(cpu_family),
+                    static_cast<uint8_t>(model),
+                    static_cast<uint8_t>(stepping)};
+    }
+  }
+  return createStringError(inconvertibleErrorCode(),
+                           "Failed parsing the target's /proc/cpuinfo file");
+}
+
+Expected<pt_cpu> TraceIntelPT::GetCPUInfo() {
+  if (!m_cpu_info) {
+    if (llvm::Expected<pt_cpu> cpu_info = GetCPUInfoForLiveProcess())
+      m_cpu_info = *cpu_info;
+    else
+      return cpu_info.takeError();
+  }
+  return *m_cpu_info;
+}
+
+void TraceIntelPT::DoRefreshLiveProcessState(
+    Expected<TraceGetStateResponse> state) {
+  m_thread_decoders.clear();
+
+  if (!state) {
+    m_live_refresh_error = toString(state.takeError());
+    return;
+  }
+
+  for (const TraceThreadState &thread_state : state->tracedThreads) {
+    Thread &thread =
+        *m_live_process->GetThreadList().FindThreadByID(thread_state.tid);
+    m_thread_decoders.emplace(
+        &thread, std::make_unique<LiveThreadDecoder>(thread, *this));
+  }
+}
+
+bool TraceIntelPT::IsTraced(const Thread &thread) {
+  RefreshLiveProcessState();
+  return m_thread_decoders.count(&thread);
+}
+
+// The information here should match the description of the intel-pt section
+// of the jLLDBTraceStart packet in the lldb/docs/lldb-gdb-remote.txt
+// documentation file. Similarly, it should match the CLI help messages of the
+// TraceIntelPTOptions.td file.
+const char *TraceIntelPT::GetStartConfigurationHelp() {
+  return R"(Parameters:
+
+  Note: If a parameter is not specified, a default value will be used.
+
+  - int threadBufferSize (defaults to 4096 bytes):
+    [process and thread tracing]
+    Trace size in bytes per thread. It must be a power of 2 greater
+    than or equal to 4096 (2^12). The trace is circular keeping the
+    the most recent data.
+
+  - boolean enableTsc (default to false):
+    [process and thread tracing]
+    Whether to use enable TSC timestamps or not. This is supported on
+    all devices that support intel-pt.
+
+  - psbPeriod (defaults to null):
+    [process and thread tracing]
+    This value defines the period in which PSB packets will be generated.
+    A PSB packet is a synchronization packet that contains a TSC
+    timestamp and the current absolute instruction pointer.
+
+    This parameter can only be used if
+
+        /sys/bus/event_source/devices/intel_pt/caps/psb_cyc
+
+    is 1. Otherwise, the PSB period will be defined by the processor.
+
+    If supported, valid values for this period can be found in
+
+        /sys/bus/event_source/devices/intel_pt/caps/psb_periods
+
+    which contains a hexadecimal number, whose bits represent
+    valid values e.g. if bit 2 is set, then value 2 is valid.
+
+    The psb_period value is converted to the approximate number of
+    raw trace bytes between PSB packets as:
+
+        2 ^ (value + 11)
+
+    e.g. value 3 means 16KiB between PSB packets. Defaults to 0 if
+    supported.
+
+  - int processBufferSizeLimit (defaults to 500 MB):
+    [process tracing only]
+    Maximum total trace size per process in bytes. This limit applies
+    to the sum of the sizes of all thread traces of this process,
+    excluding the ones created explicitly with "thread tracing".
+    Whenever a thread is attempted to be traced due to this command
+    and the limit would be reached, the process is stopped with a
+    "processor trace" reason, so that the user can retrace the process
+    if needed.)";
+}
+
+Error TraceIntelPT::Start(size_t thread_buffer_size,
+                          size_t total_buffer_size_limit, bool enable_tsc,
+                          Optional<size_t> psb_period) {
+  TraceIntelPTStartRequest request;
+  request.threadBufferSize = thread_buffer_size;
+  request.processBufferSizeLimit = total_buffer_size_limit;
+  request.enableTsc = enable_tsc;
+  request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; });
+  request.type = GetPluginName().AsCString();
+  return Trace::Start(toJSON(request));
+}
+
+Error TraceIntelPT::Start(StructuredData::ObjectSP configuration) {
+  size_t thread_buffer_size = kDefaultThreadBufferSize;
+  size_t process_buffer_size_limit = kDefaultProcessBufferSizeLimit;
+  bool enable_tsc = kDefaultEnableTscValue;
+  Optional<size_t> psb_period = kDefaultPsbPeriod;
+
+  if (configuration) {
+    if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+      dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+      dict->GetValueForKeyAsInteger("processBufferSizeLimit",
+                                    process_buffer_size_limit);
+      dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc);
+      dict->GetValueForKeyAsInteger("psbPeriod", psb_period);
+    } else {
+      return createStringError(inconvertibleErrorCode(),
+                               "configuration object is not a dictionary");
+    }
+  }
+
+  return Start(thread_buffer_size, process_buffer_size_limit, enable_tsc,
+               psb_period);
+}
+
+llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
+                                size_t thread_buffer_size, bool enable_tsc,
+                                Optional<size_t> psb_period) {
+  TraceIntelPTStartRequest request;
+  request.threadBufferSize = thread_buffer_size;
+  request.enableTsc = enable_tsc;
+  request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; });
+  request.type = GetPluginName().AsCString();
+  request.tids.emplace();
+  for (lldb::tid_t tid : tids)
+    request.tids->push_back(tid);
+  return Trace::Start(toJSON(request));
+}
+
+Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
+                          StructuredData::ObjectSP configuration) {
+  size_t thread_buffer_size = kDefaultThreadBufferSize;
+  bool enable_tsc = kDefaultEnableTscValue;
+  Optional<size_t> psb_period = kDefaultPsbPeriod;
+
+  if (configuration) {
+    if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+      dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+      dict->GetValueForKeyAsBoolean("enableTsc", enable_tsc);
+      dict->GetValueForKeyAsInteger("psbPeriod", psb_period);
+    } else {
+      return createStringError(inconvertibleErrorCode(),
+                               "configuration object is not a dictionary");
+    }
+  }
+
+  return Start(tids, thread_buffer_size, enable_tsc, psb_period);
+}
+
+Expected<std::vector<uint8_t>>
+TraceIntelPT::GetLiveThreadBuffer(lldb::tid_t tid) {
+  return Trace::GetLiveThreadBinaryData(tid, "threadTraceBuffer");
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
index 5058e6f..e3b2471 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -45,49 +45,134 @@
   /// \return
   ///     A trace instance or an error in case of failures.
   static llvm::Expected<lldb::TraceSP>
-  CreateInstance(const llvm::json::Value &trace_session_file,
-                 llvm::StringRef session_file_dir, Debugger &debugger);
+  CreateInstanceForSessionFile(const llvm::json::Value &trace_session_file,
+                               llvm::StringRef session_file_dir,
+                               Debugger &debugger);
+
+  static llvm::Expected<lldb::TraceSP>
+  CreateInstanceForLiveProcess(Process &process);
 
   static ConstString GetPluginNameStatic();
 
   uint32_t GetPluginVersion() override;
   /// \}
 
+  lldb::CommandObjectSP
+  GetProcessTraceStartCommand(CommandInterpreter &interpreter) override;
+
+  lldb::CommandObjectSP
+  GetThreadTraceStartCommand(CommandInterpreter &interpreter) override;
+
   llvm::StringRef GetSchema() override;
 
-  void TraverseInstructions(
-      const Thread &thread, size_t position, TraceDirection direction,
-      std::function<bool(size_t index, llvm::Expected<lldb::addr_t> load_addr)>
-          callback) override;
+  lldb::TraceCursorUP GetCursor(Thread &thread) override;
 
-  size_t GetInstructionCount(const Thread &thread) override;
+  void DumpTraceInfo(Thread &thread, Stream &s, bool verbose) override;
 
-  size_t GetCursorPosition(const Thread &thread) override;
+  llvm::Optional<size_t> GetRawTraceSize(Thread &thread);
+
+  void DoRefreshLiveProcessState(
+      llvm::Expected<TraceGetStateResponse> state) override;
+
+  bool IsTraced(const Thread &thread) override;
+
+  const char *GetStartConfigurationHelp() override;
+
+  /// Start tracing a live process.
+  ///
+  /// \param[in] thread_buffer_size
+  ///     Trace size per thread in bytes.
+  ///
+  /// \param[in] total_buffer_size_limit
+  ///     Maximum total trace size per process in bytes.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \param[in] enable_tsc
+  ///     Whether to use enable TSC timestamps or not.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \param[in] psb_period
+  ///
+  ///     This value defines the period in which PSB packets will be generated.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp();
+  ///
+  /// \return
+  ///     \a llvm::Error::success if the operation was successful, or
+  ///     \a llvm::Error otherwise.
+  llvm::Error Start(size_t thread_buffer_size, size_t total_buffer_size_limit,
+                    bool enable_tsc, llvm::Optional<size_t> psb_period);
+
+  /// \copydoc Trace::Start
+  llvm::Error Start(StructuredData::ObjectSP configuration =
+                        StructuredData::ObjectSP()) override;
+
+  /// Start tracing live threads.
+  ///
+  /// \param[in] tids
+  ///     Threads to trace.
+  ///
+  /// \param[in] thread_buffer_size
+  ///     Trace size per thread in bytes.
+  ///
+  /// \param[in] enable_tsc
+  ///     Whether to use enable TSC timestamps or not.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \param[in] psb_period
+  ///
+  ///     This value defines the period in which PSB packets will be generated.
+  ///     More information in TraceIntelPT::GetStartConfigurationHelp().
+  ///
+  /// \return
+  ///     \a llvm::Error::success if the operation was successful, or
+  ///     \a llvm::Error otherwise.
+  llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids, size_t thread_buffer_size,
+                    bool enable_tsc, llvm::Optional<size_t> psb_period);
+
+  /// \copydoc Trace::Start
+  llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,
+                    StructuredData::ObjectSP configuration =
+                        StructuredData::ObjectSP()) override;
+
+  /// Get the thread buffer content for a live thread
+  llvm::Expected<std::vector<uint8_t>> GetLiveThreadBuffer(lldb::tid_t tid);
+
+  llvm::Expected<pt_cpu> GetCPUInfo();
 
 private:
   friend class TraceIntelPTSessionFileParser;
 
+  llvm::Expected<pt_cpu> GetCPUInfoForLiveProcess();
+
   /// \param[in] trace_threads
   ///     ThreadTrace instances, which are not live-processes and whose trace
   ///     files are fixed.
-  TraceIntelPT(const pt_cpu &pt_cpu,
-               const std::vector<std::shared_ptr<ThreadTrace>> &traced_threads);
+  TraceIntelPT(
+      const pt_cpu &cpu_info,
+      const std::vector<lldb::ThreadPostMortemTraceSP> &traced_threads);
+
+  /// Constructor for live processes
+  TraceIntelPT(Process &live_process)
+      : Trace(live_process), m_thread_decoders(){};
 
   /// Decode the trace of the given thread that, i.e. recontruct the traced
-  /// instructions. That trace must be managed by this class.
+  /// instructions.
   ///
   /// \param[in] thread
   ///     If \a thread is a \a ThreadTrace, then its internal trace file will be
   ///     decoded. Live threads are not currently supported.
   ///
   /// \return
-  ///     A \a DecodedThread instance if decoding was successful, or a \b
-  ///     nullptr if the thread's trace is not managed by this class.
-  const DecodedThread *Decode(const Thread &thread);
+  ///     A \a DecodedThread shared pointer with the decoded instructions. Any
+  ///     errors are embedded in the instruction list.
+  DecodedThreadSP Decode(Thread &thread);
 
-  pt_cpu m_pt_cpu;
-  std::map<std::pair<lldb::pid_t, lldb::tid_t>, ThreadTraceDecoder>
-      m_trace_threads;
+  /// It is provided by either a session file or a live process' "cpuInfo"
+  /// binary data.
+  llvm::Optional<pt_cpu> m_cpu_info;
+  std::map<const Thread *, std::unique_ptr<ThreadDecoder>> m_thread_decoders;
+  /// Error gotten after a failed live process update, if any.
+  llvm::Optional<std::string> m_live_refresh_error;
 };
 
 } // namespace trace_intel_pt
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
new file mode 100644
index 0000000..c2bc1b5
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
@@ -0,0 +1,27 @@
+//===-- TraceIntelPTConstants.h ---------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+
+#include <cstddef>
+
+#include <llvm/ADT/Optional.h>
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+const size_t kDefaultThreadBufferSize = 4 * 1024;              // 4KB
+const size_t kDefaultProcessBufferSizeLimit = 5 * 1024 * 1024; // 500MB
+const bool kDefaultEnableTscValue = false;
+const llvm::Optional<size_t> kDefaultPsbPeriod = llvm::None;
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
index 6ffe949..9e8cab1 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
@@ -1,16 +1,74 @@
 include "../../../../source/Commands/OptionsBase.td"
 
+// The information of the start commands here should match the description of
+// the intel-pt section of the jLLDBTraceStart packet in the
+// lldb/docs/lldb-gdb-remote.txt documentation file. Similarly, it should match
+// the API help message of TraceIntelPT::GetStartConfigurationHelp().
+
 let Command = "thread trace start intel pt" in {
   def thread_trace_start_intel_pt_size: Option<"size", "s">,
     Group<1>,
     Arg<"Value">,
-    Desc<"The size of the trace in KB. The kernel rounds it down to the nearest"
-         " multiple of 4. Defaults to 4.">;
-  def thread_trace_start_intel_pt_custom_config: Option<"custom-config", "c">,
+    Desc<"Trace size in bytes per thread. It must be a power of 2 greater "
+         "than or equal to 4096 (2^12). The trace is circular keeping "
+         "the most recent data. Defaults to 4096 bytes.">;
+  def thread_trace_start_intel_pt_tsc: Option<"tsc", "t">,
+    Group<1>,
+    Desc<"Enable the use of TSC timestamps. This is supported on all devices "
+         "that support intel-pt.">;
+  def thread_trace_start_intel_pt_psb_period: Option<"psb-period", "p">,
     Group<1>,
     Arg<"Value">,
-    Desc<"Low level bitmask configuration for the kernel based on the values "
-         "in `grep -H  /sys/bus/event_source/devices/intel_pt/format/*`. "
-         "See https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf-intel-pt.txt"
-         " for more information. Defaults to 0.">;
+    Desc<"This value defines the period in which PSB packets will be "
+         "generated. A PSB packet is a synchronization packet that contains a "
+         "TSC timestamp and the current absolute instruction pointer. "
+         "This parameter can only be used if "
+         "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, "
+         "the PSB period will be defined by the processor. If supported, valid "
+         "values for this period can be found in "
+         "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which "
+         "contains a hexadecimal number, whose bits represent valid values "
+         "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is "
+         "converted to the approximate number of raw trace bytes between PSB "
+         "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB "
+         "packets. Defaults to 0 if supported.">;
+}
+
+let Command = "process trace start intel pt" in {
+  def process_trace_start_intel_pt_thread_size: Option<"thread-size", "s">,
+    Group<1>,
+    Arg<"Value">,
+    Desc<"Trace size in bytes per thread. It must be a power of 2 greater "
+         "than or equal to 4096 (2^12). The trace is circular keeping "
+         "the most recent data. Defaults to 4096 bytes.">;
+  def process_trace_start_intel_pt_process_size_limit: Option<"total-size-limit", "l">,
+    Group<1>,
+    Arg<"Value">,
+    Desc<"Maximum total trace size per process in bytes. This limit applies to "
+         "the sum of the sizes of all thread traces of this process, excluding "
+         "the ones created with the \"thread trace start\" command. "
+         "Whenever a thread is attempted to be traced due to this command and "
+         "the limit would be reached, the process is stopped with a "
+         "\"processor trace\" reason, so that the user can retrace the process "
+         "if needed. Defaults to 500MB.">;
+  def process_trace_start_intel_pt_tsc: Option<"tsc", "t">,
+    Group<1>,
+    Desc<"Enable the use of TSC timestamps. This is supported on all devices "
+         "that support intel-pt.">;
+  def process_trace_start_intel_pt_psb_period: Option<"psb-period", "p">,
+    Group<1>,
+    Arg<"Value">,
+    Desc<"This value defines the period in which PSB packets will be "
+         "generated. A PSB packet is a synchronization packet that contains a "
+         "TSC timestamp and the current absolute instruction pointer. "
+         "This parameter can only be used if "
+         "/sys/bus/event_source/devices/intel_pt/caps/psb_cyc is 1. Otherwise, "
+         "the PSB period will be defined by the processor. If supported, valid "
+         "values for this period can be found in "
+         "/sys/bus/event_source/devices/intel_pt/caps/psb_periods which "
+         "contains a hexadecimal number, whose bits represent valid values "
+         "e.g. if bit 2 is set, then value 2 is valid. The psb_period value is "
+         "converted to the approximate number of raw trace bytes between PSB "
+         "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB "
+         "packets. Defaults to 0 if supported.">;
 }
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
index beef5c3..5af7c26 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
@@ -8,11 +8,11 @@
 
 #include "TraceIntelPTSessionFileParser.h"
 
+#include "../common/ThreadPostMortemTrace.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/ThreadList.h"
-#include "lldb/Target/ThreadTrace.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -24,7 +24,7 @@
   if (schema.empty()) {
     schema = TraceSessionFileParser::BuildSchema(R"({
     "type": "intel-pt",
-    "pt_cpu": {
+    "cpuInfo": {
       "vendor": "intel" | "unknown",
       "family": integer,
       "model": integer,
@@ -35,21 +35,22 @@
   return schema;
 }
 
-pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(const JSONPTCPU &pt_cpu) {
-  return {pt_cpu.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
-          static_cast<uint16_t>(pt_cpu.family),
-          static_cast<uint8_t>(pt_cpu.model),
-          static_cast<uint8_t>(pt_cpu.stepping)};
+pt_cpu TraceIntelPTSessionFileParser::ParsePTCPU(
+    const JSONTraceIntelPTCPUInfo &cpu_info) {
+  return {cpu_info.vendor.compare("intel") == 0 ? pcv_intel : pcv_unknown,
+          static_cast<uint16_t>(cpu_info.family),
+          static_cast<uint8_t>(cpu_info.model),
+          static_cast<uint8_t>(cpu_info.stepping)};
 }
 
 TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance(
-    const pt_cpu &pt_cpu, std::vector<ParsedProcess> &parsed_processes) {
-  std::vector<ThreadTraceSP> threads;
+    const pt_cpu &cpu_info, std::vector<ParsedProcess> &parsed_processes) {
+  std::vector<ThreadPostMortemTraceSP> threads;
   for (const ParsedProcess &parsed_process : parsed_processes)
     threads.insert(threads.end(), parsed_process.threads.begin(),
                    parsed_process.threads.end());
 
-  TraceSP trace_instance(new TraceIntelPT(pt_cpu, threads));
+  TraceSP trace_instance(new TraceIntelPT(cpu_info, threads));
   for (const ParsedProcess &parsed_process : parsed_processes)
     parsed_process.target_sp->SetTrace(trace_instance);
 
@@ -64,7 +65,7 @@
 
   if (Expected<std::vector<ParsedProcess>> parsed_processes =
           ParseCommonSessionFile(session))
-    return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.pt_cpu),
+    return CreateTraceIntelPTInstance(ParsePTCPU(session.trace.cpuInfo),
                                       *parsed_processes);
   else
     return parsed_processes.takeError();
@@ -73,25 +74,34 @@
 namespace llvm {
 namespace json {
 
-bool fromJSON(const Value &value,
-              TraceIntelPTSessionFileParser::JSONPTCPU &pt_cpu, Path path) {
-  ObjectMapper o(value, path);
-  return o && o.map("vendor", pt_cpu.vendor) &&
-         o.map("family", pt_cpu.family) && o.map("model", pt_cpu.model) &&
-         o.map("stepping", pt_cpu.stepping);
-}
-
 bool fromJSON(
     const Value &value,
     TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings,
     Path path) {
   ObjectMapper o(value, path);
-  return o && o.map("pt_cpu", plugin_settings.pt_cpu) &&
+  return o && o.map("cpuInfo", plugin_settings.cpuInfo) &&
          fromJSON(
              value,
              (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings,
              path);
 }
 
+bool fromJSON(const json::Value &value,
+              TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info,
+              Path path) {
+  ObjectMapper o(value, path);
+  return o && o.map("vendor", cpu_info.vendor) &&
+         o.map("family", cpu_info.family) && o.map("model", cpu_info.model) &&
+         o.map("stepping", cpu_info.stepping);
+}
+
+Value toJSON(
+    const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) {
+  return Value(Object{{"family", cpu_info.family},
+                      {"model", cpu_info.model},
+                      {"stepping", cpu_info.stepping},
+                      {"vendor", cpu_info.vendor}});
+}
+
 } // namespace json
 } // namespace llvm
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
index 6a896de..b2667a8 100644
--- a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h
@@ -10,7 +10,8 @@
 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H
 
 #include "TraceIntelPT.h"
-#include "lldb/Target/TraceSessionFileParser.h"
+
+#include "../common/TraceSessionFileParser.h"
 
 namespace lldb_private {
 namespace trace_intel_pt {
@@ -19,16 +20,16 @@
 
 class TraceIntelPTSessionFileParser : public TraceSessionFileParser {
 public:
-  struct JSONPTCPU {
-    std::string vendor;
+  struct JSONTraceIntelPTCPUInfo {
     int64_t family;
     int64_t model;
     int64_t stepping;
+    std::string vendor;
   };
 
   struct JSONTraceIntelPTSettings
       : TraceSessionFileParser::JSONTracePluginSettings {
-    JSONPTCPU pt_cpu;
+    JSONTraceIntelPTCPUInfo cpuInfo;
   };
 
   /// See \a TraceSessionFileParser::TraceSessionFileParser for the description
@@ -52,11 +53,11 @@
   llvm::Expected<lldb::TraceSP> Parse();
 
   lldb::TraceSP
-  CreateTraceIntelPTInstance(const pt_cpu &pt_cpu,
+  CreateTraceIntelPTInstance(const pt_cpu &cpu_info,
                              std::vector<ParsedProcess> &parsed_processes);
 
 private:
-  pt_cpu ParsePTCPU(const JSONPTCPU &pt_cpu);
+  static pt_cpu ParsePTCPU(const JSONTraceIntelPTCPUInfo &cpu_info);
 
   const llvm::json::Value &m_trace_session_file;
 };
@@ -67,17 +68,20 @@
 namespace llvm {
 namespace json {
 
-bool fromJSON(
-    const Value &value,
-    lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::JSONPTCPU
-        &pt_cpu,
-    Path path);
-
 bool fromJSON(const Value &value,
               lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
                   JSONTraceIntelPTSettings &plugin_settings,
               Path path);
 
+bool fromJSON(const llvm::json::Value &value,
+              lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
+                  JSONTraceIntelPTCPUInfo &packet,
+              llvm::json::Path path);
+
+llvm::json::Value
+toJSON(const lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser::
+           JSONTraceIntelPTCPUInfo &packet);
+
 } // namespace json
 } // namespace llvm
 
diff --git a/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h
new file mode 100644
index 0000000..3c5f811
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/Trace/intel-pt/forward-declarations.h
@@ -0,0 +1,20 @@
+//===-- forward-declarations.h ----------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+class TraceIntelPT;
+class ThreadDecoder;
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_FORWARD_DECLARATIONS_H
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/TraceExporter/CMakeLists.txt
new file mode 100644
index 0000000..7c40191
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(ctf)
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
new file mode 100644
index 0000000..766cc18
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CMakeLists.txt
@@ -0,0 +1,17 @@
+lldb_tablegen(TraceExporterCTFCommandOptions.inc -gen-lldb-option-defs
+  SOURCE TraceExporterCTFOptions.td
+  TARGET TraceExporterCTFOptionsGen)
+
+add_lldb_library(lldbPluginTraceExporterCTF PLUGIN
+CommandObjectThreadTraceExportCTF.cpp
+  TraceExporterCTF.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbSymbol
+    lldbTarget
+  LINK_COMPONENTS
+    Support
+  )
+
+add_dependencies(lldbPluginTraceExporterCTF TraceExporterCTFOptionsGen)
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
new file mode 100644
index 0000000..3dd4c89
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp
@@ -0,0 +1,66 @@
+//===-- CommandObjectThreadTraceExportCTF.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 "CommandObjectThreadTraceExportCTF.h"
+
+#include "lldb/Host/OptionParser.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+// CommandObjectThreadTraceExportCTF
+
+#define LLDB_OPTIONS_thread_trace_export_ctf
+#include "TraceExporterCTFCommandOptions.inc"
+
+Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue(
+    uint32_t option_idx, llvm::StringRef option_arg,
+    ExecutionContext *execution_context) {
+  Status error;
+  const int short_option = m_getopt_table[option_idx].val;
+
+  switch (short_option) {
+  case 't': {
+    int64_t thread_index;
+    if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) ||
+        thread_index < 0)
+      error.SetErrorStringWithFormat("invalid integer value for option '%s'",
+                                     option_arg.str().c_str());
+    else
+      m_thread_index = thread_index;
+    break;
+  }
+  default:
+    llvm_unreachable("Unimplemented option");
+  }
+  return error;
+}
+
+void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting(
+    ExecutionContext *execution_context) {
+  m_thread_index = None;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() {
+  return llvm::makeArrayRef(g_thread_trace_export_ctf_options);
+}
+
+bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command,
+                                                  CommandReturnObject &result) {
+  Stream &s = result.GetOutputStream();
+  // TODO: create an actual instance of the exporter and invoke it
+  if (m_options.m_thread_index)
+    s.Printf("got thread index %d\n", (int)m_options.m_thread_index.getValue());
+  else
+    s.Printf("didn't get a thread index\n");
+
+  return result.Succeeded();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
new file mode 100644
index 0000000..26b068a
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h
@@ -0,0 +1,56 @@
+//===-- CommandObjectThreadTraceExportCTF.h -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
+
+#include "TraceExporterCTF.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+namespace lldb_private {
+namespace ctf {
+
+class CommandObjectThreadTraceExportCTF : public CommandObjectParsed {
+public:
+  class CommandOptions : public Options {
+  public:
+    CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override;
+
+    void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+    llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+    llvm::Optional<size_t> m_thread_index;
+  };
+
+  CommandObjectThreadTraceExportCTF(CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "thread trace export ctf",
+            "Export a given thread's trace to Chrome Trace Format",
+            "thread trace export ctf [<ctf-options>]",
+            lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock |
+                lldb::eCommandProcessMustBeLaunched |
+                lldb::eCommandProcessMustBePaused),
+        m_options() {}
+
+  Options *GetOptions() override { return &m_options; }
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+  CommandOptions m_options;
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_COMMANDOBJECTTHREADTRACEEXPORTCTF_H
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
new file mode 100644
index 0000000..08bc03d
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp
@@ -0,0 +1,53 @@
+//===-- TraceExporterCTF.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 "TraceExporterCTF.h"
+
+#include <memory>
+
+#include "CommandObjectThreadTraceExportCTF.h"
+#include "lldb/Core/PluginManager.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::ctf;
+using namespace llvm;
+
+LLDB_PLUGIN_DEFINE(TraceExporterCTF)
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+
+static CommandObjectSP
+GetThreadTraceExportCommand(CommandInterpreter &interpreter) {
+  return std::make_shared<CommandObjectThreadTraceExportCTF>(interpreter);
+}
+
+void TraceExporterCTF::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                "Chrome Trace Format Exporter", CreateInstance,
+                                GetThreadTraceExportCommand);
+}
+
+void TraceExporterCTF::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString TraceExporterCTF::GetPluginNameStatic() {
+  static ConstString g_name("ctf");
+  return g_name;
+}
+
+ConstString TraceExporterCTF::GetPluginName() { return GetPluginNameStatic(); }
+
+uint32_t TraceExporterCTF::GetPluginVersion() { return 1; }
+
+Expected<TraceExporterUP> TraceExporterCTF::CreateInstance() {
+  return std::make_unique<TraceExporterCTF>();
+}
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
new file mode 100644
index 0000000..8f9e354
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h
@@ -0,0 +1,42 @@
+//===-- TraceExporterCTF.h --------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+#define LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
+
+#include "lldb/Target/TraceExporter.h"
+
+namespace lldb_private {
+namespace ctf {
+
+/// Trace Exporter Plugin that can produce traces in Chrome Trace Format.
+/// Still in development.
+class TraceExporterCTF : public TraceExporter {
+public:
+  ~TraceExporterCTF() override = default;
+
+  /// PluginInterface protocol
+  /// \{
+  static llvm::Expected<lldb::TraceExporterUP> CreateInstance();
+
+  ConstString GetPluginName() override;
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static ConstString GetPluginNameStatic();
+
+  uint32_t GetPluginVersion() override;
+  /// \}
+};
+
+} // namespace ctf
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_EXPORTER_CTF_H
diff --git a/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
new file mode 100644
index 0000000..ce751f1
--- /dev/null
+++ b/src/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td
@@ -0,0 +1,9 @@
+include "../../../../source/Commands/OptionsBase.td"
+
+let Command = "thread trace export ctf" in {
+  def thread_trace_export_ctf: Option<"tid", "t">,
+    Group<1>,
+    Arg<"ThreadIndex">,
+    Desc<"Export the trace for the specified thread index. Otherwise, the "
+         "currently selected thread will be used.">;
+}
diff --git a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index c15b15e..7150fdc 100644
--- a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -75,7 +75,7 @@
 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
 #include "Plugins/SymbolFile/PDB/PDBASTParser.h"
 
-#include <stdio.h>
+#include <cstdio>
 
 #include <mutex>
 
@@ -163,7 +163,6 @@
           if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
             if (auto *baseDtorDecl = base_record->getDestructor()) {
               if (baseDtorDecl->isVirtual()) {
-                path.Decls = baseDtorDecl;
                 decls.push_back(baseDtorDecl);
                 return true;
               } else
@@ -171,12 +170,11 @@
             }
 
           // Otherwise, search for name in the base class.
-          for (path.Decls = base_record->lookup(name); !path.Decls.empty();
-               path.Decls = path.Decls.slice(1)) {
+          for (path.Decls = base_record->lookup(name).begin();
+               path.Decls != path.Decls.end(); ++path.Decls) {
             if (auto *method_decl =
-                    llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
+                    llvm::dyn_cast<clang::CXXMethodDecl>(*path.Decls))
               if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
-                path.Decls = method_decl;
                 decls.push_back(method_decl);
                 return true;
               }
@@ -479,6 +477,9 @@
     case clang::Language::OpenCL:
       LangStd = LangStandard::lang_opencl10;
       break;
+    case clang::Language::OpenCLCXX:
+      LangStd = LangStandard::lang_openclcpp;
+      break;
     case clang::Language::CUDA:
       LangStd = LangStandard::lang_cuda;
       break;
@@ -686,8 +687,8 @@
 void TypeSystemClang::SetExternalSource(
     llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) {
   ASTContext &ast = getASTContext();
-  ast.setExternalSource(ast_source_up);
   ast.getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+  ast.setExternalSource(ast_source_up);
 }
 
 ASTContext &TypeSystemClang::getASTContext() {
@@ -745,7 +746,7 @@
       *m_diagnostics_engine_up, *m_file_manager_up);
   m_ast_up = std::make_unique<ASTContext>(
       *m_language_options_up, *m_source_manager_up, *m_identifier_table_up,
-      *m_selector_table_up, *m_builtins_up);
+      *m_selector_table_up, *m_builtins_up, TU_Complete);
 
   m_diagnostic_consumer_up = std::make_unique<NullDiagnosticConsumer>();
   m_ast_up->getDiagnostics().setClient(m_diagnostic_consumer_up.get(), false);
@@ -1356,9 +1357,11 @@
 }
 
 namespace {
-  bool IsValueParam(const clang::TemplateArgument &argument) {
-    return argument.getKind() == TemplateArgument::Integral;
-  }
+/// Returns true iff the given TemplateArgument should be represented as an
+/// NonTypeTemplateParmDecl in the AST.
+bool IsValueParam(const clang::TemplateArgument &argument) {
+  return argument.getKind() == TemplateArgument::Integral;
+}
 }
 
 static TemplateParameterList *CreateTemplateParameterList(
@@ -1462,6 +1465,99 @@
                                                template_args_ptr, nullptr);
 }
 
+/// Returns true if the given template parameter can represent the given value.
+/// For example, `typename T` can represent `int` but not integral values such
+/// as `int I = 3`.
+static bool TemplateParameterAllowsValue(NamedDecl *param,
+                                         const TemplateArgument &value) {
+  if (auto *type_param = llvm::dyn_cast<TemplateTypeParmDecl>(param)) {
+    // Compare the argument kind, i.e. ensure that <typename> != <int>.
+    if (value.getKind() != TemplateArgument::Type)
+      return false;
+  } else if (auto *type_param =
+                 llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) {
+    // Compare the argument kind, i.e. ensure that <typename> != <int>.
+    if (!IsValueParam(value))
+      return false;
+    // Compare the integral type, i.e. ensure that <int> != <char>.
+    if (type_param->getType() != value.getIntegralType())
+      return false;
+  } else {
+    // There is no way to create other parameter decls at the moment, so we
+    // can't reach this case during normal LLDB usage. Log that this happened
+    // and assert.
+    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+    LLDB_LOG(log,
+             "Don't know how to compare template parameter to passed"
+             " value. Decl kind of parameter is: {0}",
+             param->getDeclKindName());
+    lldbassert(false && "Can't compare this TemplateParmDecl subclass");
+    // In release builds just fall back to marking the parameter as not
+    // accepting the value so that we don't try to fit an instantiation to a
+    // template that doesn't fit. E.g., avoid that `S<1>` is being connected to
+    // `template<typename T> struct S;`.
+    return false;
+  }
+  return true;
+}
+
+/// Returns true if the given class template declaration could produce an
+/// instantiation with the specified values.
+/// For example, `<typename T>` allows the arguments `float`, but not for
+/// example `bool, float` or `3` (as an integer parameter value).
+static bool ClassTemplateAllowsToInstantiationArgs(
+    ClassTemplateDecl *class_template_decl,
+    const TypeSystemClang::TemplateParameterInfos &instantiation_values) {
+
+  TemplateParameterList &params = *class_template_decl->getTemplateParameters();
+
+  // Save some work by iterating only once over the found parameters and
+  // calculate the information related to parameter packs.
+
+  // Contains the first pack parameter (or non if there are none).
+  llvm::Optional<NamedDecl *> pack_parameter;
+  // Contains the number of non-pack parameters.
+  size_t non_pack_params = params.size();
+  for (size_t i = 0; i < params.size(); ++i) {
+    NamedDecl *param = params.getParam(i);
+    if (param->isParameterPack()) {
+      pack_parameter = param;
+      non_pack_params = i;
+      break;
+    }
+  }
+
+  // The found template needs to have compatible non-pack template arguments.
+  // E.g., ensure that <typename, typename> != <typename>.
+  // The pack parameters are compared later.
+  if (non_pack_params != instantiation_values.args.size())
+    return false;
+
+  // Ensure that <typename...> != <typename>.
+  if (pack_parameter.hasValue() != instantiation_values.hasParameterPack())
+    return false;
+
+  // Compare the first pack parameter that was found with the first pack
+  // parameter value. The special case of having an empty parameter pack value
+  // always fits to a pack parameter.
+  // E.g., ensure that <int...> != <typename...>.
+  if (pack_parameter && !instantiation_values.packed_args->args.empty() &&
+      !TemplateParameterAllowsValue(
+          *pack_parameter, instantiation_values.packed_args->args.front()))
+    return false;
+
+  // Compare all the non-pack parameters now.
+  // E.g., ensure that <int> != <long>.
+  for (const auto pair : llvm::zip_first(instantiation_values.args, params)) {
+    const TemplateArgument &passed_arg = std::get<0>(pair);
+    NamedDecl *found_param = std::get<1>(pair);
+    if (!TemplateParameterAllowsValue(found_param, passed_arg))
+      return false;
+  }
+
+  return class_template_decl;
+}
+
 ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl(
     DeclContext *decl_ctx, OptionalClangModuleID owning_module,
     lldb::AccessType access_type, const char *class_name, int kind,
@@ -1475,12 +1571,22 @@
   IdentifierInfo &identifier_info = ast.Idents.get(class_name);
   DeclarationName decl_name(&identifier_info);
 
+  // Search the AST for an existing ClassTemplateDecl that could be reused.
   clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
-
   for (NamedDecl *decl : result) {
     class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
-    if (class_template_decl)
-      return class_template_decl;
+    if (!class_template_decl)
+      continue;
+    // The class template has to be able to represents the instantiation
+    // values we received. Without this we might end up putting an instantiation
+    // with arguments such as <int, int> to a template such as:
+    //     template<typename T> struct S;
+    // Connecting the instantiation to an incompatible template could cause
+    // problems later on.
+    if (!ClassTemplateAllowsToInstantiationArgs(class_template_decl,
+                                                template_param_infos))
+      continue;
+    return class_template_decl;
   }
 
   llvm::SmallVector<NamedDecl *, 8> template_param_decls;
@@ -1866,8 +1972,8 @@
         clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false);
     SetOwningModule(using_decl, owning_module);
     clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create(
-        getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl,
-        target);
+        getASTContext(), current_decl_ctx, clang::SourceLocation(),
+        target->getDeclName(), using_decl, target);
     SetOwningModule(shadow_decl, owning_module);
     using_decl->addShadowDecl(shadow_decl);
     current_decl_ctx->addDecl(using_decl);
@@ -2114,11 +2220,10 @@
   return decl;
 }
 
-void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl,
-                                            ParmVarDecl **params,
-                                            unsigned num_params) {
+void TypeSystemClang::SetFunctionParameters(
+    FunctionDecl *function_decl, llvm::ArrayRef<ParmVarDecl *> params) {
   if (function_decl)
-    function_decl->setParams(ArrayRef<ParmVarDecl *>(params, num_params));
+    function_decl->setParams(params);
 }
 
 CompilerType
@@ -2470,42 +2575,6 @@
   return nullptr;
 }
 
-bool TypeSystemClang::SetTagTypeKind(clang::QualType tag_qual_type,
-                                     int kind) const {
-  const clang::Type *clang_type = tag_qual_type.getTypePtr();
-  if (clang_type) {
-    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(clang_type);
-    if (tag_type) {
-      clang::TagDecl *tag_decl =
-          llvm::dyn_cast<clang::TagDecl>(tag_type->getDecl());
-      if (tag_decl) {
-        tag_decl->setTagKind((clang::TagDecl::TagKind)kind);
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-bool TypeSystemClang::SetDefaultAccessForRecordFields(
-    clang::RecordDecl *record_decl, int default_accessibility,
-    int *assigned_accessibilities, size_t num_assigned_accessibilities) {
-  if (record_decl) {
-    uint32_t field_idx;
-    clang::RecordDecl::field_iterator field, field_end;
-    for (field = record_decl->field_begin(),
-        field_end = record_decl->field_end(), field_idx = 0;
-         field != field_end; ++field, ++field_idx) {
-      // If no accessibility was assigned, assign the correct one
-      if (field_idx < num_assigned_accessibilities &&
-          assigned_accessibilities[field_idx] == clang::AS_none)
-        field->setAccess((clang::AccessSpecifier)default_accessibility);
-    }
-    return true;
-  }
-  return false;
-}
-
 clang::DeclContext *
 TypeSystemClang::GetDeclContextForType(const CompilerType &type) {
   return GetDeclContextForType(ClangUtil::GetQualType(type));
@@ -4697,7 +4766,6 @@
     case clang::BuiltinType::Void:
       break;
 
-    case clang::BuiltinType::Bool:
     case clang::BuiltinType::Char_S:
     case clang::BuiltinType::SChar:
     case clang::BuiltinType::WChar_S:
@@ -4708,6 +4776,7 @@
     case clang::BuiltinType::Int128:
       return lldb::eEncodingSint;
 
+    case clang::BuiltinType::Bool:
     case clang::BuiltinType::Char_U:
     case clang::BuiltinType::UChar:
     case clang::BuiltinType::WChar_U:
@@ -4889,6 +4958,75 @@
     case clang::BuiltinType::SveFloat64x4:
       break;
 
+    // RISC-V V builtin types.
+    case clang::BuiltinType::RvvInt8mf8:
+    case clang::BuiltinType::RvvInt8mf4:
+    case clang::BuiltinType::RvvInt8mf2:
+    case clang::BuiltinType::RvvInt8m1:
+    case clang::BuiltinType::RvvInt8m2:
+    case clang::BuiltinType::RvvInt8m4:
+    case clang::BuiltinType::RvvInt8m8:
+    case clang::BuiltinType::RvvUint8mf8:
+    case clang::BuiltinType::RvvUint8mf4:
+    case clang::BuiltinType::RvvUint8mf2:
+    case clang::BuiltinType::RvvUint8m1:
+    case clang::BuiltinType::RvvUint8m2:
+    case clang::BuiltinType::RvvUint8m4:
+    case clang::BuiltinType::RvvUint8m8:
+    case clang::BuiltinType::RvvInt16mf4:
+    case clang::BuiltinType::RvvInt16mf2:
+    case clang::BuiltinType::RvvInt16m1:
+    case clang::BuiltinType::RvvInt16m2:
+    case clang::BuiltinType::RvvInt16m4:
+    case clang::BuiltinType::RvvInt16m8:
+    case clang::BuiltinType::RvvUint16mf4:
+    case clang::BuiltinType::RvvUint16mf2:
+    case clang::BuiltinType::RvvUint16m1:
+    case clang::BuiltinType::RvvUint16m2:
+    case clang::BuiltinType::RvvUint16m4:
+    case clang::BuiltinType::RvvUint16m8:
+    case clang::BuiltinType::RvvInt32mf2:
+    case clang::BuiltinType::RvvInt32m1:
+    case clang::BuiltinType::RvvInt32m2:
+    case clang::BuiltinType::RvvInt32m4:
+    case clang::BuiltinType::RvvInt32m8:
+    case clang::BuiltinType::RvvUint32mf2:
+    case clang::BuiltinType::RvvUint32m1:
+    case clang::BuiltinType::RvvUint32m2:
+    case clang::BuiltinType::RvvUint32m4:
+    case clang::BuiltinType::RvvUint32m8:
+    case clang::BuiltinType::RvvInt64m1:
+    case clang::BuiltinType::RvvInt64m2:
+    case clang::BuiltinType::RvvInt64m4:
+    case clang::BuiltinType::RvvInt64m8:
+    case clang::BuiltinType::RvvUint64m1:
+    case clang::BuiltinType::RvvUint64m2:
+    case clang::BuiltinType::RvvUint64m4:
+    case clang::BuiltinType::RvvUint64m8:
+    case clang::BuiltinType::RvvFloat16mf4:
+    case clang::BuiltinType::RvvFloat16mf2:
+    case clang::BuiltinType::RvvFloat16m1:
+    case clang::BuiltinType::RvvFloat16m2:
+    case clang::BuiltinType::RvvFloat16m4:
+    case clang::BuiltinType::RvvFloat16m8:
+    case clang::BuiltinType::RvvFloat32mf2:
+    case clang::BuiltinType::RvvFloat32m1:
+    case clang::BuiltinType::RvvFloat32m2:
+    case clang::BuiltinType::RvvFloat32m4:
+    case clang::BuiltinType::RvvFloat32m8:
+    case clang::BuiltinType::RvvFloat64m1:
+    case clang::BuiltinType::RvvFloat64m2:
+    case clang::BuiltinType::RvvFloat64m4:
+    case clang::BuiltinType::RvvFloat64m8:
+    case clang::BuiltinType::RvvBool1:
+    case clang::BuiltinType::RvvBool2:
+    case clang::BuiltinType::RvvBool4:
+    case clang::BuiltinType::RvvBool8:
+    case clang::BuiltinType::RvvBool16:
+    case clang::BuiltinType::RvvBool32:
+    case clang::BuiltinType::RvvBool64:
+      break;
+
     case clang::BuiltinType::IncompleteMatrixIdx:
       break;
     }
@@ -6365,7 +6503,7 @@
   case clang::Type::RValueReference:
     if (idx_is_valid) {
       const clang::ReferenceType *reference_type =
-          llvm::cast<clang::ReferenceType>(parent_qual_type.getTypePtr());
+          llvm::cast<clang::ReferenceType>(GetQualType(type).getTypePtr());
       CompilerType pointee_clang_type =
           GetType(reference_type->getPointeeType());
       if (transparent_pointers && pointee_clang_type.IsAggregateType()) {
@@ -6536,10 +6674,11 @@
           if (cxx_record_decl->lookupInBases(
                   [decl_name](const clang::CXXBaseSpecifier *specifier,
                               clang::CXXBasePath &path) {
-                    path.Decls =
-                        specifier->getType()->getAsCXXRecordDecl()->lookup(
-                            decl_name);
-                    return !path.Decls.empty();
+                    CXXRecordDecl *record =
+                      specifier->getType()->getAsCXXRecordDecl();
+                    auto r = record->lookup(decl_name);
+                    path.Decls = r.begin();
+                    return !r.empty();
                   },
                   paths)) {
             clang::CXXBasePaths::const_paths_iterator path,
@@ -6562,9 +6701,10 @@
                           ->getDecl());
                 }
               }
-              for (clang::NamedDecl *path_decl : path->Decls) {
+              for (clang::DeclContext::lookup_iterator I = path->Decls, E;
+                   I != E; ++I) {
                 child_idx = GetIndexForRecordChild(
-                    parent_record_decl, path_decl, omit_empty_base_classes);
+                    parent_record_decl, *I, omit_empty_base_classes);
                 if (child_idx == UINT32_MAX) {
                   child_indexes.clear();
                   return 0;
@@ -9234,11 +9374,11 @@
 std::vector<CompilerDecl> TypeSystemClang::DeclContextFindDeclByName(
     void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) {
   std::vector<CompilerDecl> found_decls;
-  if (opaque_decl_ctx) {
+  SymbolFile *symbol_file = GetSymbolFile();
+  if (opaque_decl_ctx && symbol_file) {
     DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
     std::set<DeclContext *> searched;
     std::multimap<DeclContext *, DeclContext *> search_queue;
-    SymbolFile *symbol_file = GetSymbolFile();
 
     for (clang::DeclContext *decl_context = root_decl_ctx;
          decl_context != nullptr && found_decls.empty();
@@ -9332,10 +9472,10 @@
                                           clang::DeclContext *child_decl_ctx,
                                           ConstString *child_name,
                                           CompilerType *child_type) {
-  if (frame_decl_ctx) {
+  SymbolFile *symbol_file = GetSymbolFile();
+  if (frame_decl_ctx && symbol_file) {
     std::set<DeclContext *> searched;
     std::multimap<DeclContext *, DeclContext *> search_queue;
-    SymbolFile *symbol_file = GetSymbolFile();
 
     // Get the lookup scope for the decl we're trying to find.
     clang::DeclContext *parent_decl_ctx = child_decl_ctx->getParent();
@@ -9581,7 +9721,8 @@
                                                llvm::Triple triple)
     : TypeSystemClang("scratch ASTContext", triple), m_triple(triple),
       m_target_wp(target.shared_from_this()),
-      m_persistent_variables(new ClangPersistentVariables) {
+      m_persistent_variables(
+          new ClangPersistentVariables(target.shared_from_this())) {
   m_scratch_ast_source_up = CreateASTSource();
   m_scratch_ast_source_up->InstallASTContext(*this);
   llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(
@@ -9649,7 +9790,8 @@
     return {};
 
   return std::make_unique<ClangUtilityFunction>(
-      *target_sp.get(), std::move(text), std::move(name));
+      *target_sp.get(), std::move(text), std::move(name),
+      target_sp->GetDebugUtilityExpression());
 }
 
 PersistentExpressionState *
diff --git a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index f37652f..701e4ca 100644
--- a/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/src/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -9,7 +9,7 @@
 #ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
 #define LLDB_SOURCE_PLUGINS_TYPESYSTEM_CLANG_TYPESYSTEMCLANG_H
 
-#include <stdint.h>
+#include <cstdint>
 
 #include <functional>
 #include <initializer_list>
@@ -265,7 +265,7 @@
       clang::DeclContext::lookup_result result = decl_context->lookup(myName);
 
       if (!result.empty()) {
-        clang::NamedDecl *named_decl = result[0];
+        clang::NamedDecl *named_decl = *result.begin();
         if (const RecordDeclType *record_decl =
                 llvm::dyn_cast<RecordDeclType>(named_decl))
           compiler_type.SetCompilerType(
@@ -328,6 +328,8 @@
         (!packed_args || !packed_args->packed_args);
     }
 
+    bool hasParameterPack() const { return static_cast<bool>(packed_args); }
+
     llvm::SmallVector<const char *, 2> names;
     llvm::SmallVector<clang::TemplateArgument, 2> args;
     
@@ -378,13 +380,6 @@
                                bool isForwardDecl, bool isInternal,
                                ClangASTMetadata *metadata = nullptr);
 
-  bool SetTagTypeKind(clang::QualType type, int kind) const;
-
-  bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
-                                       int default_accessibility,
-                                       int *assigned_accessibilities,
-                                       size_t num_assigned_accessibilities);
-
   // Returns a mask containing bits from the TypeSystemClang::eTypeXXX
   // enumerations
 
@@ -421,7 +416,7 @@
                              int storage, bool add_decl = false);
 
   void SetFunctionParameters(clang::FunctionDecl *function_decl,
-                             clang::ParmVarDecl **params, unsigned num_params);
+                             llvm::ArrayRef<clang::ParmVarDecl *> params);
 
   CompilerType CreateBlockPointerType(const CompilerType &function_type);
 
diff --git a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 1bc071c..65947c5 100644
--- a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -38,10 +38,10 @@
   ProcessSP process_sp(thread.GetProcess());
   if (process_sp) {
     Status error;
-    const bool prefer_file_cache = true;
+    const bool force_live_memory = true;
     if (process_sp->GetTarget().ReadMemory(
-            range.GetBaseAddress(), prefer_file_cache, function_text.data(),
-            range.GetByteSize(), error) != range.GetByteSize()) {
+            range.GetBaseAddress(), function_text.data(), range.GetByteSize(),
+            error, force_live_memory) != range.GetByteSize()) {
       return false;
     }
   }
diff --git a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index fe1275d..402a70c 100644
--- a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -51,12 +51,11 @@
   ProcessSP process_sp(thread.GetProcess());
   if (process_sp.get() == nullptr)
     return false;
-  const bool prefer_file_cache = true;
   std::vector<uint8_t> function_text(func.GetByteSize());
   Status error;
   if (process_sp->GetTarget().ReadMemory(
-          func.GetBaseAddress(), prefer_file_cache, function_text.data(),
-          func.GetByteSize(), error) == func.GetByteSize()) {
+          func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
+          error) == func.GetByteSize()) {
     RegisterContextSP reg_ctx(thread.GetRegisterContext());
     m_assembly_inspection_engine->Initialize(reg_ctx);
     return m_assembly_inspection_engine->GetNonCallSiteUnwindPlanFromAssembly(
@@ -153,12 +152,11 @@
       return false;
     if (m_assembly_inspection_engine == nullptr)
       return false;
-    const bool prefer_file_cache = true;
     std::vector<uint8_t> function_text(func.GetByteSize());
     Status error;
     if (process_sp->GetTarget().ReadMemory(
-            func.GetBaseAddress(), prefer_file_cache, function_text.data(),
-            func.GetByteSize(), error) == func.GetByteSize()) {
+            func.GetBaseAddress(), function_text.data(), func.GetByteSize(),
+            error) == func.GetByteSize()) {
       RegisterContextSP reg_ctx(thread.GetRegisterContext());
       m_assembly_inspection_engine->Initialize(reg_ctx);
       return m_assembly_inspection_engine->AugmentUnwindPlanFromCallSite(
@@ -185,10 +183,9 @@
   ProcessSP process_sp = thread.GetProcess();
   if (process_sp) {
     Target &target(process_sp->GetTarget());
-    const bool prefer_file_cache = true;
     Status error;
-    if (target.ReadMemory(func.GetBaseAddress(), prefer_file_cache,
-                          opcode_data.data(), 4, error) == 4) {
+    if (target.ReadMemory(func.GetBaseAddress(), opcode_data.data(), 4,
+                          error) == 4) {
       uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5};
       uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5};
 
@@ -220,12 +217,10 @@
   if (m_assembly_inspection_engine == nullptr)
     return false;
 
-  const bool prefer_file_cache = true;
   std::vector<uint8_t> function_text(func.GetByteSize());
   Status error;
-  if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache,
-                         function_text.data(), func.GetByteSize(),
-                         error) == func.GetByteSize()) {
+  if (target->ReadMemory(func.GetBaseAddress(), function_text.data(),
+                         func.GetByteSize(), error) == func.GetByteSize()) {
     size_t offset;
     if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction(
             function_text.data(), func.GetByteSize(), offset)) {
diff --git a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index f39dce1..4877488 100644
--- a/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/src/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -45,9 +45,9 @@
   /// are called.  This one takes a vector of register name and lldb
   /// register numbers.
   struct lldb_reg_info {
-    const char *name;
-    uint32_t lldb_regnum;
-    lldb_reg_info() : name(nullptr), lldb_regnum(LLDB_INVALID_REGNUM) {}
+    const char *name = nullptr;
+    uint32_t lldb_regnum = LLDB_INVALID_REGNUM;
+    lldb_reg_info() = default;
   };
   void Initialize(std::vector<lldb_reg_info> &reg_info);