JDevlieghere updated this revision to Diff 337991.
JDevlieghere added a comment.

Save a line or two


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100521/new/

https://reviews.llvm.org/D100521

Files:
  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

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,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();
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,13 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABISysV_arm64::FixAddress(addr_t pc, addr_t mask) {
+  if (mask == (lldb::addr_t)-1)
+    return pc;
+  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);
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,8 @@
     return true;
   }
 
+  lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) 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,13 @@
   return return_valobj_sp;
 }
 
+lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
+  if (mask == (lldb::addr_t)-1)
+    return pc;
+  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);
Index: lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIAArch64.h
+++ 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;
 
Index: lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ 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")
Index: lldb/include/lldb/Target/ABI.h
===================================================================
--- lldb/include/lldb/Target/ABI.h
+++ lldb/include/lldb/Target/ABI.h
@@ -117,12 +117,13 @@
   // "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 @@
   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;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to