jasonmolenda created this revision.
jasonmolenda added a reviewer: JDevlieghere.
jasonmolenda added a project: LLDB.
Herald added a subscriber: kristof.beyls.
Herald added a reviewer: a.sidorin.
Herald added a project: All.
jasonmolenda requested review of this revision.
Herald added a subscriber: lldb-commits.

The darwin kernel may have authentication bits on fields like $pc or $sp when 
the register state is thread_get_state'd with macOS Sonoma.  debugserver clears 
these bits before handing the values to lldb  arm64 corefiles created by gcore 
on MacOS Sonoma (macOS 14) will include these signed value as-is.

This patch changes RegisterContextUnwind to clear the unaddressable bits from 
sp/pc/fp/lr -- these must point to stack or code in memory.

We already clear the bits from spilled lr's because that's frequently signed 
with an ABI using ARMv8.3 ptrauth.  This patch extends that same behavior to sp 
and fp.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152861

Files:
  lldb/source/Target/RegisterContextUnwind.cpp

Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -362,10 +362,16 @@
   if (log) {
     UnwindLogMsg("pc = 0x%" PRIx64, pc);
     addr_t reg_val;
-    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
+    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) {
+      if (abi)
+        reg_val = abi->FixDataAddress(reg_val);
       UnwindLogMsg("fp = 0x%" PRIx64, reg_val);
-    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
+    }
+    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) {
+      if (abi)
+        reg_val = abi->FixDataAddress(reg_val);
       UnwindLogMsg("sp = 0x%" PRIx64, reg_val);
+    }
   }
 
   // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
@@ -1953,6 +1959,7 @@
 
   address = LLDB_INVALID_ADDRESS;
   addr_t cfa_reg_contents;
+  ABI *abi = m_thread.GetProcess()->GetABI().get();
 
   switch (fa.GetValueType()) {
   case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
@@ -1963,12 +1970,14 @@
           GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
       RegisterValue reg_value;
       if (reg_info) {
+        if (abi)
+          cfa_reg_contents = abi->FixDataAddress(cfa_reg_contents);
         Status error = ReadRegisterValueFromMemory(
             reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
         if (error.Success()) {
           address = reg_value.GetAsUInt64();
-          if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
-            address = abi_sp->FixCodeAddress(address);
+          if (abi)
+            address = abi->FixCodeAddress(address);
           UnwindLogMsg(
               "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
               ", CFA value is 0x%" PRIx64,
@@ -1989,6 +1998,8 @@
     RegisterNumber cfa_reg(m_thread, row_register_kind,
                            fa.GetRegisterNumber());
     if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
+      if (abi)
+        cfa_reg_contents = abi->FixDataAddress(cfa_reg_contents);
       if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
           cfa_reg_contents == 1) {
         UnwindLogMsg(
@@ -2024,8 +2035,8 @@
     if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
                            &error)) {
       address = result.GetScalar().ULongLong();
-      if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
-        address = abi_sp->FixCodeAddress(address);
+      if (ABI *abi = m_thread.GetProcess()->GetABI().get())
+        address = abi->FixCodeAddress(address);
 
       UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
                    address);
@@ -2076,6 +2087,8 @@
     return LLDB_INVALID_ADDRESS;
   if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
     return LLDB_INVALID_ADDRESS;
+  if (ABI *abi = m_thread.GetProcess()->GetABI().get())
+    hint = abi->FixCodeAddress(hint);
 
   hint += plan_offset;
 
@@ -2133,28 +2146,38 @@
     return false;
   }
 
+  uint32_t generic_regnum = LLDB_INVALID_REGNUM;
+  if (register_kind == eRegisterKindGeneric)
+    generic_regnum = regnum;
+  else
+    m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
+        register_kind, regnum, eRegisterKindGeneric, generic_regnum);
+  ABI *abi = m_thread.GetProcess()->GetABI().get();
+
   RegisterValue reg_value;
   // if this is frame 0 (currently executing frame), get the requested reg
   // contents from the actual thread registers
   if (IsFrameZero()) {
     if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
       value = reg_value.GetAsUInt64();
+      if (abi && generic_regnum != LLDB_INVALID_REGNUM) {
+        if (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+            generic_regnum == LLDB_REGNUM_GENERIC_RA)
+          value = abi->FixCodeAddress(value);
+        if (generic_regnum == LLDB_REGNUM_GENERIC_SP ||
+            generic_regnum == LLDB_REGNUM_GENERIC_FP)
+          value = abi->FixDataAddress(value);
+      }
       return true;
     }
     return false;
   }
 
   bool pc_register = false;
-  uint32_t generic_regnum;
-  if (register_kind == eRegisterKindGeneric &&
-      (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) {
-    pc_register = true;
-  } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
-                 register_kind, regnum, eRegisterKindGeneric, generic_regnum) &&
-             (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
-              generic_regnum == LLDB_REGNUM_GENERIC_RA)) {
+  if (generic_regnum != LLDB_INVALID_REGNUM &&
+      (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
+       generic_regnum == LLDB_REGNUM_GENERIC_RA))
     pc_register = true;
-  }
 
   lldb_private::UnwindLLDB::RegisterLocation regloc;
   if (!m_parent_unwind.SearchForSavedLocationForRegister(
@@ -2164,9 +2187,8 @@
   if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
     value = reg_value.GetAsUInt64();
     if (pc_register) {
-      if (ProcessSP process_sp = m_thread.GetProcess()) {
-        if (ABISP abi = process_sp->GetABI())
-          value = abi->FixCodeAddress(value);
+      if (ABI *abi = m_thread.GetProcess()->GetABI().get()) {
+        value = abi->FixCodeAddress(value);
       }
     }
     return true;
@@ -2215,10 +2237,8 @@
     if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
       addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
       if (reg_value != LLDB_INVALID_ADDRESS) {
-        if(ProcessSP process_sp = m_thread.GetProcess()) {
-          if (ABISP abi = process_sp->GetABI())
-            value = abi->FixCodeAddress(reg_value);
-        }
+        if (ABI *abi = m_thread.GetProcess()->GetABI().get())
+          value = abi->FixCodeAddress(reg_value);
       }
     }
   }
@@ -2330,13 +2350,8 @@
     // through a NULL pointer -- we want to be able to unwind past that frame
     // to help find the bug.
 
-    ProcessSP process_sp (m_thread.GetProcess());
-    if (process_sp)
-    {
-        ABI *abi = process_sp->GetABI().get();
-        if (abi)
-            pc = abi->FixCodeAddress(pc);
-    }
+    if (ABI *abi = m_thread.GetProcess()->GetABI().get())
+      pc = abi->FixCodeAddress(pc);
 
     return !(m_all_registers_available == false &&
              above_trap_handler == false && (pc == 0 || pc == 1));
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to