Skip to content

Commit c8e31f7

Browse files
Merge pull request #6952 from apple/eng/r109746900-different-addressing-bits-for-high-and-low-mem-addresses-59
Setting to control addressable bits in high memory
2 parents 4605c8b + f6a3fba commit c8e31f7

File tree

6 files changed

+100
-29
lines changed

6 files changed

+100
-29
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class ProcessProperties : public Properties {
8181
FileSpec GetPythonOSPluginPath() const;
8282
uint32_t GetVirtualAddressableBits() const;
8383
void SetVirtualAddressableBits(uint32_t bits);
84+
uint32_t GetHighmemVirtualAddressableBits() const;
85+
void SetHighmemVirtualAddressableBits(uint32_t bits);
8486
void SetPythonOSPluginPath(const FileSpec &file);
8587
bool GetIgnoreBreakpointsInExpressions() const;
8688
void SetIgnoreBreakpointsInExpressions(bool ignore);
@@ -1388,6 +1390,9 @@ class Process : public std::enable_shared_from_this<Process>,
13881390
lldb::addr_t GetCodeAddressMask();
13891391
lldb::addr_t GetDataAddressMask();
13901392

1393+
lldb::addr_t GetHighmemCodeAddressMask();
1394+
lldb::addr_t GetHighmemDataAddressMask();
1395+
13911396
void SetCodeAddressMask(lldb::addr_t code_address_mask) {
13921397
m_code_address_mask = code_address_mask;
13931398
}
@@ -1396,6 +1401,14 @@ class Process : public std::enable_shared_from_this<Process>,
13961401
m_data_address_mask = data_address_mask;
13971402
}
13981403

1404+
void SetHighmemCodeAddressMask(lldb::addr_t code_address_mask) {
1405+
m_highmem_code_address_mask = code_address_mask;
1406+
}
1407+
1408+
void SetHighmemDataAddressMask(lldb::addr_t data_address_mask) {
1409+
m_highmem_data_address_mask = data_address_mask;
1410+
}
1411+
13991412
/// Get the Modification ID of the process.
14001413
///
14011414
/// \return
@@ -3036,9 +3049,13 @@ void PruneThreadPlans();
30363049
/// Mask for code an data addresses. The default value (0) means no mask is
30373050
/// set. The bits set to 1 indicate bits that are NOT significant for
30383051
/// addressing.
3052+
/// The highmem versions are for targets where we may have different masks
3053+
/// for low memory versus high memory addresses.
30393054
/// @{
30403055
lldb::addr_t m_code_address_mask = 0;
30413056
lldb::addr_t m_data_address_mask = 0;
3057+
lldb::addr_t m_highmem_code_address_mask = 0;
3058+
lldb::addr_t m_highmem_data_address_mask = 0;
30423059
/// @}
30433060

30443061
bool m_clear_thread_plans_on_stop;

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,41 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
814814
return return_valobj_sp;
815815
}
816816

817-
lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) {
818-
lldb::addr_t pac_sign_extension = 0x0080000000000000ULL;
819-
// When no mask is specified, clear/set the top byte; preserve
820-
// the low 55 bits (00..54) for addressing and bit 55 to indicate
821-
// sign.
822-
if (mask == 0) {
823-
// ~((1ULL<<55)-1)
824-
mask = 0xff80000000000000;
817+
addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
818+
addr_t pac_sign_extension = 0x0080000000000000ULL;
819+
addr_t tbi_mask = 0xff80000000000000ULL;
820+
addr_t mask = 0;
821+
822+
if (ProcessSP process_sp = GetProcessSP()) {
823+
mask = process_sp->GetCodeAddressMask();
824+
if (pc & pac_sign_extension) {
825+
addr_t highmem_mask = process_sp->GetHighmemCodeAddressMask();
826+
if (highmem_mask)
827+
mask = highmem_mask;
828+
}
829+
}
830+
if (mask == 0)
831+
mask = tbi_mask;
832+
833+
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
834+
}
835+
836+
addr_t ABIMacOSX_arm64::FixDataAddress(addr_t pc) {
837+
addr_t pac_sign_extension = 0x0080000000000000ULL;
838+
addr_t tbi_mask = 0xff80000000000000ULL;
839+
addr_t mask = 0;
840+
841+
if (ProcessSP process_sp = GetProcessSP()) {
842+
mask = process_sp->GetDataAddressMask();
843+
if (pc & pac_sign_extension) {
844+
addr_t highmem_mask = process_sp->GetHighmemDataAddressMask();
845+
if (highmem_mask)
846+
mask = highmem_mask;
847+
}
825848
}
849+
if (mask == 0)
850+
mask = tbi_mask;
851+
826852
return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
827853
}
828854

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
6262
return true;
6363
}
6464

65-
lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override;
65+
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
66+
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
6667

6768
// Static Functions
6869

lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,15 +1079,18 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
10791079
}
10801080
// If the kernel global with the T1Sz setting is available,
10811081
// update the target.process.virtual-addressable-bits to be correct.
1082+
// NB the xnu kernel always has T0Sz and T1Sz the same value. If
1083+
// it wasn't the same, we would need to set
1084+
// target.process.virtual-addressable-bits = T0Sz
1085+
// target.process.highmem-virtual-addressable-bits = T1Sz
10821086
symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
10831087
arm64_T1Sz_value, eSymbolTypeData);
10841088
if (symbol) {
1085-
const uint32_t orig_bits_value = m_process->GetVirtualAddressableBits();
1086-
// Mark all bits as addressable so we don't strip any from our
1087-
// memory read below, with an incorrect default value.
1088-
// b55 is the sign extension bit with PAC, b56:63 are TBI,
1089-
// don't mark those as addressable.
1090-
m_process->SetVirtualAddressableBits(55);
1089+
const addr_t orig_code_mask = m_process->GetCodeAddressMask();
1090+
const addr_t orig_data_mask = m_process->GetDataAddressMask();
1091+
1092+
m_process->SetCodeAddressMask(0);
1093+
m_process->SetDataAddressMask(0);
10911094
Status error;
10921095
// gT1Sz is 8 bytes. We may run on a stripped kernel binary
10931096
// where we can't get the size accurately. Hardcode it.
@@ -1102,9 +1105,12 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
11021105
// T1Sz is 25, then 64-25 == 39, bits 0..38 are used for
11031106
// addressing, bits 39..63 are used for PAC/TBI or whatever.
11041107
uint32_t virt_addr_bits = 64 - sym_value;
1105-
m_process->SetVirtualAddressableBits(virt_addr_bits);
1108+
addr_t mask = ~((1ULL << virt_addr_bits) - 1);
1109+
m_process->SetCodeAddressMask(mask);
1110+
m_process->SetDataAddressMask(mask);
11061111
} else {
1107-
m_process->SetVirtualAddressableBits(orig_bits_value);
1112+
m_process->SetCodeAddressMask(orig_code_mask);
1113+
m_process->SetDataAddressMask(orig_data_mask);
11081114
}
11091115
}
11101116
} else {

lldb/source/Target/Process.cpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@ void ProcessProperties::SetVirtualAddressableBits(uint32_t bits) {
231231
const uint32_t idx = ePropertyVirtualAddressableBits;
232232
m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, bits);
233233
}
234+
235+
uint32_t ProcessProperties::GetHighmemVirtualAddressableBits() const {
236+
const uint32_t idx = ePropertyHighmemVirtualAddressableBits;
237+
return m_collection_sp->GetPropertyAtIndexAsUInt64(
238+
nullptr, idx, g_process_properties[idx].default_uint_value);
239+
}
240+
241+
void ProcessProperties::SetHighmemVirtualAddressableBits(uint32_t bits) {
242+
const uint32_t idx = ePropertyHighmemVirtualAddressableBits;
243+
m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, bits);
244+
}
245+
234246
void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) {
235247
const uint32_t idx = ePropertyPythonOSPluginPath;
236248
m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file);
@@ -5817,25 +5829,31 @@ void Process::Flush() {
58175829
}
58185830

58195831
lldb::addr_t Process::GetCodeAddressMask() {
5820-
if (m_code_address_mask == 0) {
5821-
if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) {
5822-
lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1);
5823-
SetCodeAddressMask(address_mask);
5824-
}
5825-
}
5832+
if (uint32_t num_bits_setting = GetVirtualAddressableBits())
5833+
return ~((1ULL << num_bits_setting) - 1);
5834+
58265835
return m_code_address_mask;
58275836
}
58285837

58295838
lldb::addr_t Process::GetDataAddressMask() {
5830-
if (m_data_address_mask == 0) {
5831-
if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) {
5832-
lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1);
5833-
SetDataAddressMask(address_mask);
5834-
}
5835-
}
5839+
if (uint32_t num_bits_setting = GetVirtualAddressableBits())
5840+
return ~((1ULL << num_bits_setting) - 1);
5841+
58365842
return m_data_address_mask;
58375843
}
58385844

5845+
lldb::addr_t Process::GetHighmemCodeAddressMask() {
5846+
if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
5847+
return ~((1ULL << num_bits_setting) - 1);
5848+
return GetCodeAddressMask();
5849+
}
5850+
5851+
lldb::addr_t Process::GetHighmemDataAddressMask() {
5852+
if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits())
5853+
return ~((1ULL << num_bits_setting) - 1);
5854+
return GetDataAddressMask();
5855+
}
5856+
58395857
void Process::DidExec() {
58405858
Log *log = GetLog(LLDBLog::Process);
58415859
LLDB_LOGF(log, "Process::%s()", __FUNCTION__);

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ let Definition = "process" in {
289289
def VirtualAddressableBits: Property<"virtual-addressable-bits", "UInt64">,
290290
DefaultUnsignedValue<0>,
291291
Desc<"The number of bits used for addressing. If the value is 39, then bits 0..38 are used for addressing. The default value of 0 means unspecified.">;
292+
def HighmemVirtualAddressableBits: Property<"highmem-virtual-addressable-bits", "UInt64">,
293+
DefaultUnsignedValue<0>,
294+
Desc<"The number of bits used for addressing high memory, when it differs from low memory in the same Process. When this is non-zero, target.process.virtual-addressable-bits will be the value for low memory (0x000... addresses) and this setting will be the value for high memory (0xfff... addresses). When this is zero, target.process.virtual-addressable-bits applies to all addresses. It is very uncommon to use this setting.">;
292295
def FollowForkMode: Property<"follow-fork-mode", "Enum">,
293296
DefaultEnumValue<"eFollowParent">,
294297
EnumValues<"OptionEnumValues(g_follow_fork_mode_values)">,

0 commit comments

Comments
 (0)