Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fb7aed7
[lldb] Make StackID call Fix{Code,Data} pointers
felipepiovezan Aug 8, 2025
c52fe95
[lldb] Fix StackIDTest compilation issue
felipepiovezan Sep 2, 2025
077e351
[lldb] Call FixUpPointer in WritePointerToMemory (try 2) (#153585)
felipepiovezan Sep 4, 2025
da2792c
[lldb] Call FixAddress from TestSwiftAsyncBacktraceLocals
felipepiovezan Jul 30, 2025
a62c775
[lldb] Increase tolerance for skipped instructions in TestSwiftAsyncU…
felipepiovezan Jul 30, 2025
17e9a97
[lldb] Disable TestSwiftAsyncUnwindRecursiveQFunclets for arm64e
felipepiovezan Jul 31, 2025
007b207
[lldb] Fix typo in TestSwiftOtherArchDylib skipIf for arm64e
felipepiovezan Sep 2, 2025
52990e2
[lldb] Disable TestDAP_stackTraceMissingFunctionName on arm64e
felipepiovezan Jul 31, 2025
8cc7914
[lldb][NFC] Fix style issues with StackID.h (#157483)
felipepiovezan Sep 8, 2025
d695eb0
[lldb][nfc] Rename WritePointerToMemory argument's name (#157566)
felipepiovezan Sep 9, 2025
75070b0
[lldb] Make TestSwiftAsyncFrameVarMultipleFrames consider stripped po…
felipepiovezan Sep 11, 2025
5ecc9f1
[lldb] Strip pointer metadata when in Swift Task formatters
felipepiovezan Sep 11, 2025
c507ec1
[lldb] Track CFA pointer metadata in StackID (#157498)
felipepiovezan Sep 12, 2025
778cf98
[lldb] Fix TestSwiftAsyncFrameVarMultipleFrames under arm64e
felipepiovezan Sep 15, 2025
92b7d63
Reland "Revert "[lldb] Fix OP_deref evaluation for large integer resu…
felipepiovezan Sep 18, 2025
9613d7f
[lldb] Skip TestArmPointerMetadataStripping
felipepiovezan Sep 18, 2025
618f944
[lldb][nfc] Remove no-op calls to Fix*Address (#159586)
felipepiovezan Sep 18, 2025
5462859
[lldb][NFC] Simplify logic in ABIMacOSX_arm64::FixDataAddress (#159612)
felipepiovezan Sep 18, 2025
1c84c9b
[lldb] Don't call FixDataAddress when reading fp in ReadGPRValue (#15…
felipepiovezan Sep 19, 2025
31724b1
[lldb] Introduce Process::FixAnyAddressPreservingAuthentication
felipepiovezan Sep 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/include/lldb/Expression/IRMemoryMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class IRMemoryMap {
size_t size, Status &error);
void WriteScalarToMemory(lldb::addr_t process_address, Scalar &scalar,
size_t size, Status &error);
void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t address,
void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t pointer,
Status &error);
void ReadMemory(uint8_t *bytes, lldb::addr_t process_address, size_t size,
Status &error);
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Target/ABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ class ABI : public PluginInterface {
return FixDataAddress(pc);
}

virtual lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) {
return FixAnyAddress(pc);
}

llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; }

virtual void
Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/Target/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,11 @@ class Process : public std::enable_shared_from_this<Process>,
/// platforms where there is a difference (only Arm Thumb at this time).
lldb::addr_t FixAnyAddress(lldb::addr_t pc);

/// Strip pointer metadata except for the bits necessary to authenticate a
/// memory access. This is useful, for example, if `address` requires
/// authentication and it is going to be consumed in JITed code.
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t address);

/// Get the Modification ID of the process.
///
/// \return
Expand Down
78 changes: 36 additions & 42 deletions lldb/include/lldb/Target/StackID.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,27 @@
#define LLDB_TARGET_STACKID_H

#include "lldb/Core/AddressRange.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

class Process;

class StackID {
public:
// Constructors and Destructors
StackID() = default;

StackID(const StackID &rhs) = default;
explicit StackID(lldb::addr_t pc, lldb::addr_t cfa,
SymbolContextScope *symbol_scope, Process *process);

~StackID() = default;

lldb::addr_t GetPC() const { return m_pc; }

lldb::addr_t GetCallFrameAddress() const { return m_cfa; }
lldb::addr_t GetCallFrameAddressWithMetadata() const {
return m_cfa_with_metadata;
}

lldb::addr_t GetCallFrameAddressWithoutMetadata() const { return m_cfa; }

SymbolContextScope *GetSymbolContextScope() const { return m_symbol_scope; }

Expand All @@ -46,17 +51,6 @@ class StackID {

void Dump(Stream *s);

// Operators
const StackID &operator=(const StackID &rhs) {
if (this != &rhs) {
m_pc = rhs.m_pc;
m_cfa = rhs.m_cfa;
m_cfa_on_stack = rhs.m_cfa_on_stack;
m_symbol_scope = rhs.m_symbol_scope;
}
return *this;
}

/// Check if the CFA is on the stack, or elsewhere in the process, such as on
/// the heap.
bool IsCFAOnStack(Process &process) const;
Expand All @@ -68,34 +62,34 @@ class StackID {
protected:
friend class StackFrame;

explicit StackID(lldb::addr_t pc, lldb::addr_t cfa) : m_pc(pc), m_cfa(cfa) {}

void SetPC(lldb::addr_t pc) { m_pc = pc; }

void SetCFA(lldb::addr_t cfa) { m_cfa = cfa; }

lldb::addr_t m_pc =
LLDB_INVALID_ADDRESS; // The pc value for the function/symbol for this
// frame. This will
// only get used if the symbol scope is nullptr (the code where we are
// stopped is not represented by any function or symbol in any shared
// library).
lldb::addr_t m_cfa =
LLDB_INVALID_ADDRESS; // The call frame address (stack pointer) value
// at the beginning of the function that uniquely
// identifies this frame (along with m_symbol_scope
// below)
// True if the CFA is an address on the stack, false if it's an address
// elsewhere (ie heap).
void SetPC(lldb::addr_t pc, Process *process);
void SetCFA(lldb::addr_t cfa, Process *process);

/// The pc value for the function/symbol for this frame. This will only get
/// used if the symbol scope is nullptr (the code where we are stopped is not
/// represented by any function or symbol in any shared library).
lldb::addr_t m_pc = LLDB_INVALID_ADDRESS;

/// The call frame address (stack pointer) value at the beginning of the
/// function that uniquely identifies this frame (along with m_symbol_scope
/// below)
lldb::addr_t m_cfa = LLDB_INVALID_ADDRESS;

/// The cfa with metadata (i.e. prior to Process::FixAddress).
lldb::addr_t m_cfa_with_metadata = LLDB_INVALID_ADDRESS;

/// If nullptr, there is no block or symbol for this frame. If not nullptr,
/// this will either be the scope for the lexical block for the frame, or the
/// scope for the symbol. Symbol context scopes are always be unique pointers
/// since the are part of the Block and Symbol objects and can easily be used
/// to tell if a stack ID is the same as another.
SymbolContextScope *m_symbol_scope = nullptr;

// BEGIN SWIFT
/// True if the CFA is an address on the stack, false if it's an address
/// elsewhere (ie heap).
mutable LazyBool m_cfa_on_stack = eLazyBoolCalculate;
SymbolContextScope *m_symbol_scope =
nullptr; // If nullptr, there is no block or symbol for this frame.
// If not nullptr, this will either be the scope for the
// lexical block for the frame, or the scope for the
// symbol. Symbol context scopes are always be unique
// pointers since the are part of the Block and Symbol
// objects and can easily be used to tell if a stack ID
// is the same as another.
// END SWIFT
};

bool operator==(const StackID &lhs, const StackID &rhs);
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/API/SBFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ lldb::addr_t SBFrame::GetCFA() const {

StackFrame *frame = exe_ctx.GetFramePtr();
if (frame)
return frame->GetStackID().GetCallFrameAddress();
return frame->GetStackID().GetCallFrameAddressWithoutMetadata();
return LLDB_INVALID_ADDRESS;
}

Expand Down
4 changes: 1 addition & 3 deletions lldb/source/Expression/DWARFExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,6 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
lldb::addr_t pointer_value =
process->ReadPointerFromMemory(pointer_addr, error);
if (pointer_value != LLDB_INVALID_ADDRESS) {
if (ABISP abi_sp = process->GetABI())
pointer_value = abi_sp->FixCodeAddress(pointer_value);
stack.back().GetScalar() = pointer_value;
stack.back().ClearContext();
} else {
Expand Down Expand Up @@ -2279,7 +2277,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
// Note that we don't have to parse FDEs because this DWARF expression
// is commonly evaluated with a valid stack frame.
StackID id = frame->GetStackID();
addr_t cfa = id.GetCallFrameAddress();
addr_t cfa = id.GetCallFrameAddressWithMetadata();
if (cfa != LLDB_INVALID_ADDRESS) {
stack.push_back(Scalar(cfa));
stack.back().SetValueType(Value::ValueType::LoadAddress);
Expand Down
13 changes: 11 additions & 2 deletions lldb/source/Expression/IRMemoryMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,19 @@ void IRMemoryMap::WriteScalarToMemory(lldb::addr_t process_address,
}

void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
lldb::addr_t address, Status &error) {
lldb::addr_t pointer, Status &error) {
error.Clear();

Scalar scalar(address);
/// Only ask the Process to fix `pointer` if the address belongs to the
/// process. An address belongs to the process if the Allocation policy is not
/// eAllocationPolicyHostOnly.
auto it = FindAllocation(pointer, 1);
if (it == m_allocations.end() ||
it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly)
if (auto process_sp = GetProcessWP().lock())
pointer = process_sp->FixAnyAddressPreservingAuthentication(pointer);

Scalar scalar(pointer);

WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
}
Expand Down
66 changes: 36 additions & 30 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,42 +811,48 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
return return_valobj_sp;
}

addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
addr_t pac_sign_extension = 0x0080000000000000ULL;
addr_t tbi_mask = 0xff80000000000000ULL;
addr_t mask = 0;

if (ProcessSP process_sp = GetProcessSP()) {
mask = process_sp->GetCodeAddressMask();
if (pc & pac_sign_extension) {
addr_t highmem_mask = process_sp->GetHighmemCodeAddressMask();
if (highmem_mask != LLDB_INVALID_ADDRESS_MASK)
mask = highmem_mask;
}
}
constexpr addr_t tbi_mask = 0xff80000000000000ULL;
constexpr addr_t pac_sign_extension = 0x0080000000000000ULL;

/// Consults the process for its {code, data} address masks and applies it to
/// `addr`.
static addr_t DoFixAddr(addr_t addr, bool is_code, ProcessSP process_sp) {
if (!process_sp)
return addr;

addr_t mask = is_code ? process_sp->GetCodeAddressMask()
: process_sp->GetDataAddressMask();
if (mask == LLDB_INVALID_ADDRESS_MASK)
mask = tbi_mask;

return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
if (addr & pac_sign_extension) {
addr_t highmem_mask = is_code ? process_sp->GetHighmemCodeAddressMask()
: process_sp->GetHighmemCodeAddressMask();
if (highmem_mask != LLDB_INVALID_ADDRESS_MASK)
return addr | highmem_mask;
return addr | mask;
}

return addr & (~mask);
}

addr_t ABIMacOSX_arm64::FixDataAddress(addr_t pc) {
addr_t pac_sign_extension = 0x0080000000000000ULL;
addr_t tbi_mask = 0xff80000000000000ULL;
addr_t mask = 0;

if (ProcessSP process_sp = GetProcessSP()) {
mask = process_sp->GetDataAddressMask();
if (pc & pac_sign_extension) {
addr_t highmem_mask = process_sp->GetHighmemDataAddressMask();
if (highmem_mask != LLDB_INVALID_ADDRESS_MASK)
mask = highmem_mask;
}
}
if (mask == LLDB_INVALID_ADDRESS_MASK)
mask = tbi_mask;
addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) {
ProcessSP process_sp = GetProcessSP();
return DoFixAddr(pc, true /*is_code*/, GetProcessSP());
}

addr_t ABIMacOSX_arm64::FixDataAddress(addr_t addr) {
ProcessSP process_sp = GetProcessSP();
return DoFixAddr(addr, false /*is_code*/, GetProcessSP());
}

addr_t ABIMacOSX_arm64::FixAnyAddressPreservingAuthentication(addr_t addr) {
// Save the old MTE tag and restore it later.
constexpr addr_t mte_mask = 0x0f00000000000000ULL;
addr_t old_mte_tag = addr & mte_mask;

return (pc & pac_sign_extension) ? pc | mask : pc & (~mask);
addr_t fixed_addr = FixDataAddress(addr);
return old_mte_tag | (fixed_addr & (~mte_mask));
}

void ABIMacOSX_arm64::Initialize() {
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class ABIMacOSX_arm64 : public ABIAArch64 {

lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) override;

// Static Functions

Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Plugins/Language/Swift/SwiftFormatters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,8 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
m_ts->GetTypeFromMangledTypename(ConstString("$sSVD"));

addr_t value = m_task_ptr;
if (auto process_sp = m_backend.GetProcessSP())
value = process_sp->FixDataAddress(value);
DataExtractor data{reinterpret_cast<const void *>(&value),
sizeof(value), endian::InlHostByteOrder(),
sizeof(void *)};
Expand Down Expand Up @@ -903,7 +905,7 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
parent_addr = 0;
}

addr_t value = parent_addr;
addr_t value = process_sp->FixDataAddress(parent_addr);
DataExtractor data{reinterpret_cast<const void *>(&value),
sizeof(value), endian::InlHostByteOrder(),
sizeof(void *)};
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/Target/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6048,6 +6048,12 @@ addr_t Process::FixAnyAddress(addr_t addr) {
return addr;
}

addr_t Process::FixAnyAddressPreservingAuthentication(addr_t addr) {
if (ABISP abi_sp = GetABI())
addr = abi_sp->FixAnyAddressPreservingAuthentication(addr);
return addr;
}

void Process::DidExec() {
Log *log = GetLog(LLDBLog::Process);
LLDB_LOGF(log, "Process::%s()", __FUNCTION__);
Expand Down
Loading