JDevlieghere created this revision.
JDevlieghere added reviewers: jasonmolenda, omjavaid, justincohen.
Herald added a subscriber: kristof.beyls.
Herald added a reviewer: a.sidorin.
JDevlieghere requested review of this revision.

Call into the ABI to fixup code addresses in RegisterContextUnwind. We need 
this in order to debug on Apple Silicon where libraries like libSystem are 
`arm64e` even when the inferior is `arm64`.


https://reviews.llvm.org/D100521

Files:
  lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
  lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
  lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
  lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
  lldb/source/Target/RegisterContextUnwind.cpp

Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -383,7 +383,7 @@
   // symbol/function information - just stick in some reasonable defaults and
   // hope we can unwind past this frame.  If we're above a trap handler,
   // we may be at a bogus address because we jumped through a bogus function
-  // pointer and trapped, so don't force the arch default unwind plan in that 
+  // pointer and trapped, so don't force the arch default unwind plan in that
   // case.
   ModuleSP pc_module_sp(m_current_pc.GetModule());
   if ((!m_current_pc.IsValid() || !pc_module_sp) &&
@@ -1277,7 +1277,7 @@
     // arch default unwind plan is used as the Fast Unwind Plan, we
     // need to recognize this & switch over to the Full Unwind Plan
     // to see what unwind rule that (more knoweldgeable, probably)
-    // UnwindPlan has.  If the full UnwindPlan says the register 
+    // UnwindPlan has.  If the full UnwindPlan says the register
     // location is Undefined, then it really is.
     if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
                                     unwindplan_regloc) &&
@@ -1325,14 +1325,14 @@
           m_full_unwind_plan_sp->GetReturnAddressRegister() !=
               LLDB_INVALID_REGNUM) {
         // If this is a trap handler frame, we should have access to
-        // the complete register context when the interrupt/async 
+        // the complete register context when the interrupt/async
         // signal was received, we should fetch the actual saved $pc
         // value instead of the Return Address register.
         // If $pc is not available, fall back to the RA reg.
         UnwindPlan::Row::RegisterLocation scratch;
         if (m_frame_type == eTrapHandlerFrame &&
-            active_row->GetRegisterInfo 
-              (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) {
+            active_row->GetRegisterInfo(
+                pc_regnum.GetAsKind(unwindplan_registerkind), scratch)) {
           UnwindLogMsg("Providing pc register instead of rewriting to "
                        "RA reg because this is a trap handler and there is "
                        "a location for the saved pc register value.");
@@ -1730,6 +1730,12 @@
       RegisterValue reg_value;
       if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
         old_caller_pc_value = reg_value.GetAsUInt64();
+        ProcessSP process_sp(m_thread.GetProcess());
+        if (process_sp) {
+          ABI *abi = process_sp->GetABI().get();
+          if (abi)
+            old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value);
+        }
       }
     }
   }
@@ -1785,6 +1791,12 @@
         if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
                                                   reg_value)) {
           new_caller_pc_value = reg_value.GetAsUInt64();
+          ProcessSP process_sp(m_thread.GetProcess());
+          if (process_sp) {
+            ABI *abi = process_sp->GetABI().get();
+            if (abi)
+              new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
+          }
         }
       }
     }
@@ -2121,6 +2133,14 @@
   }
   if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
     value = reg_value.GetAsUInt64();
+    if (pc_register) {
+      ProcessSP process_sp(m_thread.GetProcess());
+      if (process_sp) {
+        ABI *abi = process_sp->GetABI().get();
+        if (abi)
+          value = abi->FixCodeAddress(value);
+      }
+    }
     return true;
   }
   return false;
@@ -2162,7 +2182,19 @@
           lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
     return false;
 
-  return ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
+  bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
+  if (result) {
+    if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
+      ProcessSP process_sp(m_thread.GetProcess());
+      addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
+      if (process_sp && reg_value != LLDB_INVALID_ADDRESS) {
+        ABI *abi = process_sp->GetABI().get();
+        if (abi)
+          value = abi->FixCodeAddress(reg_value);
+      }
+    }
+  }
+  return result;
 }
 
 bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info,
Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
+++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -67,6 +67,7 @@
 
   bool GetPointerReturnRegister(const char *&name) override;
 
+  lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
   // Static Functions
 
   static void Initialize();
Index: lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -782,6 +782,19 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABISysV_arm64::FixCodeAddress(addr_t pc) {
+  ProcessSP process_sp = GetProcessSP();
+  if (!process_sp)
+    return pc;
+
+  lldb::addr_t mask = process_sp->GetCodeAddressMask();
+  lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+
+  if (pc & pac_sign_extension)
+    return pc | mask;
+  return pc & (~mask);
+}
+
 void ABISysV_arm64::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 "SysV ABI for AArch64 targets", CreateInstance);
Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -62,6 +62,7 @@
     return true;
   }
 
+  lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
   // Static Functions
 
   static void Initialize();
Index: lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -815,6 +815,19 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
+  ProcessSP process_sp = GetProcessSP();
+  if (!process_sp)
+    return pc;
+
+  lldb::addr_t mask = process_sp->GetCodeAddressMask();
+  lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
+
+  if (pc & pac_sign_extension)
+    return pc | mask;
+  return pc & (~mask);
+}
+
 void ABIMacOSX_arm64::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
                                 CreateInstance);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to