diff options
author | Jason Molenda <jason@molenda.com> | 2023-04-03 13:49:51 -0700 |
---|---|---|
committer | Jason Molenda <jason@molenda.com> | 2023-04-03 13:49:51 -0700 |
commit | 8b092714c304defb00876a01995af3b114dadc92 (patch) | |
tree | fd8b18a1bbc4f3b005f9a1ae0dc8ad05302eb7ba /lldb | |
parent | e538c6fc3048e1fb1a58da879275d6804186856e (diff) | |
download | llvm-8b092714c304defb00876a01995af3b114dadc92.zip llvm-8b092714c304defb00876a01995af3b114dadc92.tar.gz llvm-8b092714c304defb00876a01995af3b114dadc92.tar.bz2 |
Using global variable in xnu kernel, set # of addressable bits
The kernel has a global variable with the TCR_EL1.T1SZ value,
from which was can calculate the number of addressable bits.
Find that symbol in DynamicLoaderDarwinKernel and set the bits
to that value for this Process.
Differential Revision: https://reviews.llvm.org/D147462
rdar://107445318
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index ea2cb46..05658d1 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -1068,6 +1068,7 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() { if (m_kernel.IsLoaded() && m_kernel.GetModule()) { static ConstString kext_summary_symbol("gLoadedKextSummaries"); + static ConstString arm64_T1Sz_value("gT1Sz"); const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType( kext_summary_symbol, eSymbolTypeData); @@ -1076,6 +1077,36 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() { // Update all image infos ReadAllKextSummaries(); } + // If the kernel global with the T1Sz setting is available, + // update the target.process.virtual-addressable-bits to be correct. + symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType( + arm64_T1Sz_value, eSymbolTypeData); + if (symbol) { + const uint32_t orig_bits_value = m_process->GetVirtualAddressableBits(); + // Mark all bits as addressable so we don't strip any from our + // memory read below, with an incorrect default value. + // b55 is the sign extension bit with PAC, b56:63 are TBI, + // don't mark those as addressable. + m_process->SetVirtualAddressableBits(55); + Status error; + // gT1Sz is 8 bytes. We may run on a stripped kernel binary + // where we can't get the size accurately. Hardcode it. + const size_t sym_bytesize = 8; // size of gT1Sz value + uint64_t sym_value = + m_process->GetTarget().ReadUnsignedIntegerFromMemory( + symbol->GetAddress(), sym_bytesize, 0, error); + if (error.Success()) { + // 64 - T1Sz is the highest bit used for auth. + // The value we pass in to SetVirtualAddressableBits is + // the number of bits used for addressing, so if + // T1Sz is 25, then 64-25 == 39, bits 0..38 are used for + // addressing, bits 39..63 are used for PAC/TBI or whatever. + uint32_t virt_addr_bits = 64 - sym_value; + m_process->SetVirtualAddressableBits(virt_addr_bits); + } else { + m_process->SetVirtualAddressableBits(orig_bits_value); + } + } } else { m_kernel.Clear(); } |