jasonmolenda updated this revision to Diff 492951. jasonmolenda added a comment.
Fix the nits Jonas pointed out, thanks Jonas. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D142792/new/ https://reviews.llvm.org/D142792 Files: lldb/bindings/interface/SBValue.i lldb/include/lldb/API/SBValue.h lldb/include/lldb/Core/ValueObject.h lldb/source/API/SBValue.cpp lldb/source/Core/ValueObject.cpp lldb/source/DataFormatters/ValueObjectPrinter.cpp lldb/test/API/api/clear-sbvalue-nonadressable-bits/Makefile lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c
Index: lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c =================================================================== --- /dev/null +++ lldb/test/API/api/clear-sbvalue-nonadressable-bits/main.c @@ -0,0 +1,14 @@ +#include <stdint.h> +int main() { + int v = 5; + int *v_p = &v; + + // Add some metadata in the top byte (this will crash unless the + // test is running with TBI enabled, but we won't dereference it) + + intptr_t scratch = (intptr_t)v_p; + scratch |= (3ULL << 60); + int *v_invalid_p = (int *)scratch; + + return v; // break here +} Index: lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py =================================================================== --- /dev/null +++ lldb/test/API/api/clear-sbvalue-nonadressable-bits/TestClearSBValueNonAddressableBits.py @@ -0,0 +1,35 @@ +"""Test that SBValue clears non-addressable bits""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestClearSBValueNonAddressableBits(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + + # On AArch64 systems, the top bits that are not used for + # addressing may be used for TBI, MTE, and/or pointer + # authentication. + @skipIf(archs=no_match(['aarch64', 'arm64', 'arm64e'])) + + def test(self): + self.source = 'main.c' + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "break here", lldb.SBFileSpec(self.source, False)) + + if self.TraceOn(): + self.runCmd ("v v v_p v_invalid_p") + self.runCmd ("v &v &v_p &v_invalid_p") + + frame = thread.GetFrameAtIndex(0) + v_p = frame.FindVariable("v_p") + v_invalid_p = frame.FindVariable("v_invalid_p") + + self.assertEqual(v_p.GetValueAsUnsigned(), v_invalid_p.GetValueAsAddress()) + self.assertNotEqual(v_invalid_p.GetValueAsUnsigned(), v_invalid_p.GetValueAsAddress()) + + self.assertEqual(5, v_p.Dereference().GetValueAsUnsigned()) + self.assertEqual(5, v_invalid_p.Dereference().GetValueAsUnsigned()) Index: lldb/test/API/api/clear-sbvalue-nonadressable-bits/Makefile =================================================================== --- /dev/null +++ lldb/test/API/api/clear-sbvalue-nonadressable-bits/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules Index: lldb/source/DataFormatters/ValueObjectPrinter.cpp =================================================================== --- lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -426,6 +426,11 @@ IsPointerValue(m_valobj->GetCompilerType())) { } else { m_stream->Printf(" %s", m_value.c_str()); + addr_t stripped = + m_valobj->GetStrippedPointerValue(m_valobj->GetPointerValue()); + if (stripped != m_valobj->GetPointerValue()) { + m_stream->Printf(" (actual=0x%" PRIx64 ")", stripped); + } value_printed = true; } } Index: lldb/source/Core/ValueObject.cpp =================================================================== --- lldb/source/Core/ValueObject.cpp +++ lldb/source/Core/ValueObject.cpp @@ -31,6 +31,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" @@ -1442,6 +1443,14 @@ return LLDB_INVALID_ADDRESS; } +addr_t ValueObject::GetStrippedPointerValue(addr_t address) { + ExecutionContext exe_ctx(GetExecutionContextRef()); + if (Process *process = exe_ctx.GetProcessPtr()) + if (ABISP abi_sp = process->GetABI()) + return abi_sp->FixCodeAddress(address); + return address; +} + addr_t ValueObject::GetPointerValue(AddressType *address_type) { addr_t address = LLDB_INVALID_ADDRESS; if (address_type) @@ -1461,7 +1470,7 @@ case Value::ValueType::LoadAddress: case Value::ValueType::FileAddress: { lldb::offset_t data_offset = 0; - address = m_data.GetAddress(&data_offset); + address = GetStrippedPointerValue(m_data.GetAddress(&data_offset)); } break; } @@ -3000,6 +3009,11 @@ if (type) { CompilerType pointer_type(type.GetPointerType()); if (pointer_type) { + if (Process *process = exe_ctx.GetProcessPtr()) { + if (ABISP abi_sp = process->GetABI()) { + address = abi_sp->FixCodeAddress(address); + } + } lldb::DataBufferSP buffer( new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t))); lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create( Index: lldb/source/API/SBValue.cpp =================================================================== --- lldb/source/API/SBValue.cpp +++ lldb/source/API/SBValue.cpp @@ -30,6 +30,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" @@ -920,6 +921,25 @@ return fail_value; } +lldb::addr_t SBValue::GetValueAsAddress() { + addr_t fail_value = LLDB_INVALID_ADDRESS; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) { + bool success = true; + uint64_t ret_val = fail_value; + ret_val = value_sp->GetValueAsUnsigned(fail_value, &success); + if (!success) + return fail_value; + if (ProcessSP process_sp = m_opaque_sp->GetProcessSP()) + if (ABISP abi_sp = process_sp->GetABI()) + return abi_sp->FixCodeAddress(ret_val); + return ret_val; + } + + return fail_value; +} + bool SBValue::MightHaveChildren() { LLDB_INSTRUMENT_VA(this); Index: lldb/include/lldb/Core/ValueObject.h =================================================================== --- lldb/include/lldb/Core/ValueObject.h +++ lldb/include/lldb/Core/ValueObject.h @@ -564,6 +564,10 @@ lldb::addr_t GetPointerValue(AddressType *address_type = nullptr); + /// Remove TBI/MTE/ptrauth bits from address, if those are defined on this + /// target/ABI. + lldb::addr_t GetStrippedPointerValue(lldb::addr_t address); + lldb::ValueObjectSP GetSyntheticChild(ConstString key) const; lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create); Index: lldb/include/lldb/API/SBValue.h =================================================================== --- lldb/include/lldb/API/SBValue.h +++ lldb/include/lldb/API/SBValue.h @@ -62,6 +62,8 @@ uint64_t GetValueAsUnsigned(uint64_t fail_value = 0); + lldb::addr_t GetValueAsAddress(); + ValueType GetValueType(); // If you call this on a newly created ValueObject, it will always return Index: lldb/bindings/interface/SBValue.i =================================================================== --- lldb/bindings/interface/SBValue.i +++ lldb/bindings/interface/SBValue.i @@ -113,6 +113,28 @@ uint64_t GetValueAsUnsigned(uint64_t fail_value=0); + %feature("docstring", +" Return the value as an address. On failure, LLDB_INVALID_ADDRESS + will be returned. On architectures like AArch64, where the + top (unaddressable) bits can be used for authentication, + memory tagging, or top byte ignore, this method will return + the value with those top bits cleared. + + GetValueAsUnsigned returns the actual value, with the + authentication/TBI/MTE bits. + + Calling this on a random value which is not a pointer is an + incorrect. Call GetType().IsPointerType() if in doubt. + + An SB API program may want to show both the literal byte value + and the address it refers to in memory. These two SBValue + methods allow SB API writers to behave appropriately for their + interface." + ) GetValueAsAddress; + + lldb::addr_t + GetValueAsAddress(); + ValueType GetValueType ();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits