[Lldb-commits] [lldb] 8770b4e - [lldb] Implement ABI::Fix{Code, Data}Address for AArch64

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 16 13:49:54 PDT 2021


Author: Jonas Devlieghere
Date: 2021-04-16T13:49:38-07:00
New Revision: 8770b4ecca557b02d37188ae2fa5479e6136b2fb

URL: https://github.com/llvm/llvm-project/commit/8770b4ecca557b02d37188ae2fa5479e6136b2fb
DIFF: https://github.com/llvm/llvm-project/commit/8770b4ecca557b02d37188ae2fa5479e6136b2fb.diff

LOG: [lldb] Implement ABI::Fix{Code,Data}Address for AArch64

Implement FixCodeAddress and FixDataAddress for ABIMacOSX_arm64 and
ABISysV_arm64 and add missing calls to RegisterContextUnwind. We need
this to unwind on Apple Silicon where libraries like libSystem are
arm64e even when the program being debugged is arm64.

Differential revision: https://reviews.llvm.org/D100521

Added: 
    

Modified: 
    lldb/include/lldb/Target/ABI.h
    lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
    lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
    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

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h
index 131b2eaff765c..8fbb6aae68c4c 100644
--- a/lldb/include/lldb/Target/ABI.h
+++ b/lldb/include/lldb/Target/ABI.h
@@ -117,12 +117,13 @@ class ABI : public PluginInterface {
   // "pc".
   virtual bool CodeAddressIsValid(lldb::addr_t pc) = 0;
 
-  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) {
-    // Some targets might use bits in a code address to indicate a mode switch.
-    // ARM uses bit zero to signify a code address is thumb, so any ARM ABI
-    // plug-ins would strip those bits.
-    return pc;
-  }
+  /// Some targets might use bits in a code address to indicate a mode switch.
+  /// ARM uses bit zero to signify a code address is thumb, so any ARM ABI
+  /// plug-ins would strip those bits.
+  /// @{
+  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc) { return pc; }
+  virtual lldb::addr_t FixDataAddress(lldb::addr_t pc) { return pc; }
+  /// @}
 
   llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; }
 
@@ -147,6 +148,10 @@ class ABI : public PluginInterface {
   lldb::ProcessWP m_process_wp;
   std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up;
 
+  virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc, lldb::addr_t mask) {
+    return pc;
+  }
+
 private:
   ABI(const ABI &) = delete;
   const ABI &operator=(const ABI &) = delete;

diff  --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
index 7cae4cc427501..42d73ce39ed6f 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ b/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 @@ void ABIAArch64::Terminate() {
   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/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
index bdff648f1b522..41bbf5cfdeb96 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
+++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
@@ -16,7 +16,14 @@ class ABIAArch64: public lldb_private::MCBasedABI {
   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/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
index 861310e3ea0c1..c7ae128d874f5 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
@@ -815,6 +815,11 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
   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/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
index fc8ccee92e71e..dc3ab35115fd5 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
+++ b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
@@ -62,6 +62,8 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
     return true;
   }
 
+  lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
   // Static Functions
 
   static void Initialize();

diff  --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
index 0f74c1f5c73b1..312b5620262d6 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
@@ -782,6 +782,11 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
   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);
+}
+
 void ABISysV_arm64::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 "SysV ABI for AArch64 targets", CreateInstance);

diff  --git a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
index aeb74acc38b5d..4c88ee2cb63e0 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
+++ b/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h
@@ -67,6 +67,8 @@ class ABISysV_arm64 : public ABIAArch64 {
 
   bool GetPointerReturnRegister(const char *&name) override;
 
+  lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
+
   // Static Functions
 
   static void Initialize();

diff  --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index e77905f023dbe..b8d9926ac77ba 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -1730,6 +1730,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
       RegisterValue reg_value;
       if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
         old_caller_pc_value = reg_value.GetAsUInt64();
+        if (ProcessSP process_sp = m_thread.GetProcess()) {
+          if (ABISP abi = process_sp->GetABI())
+            old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value);
+        }
       }
     }
   }
@@ -1785,6 +1789,10 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() {
         if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
                                                   reg_value)) {
           new_caller_pc_value = reg_value.GetAsUInt64();
+          if (ProcessSP process_sp = m_thread.GetProcess()) {
+            if (ABISP abi = process_sp->GetABI())
+              new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value);
+          }
         }
       }
     }
@@ -2121,6 +2129,12 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
   }
   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);
+      }
+    }
     return true;
   }
   return false;
@@ -2162,7 +2176,19 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info,
           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) {
+      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);
+        }
+      }
+    }
+  }
+  return result;
 }
 
 bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info,


        


More information about the lldb-commits mailing list