Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -1328,6 +1328,23 @@ virtual void DidExit() {} + /// Get number of bits being used by process for addressing. + /// + /// \return + /// Number of bits out of maximum address bit size used + /// for addressing. + uint32_t GetAddressBitsInUse() { return m_address_bits_in_use; } + + /// Set number of bits being used by process for addressing. + /// + /// \param [in] address_bits_in_use + /// Number of bits out of maximum address bit size used + /// for addressing. Default value is zero meaning all + /// address bits will be used for addressing. + void SetAddressBitsInUse(uint32_t address_bits_in_use) { + m_address_bits_in_use = address_bits_in_use; + } + /// Get the Modification ID of the process. /// /// \return @@ -2876,6 +2893,10 @@ /// from looking up or creating things during or after a finalize call. std::atomic m_finalizing; + uint32_t m_address_bits_in_use = 0; ///< No of bits in use by address out + /// of total target address bit width. + /// or 0 if not set. + bool m_clear_thread_plans_on_stop; bool m_force_next_event_delivery; lldb::StateType m_last_broadcast_state; /// This helps with the Public event 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 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 @@ -33,6 +33,20 @@ using namespace lldb; using namespace lldb_private; +lldb::addr_t ABISysV_arm64::FixCodeAddress(lldb::addr_t pc) { + // This function clears top bits of argument pc which are not used for + // addressing by current target process. Resulting sign extended + // address is returned. + uint32_t address_shift_width = GetProcessSP()->GetAddressBitsInUse(); + if (address_shift_width && + (address_shift_width < (sizeof(lldb::addr_t) * CHAR_BIT))) { + lldb::addr_t sign = (lldb::addr_t)1 << (address_shift_width - 1); + pc &= ((lldb::addr_t)1 << address_shift_width) - 1; + pc = (pc ^ sign) - sign; + } + return pc; +} + bool ABISysV_arm64::GetPointerReturnRegister(const char *&name) { name = "x0"; return true; Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -10,6 +10,7 @@ #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/RegisterValue.h" @@ -53,9 +54,24 @@ if (m_register_info_up->IsSVEEnabled()) m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc); - if (m_register_info_up->IsPAuthEnabled()) + if (m_register_info_up->IsPAuthEnabled()) { m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc); + // At this stage we should be able to guess no of address bits + // being used by target configuration when elf-core was generated. + // This will either be 48 or 52 bits depending on AArch64 virtual + // address size configuration. Following code checks if PAC starts + // from 48th or 52nd bit onwards and accordingly sets address bits + // in use by the this elf-core process. + uint64_t pac_masks[2] = {0, 0}; + uint64_t pac_test_mask = 1ULL << 48; + lldb::offset_t pac_data_offset = 0; + if (m_pac_data.GetU64(&pac_data_offset, pac_masks, 2) && + ((pac_masks[0] & pac_test_mask) || (pac_masks[1] & pac_test_mask))) + thread.GetProcess()->SetAddressBitsInUse(48); + else + thread.GetProcess()->SetAddressBitsInUse(52); + } ConfigureRegisterContext(); } Index: lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py =================================================================== --- lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -20,6 +20,7 @@ mydir = TestBase.compute_mydir(__file__) _aarch64_pid = 37688 + _aarch64_pac_pid = 387 _i386_pid = 32306 _x86_64_pid = 32259 _s390x_pid = 1045 @@ -257,6 +258,18 @@ self.dbg.DeleteTarget(target) + @skipIfLLVMTargetMissing("AArch64") + def test_aarch64_pac(self): + """Test that lldb can find the exe for an AArch64 Linux core file which has PAC enabled.""" + + target = self.dbg.CreateTarget("linux-aarch64-pac.out") + self.assertTrue(target, VALID_TARGET) + process = target.LoadCore("linux-aarch64-pac.core") + + self.check_all(process, self._aarch64_pac_pid, self._aarch64_regions, "a.out") + + self.dbg.DeleteTarget(target) + @skipIfLLVMTargetMissing("AArch64") @expectedFailureAll(archs=["aarch64"], oslist=["freebsd"], bugnumber="llvm.org/pr49415")