Skip to content

Conversation

felipepiovezan
Copy link
Contributor

In architectures where pointers may contain metadata, such as arm64e, the metadata may need to be cleaned prior to sending this pointer to be used in expression evaluation generated code.

This patch is a step towards allowing consumers of pointers to decide whether they want to keep or remove metadata, as opposed to discarding metadata at the moment pointers are created. See
#150537.

This was tested running the LLDB test suite on arm64e.

In architectures where pointers may contain metadata, such as arm64e,
the metadata may need to be cleaned prior to sending this pointer to be
used in expression evaluation generated code.

This patch is a step towards allowing consumers of pointers to decide
whether they want to keep or remove metadata, as opposed to discarding
metadata at the moment pointers are created. See
llvm#150537.

This was tested running the LLDB test suite on arm64e.
@llvmbot
Copy link
Member

llvmbot commented Aug 8, 2025

@llvm/pr-subscribers-lldb

Author: Felipe de Azevedo Piovezan (felipepiovezan)

Changes

In architectures where pointers may contain metadata, such as arm64e, the metadata may need to be cleaned prior to sending this pointer to be used in expression evaluation generated code.

This patch is a step towards allowing consumers of pointers to decide whether they want to keep or remove metadata, as opposed to discarding metadata at the moment pointers are created. See
#150537.

This was tested running the LLDB test suite on arm64e.


Full diff: https://github.com/llvm/llvm-project/pull/152798.diff

1 Files Affected:

  • (modified) lldb/source/Expression/IRMemoryMap.cpp (+3)
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index 150699352a2e3..8be389973f123 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -640,6 +640,9 @@ void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
                                        lldb::addr_t address, Status &error) {
   error.Clear();
 
+  if (auto process_sp = GetProcessWP().lock())
+    address = process_sp->FixAnyAddress(address);
+
   Scalar scalar(address);
 
   WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);

Copy link
Collaborator

@jasonmolenda jasonmolenda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

error.Clear();

if (auto process_sp = GetProcessWP().lock())
address = process_sp->FixAnyAddress(address);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put this deeper down, in WriteScalarToMemory or even WriteMemory ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting it here might fix tests but the other code paths might be lacking coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only pointers need to be fixed though. I'm not sure I understand?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHHH, I see the confusion now: note that this is not fixing the "pointer where the data is written", but rather it is fixing the "pointer written to memory". (see the name of the method: Write**Pointer**ToMemory)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least one thing in this method should be actually be called pointer, but that's not your fault.

I'm not 100% sure that all pointer values here do want to be fixed. Looking at the uses of this method inside of lldb I see:

  • materialising references to variables
  • setting up the stack frame for a function call, in some ABI plugins

Both of which should be ok with removing the current uses of non-address bits. If you remove pointer authentication bits from a function pointer, it should still authenticate, it's just unsigned. So if there was code that checked for that, that's a corner case that won't work.

It's not in the SB API so there's nothing to break there.

Probably some corner case here but short of a major rework of how we handle addresses, this is a good step. We can consider it a bug fix to the current strategy, whether that strategy is ultimately good or bad.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will make a note of that possibility and try to make things break when I get the chance, as this is the kind of corner case I want to explore too.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pointer authentication is probably ok unless your ABI specifically checks that there is a non-zero authentication code. I'm assuming a code of 0 will always authenticate.

For memory tagging if your memory allocator uses tags you would not be able to write to write via. a pointer to a heap allocation. The top byte would be removed and treated as tag 0 which is often used to mark unallocated areas (though you don't have to, some will randomise it).

(you can read/write a heap allocation with lldb's commands because debug APIs ignore tag mismatches)

I'm not sure how exactly you'd hit this from LLDB. And I wonder if you could work around it with some crafty casting in and out of uintptr_t.

I will make a note to try out memory tagging.

Istr Objective C using the top byte for something, you could look into that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact the more I think about it, debug APIs are allowed to ignore memory attributes but I'm not so sure expressions should.

We can consider it a bug fix to the current strategy, whether that strategy is ultimately good or bad.

But this still applies. Can't consider a change before we make the existing thing consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the crucial part of your observations is that we really need to delay cleaning those attributes until absolutely necessary (e.g. #150537), so that we then have the chance to decide whether/which bits to clean up. In that sense, the existing patches are a step in that direction.

Copy link
Collaborator

@DavidSpickett DavidSpickett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@felipepiovezan felipepiovezan merged commit 18ef8d7 into llvm:main Aug 11, 2025
11 checks passed
@felipepiovezan felipepiovezan deleted the felipe/cleanup_pointers_expr_eval branch August 11, 2025 16:39
@bulbazord
Copy link
Member

Heads up, this broke TestScriptedProcessEmptyMemoryRegion.py on Green Dragon. Could you please fix forward or revert?
https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/31278/console
(Note the builds have been red for a while now, I bisected the last day's commits to determine this is the offending change)

@felipepiovezan
Copy link
Contributor Author

Heads up, this broke TestScriptedProcessEmptyMemoryRegion.py on Green Dragon. Could you please fix forward or revert? https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/31278/console (Note the builds have been red for a while now, I bisected the last day's commits to determine this is the offending change)

Looking at this now. If it's not a simple test change, I'll revert and have a look with more time tomorrow.

@felipepiovezan
Copy link
Contributor Author

This test is exercising a corner case when we can't allocate memory in the inferior, so we allocate it in the lldb process and give it a magic address which is, allegedly, never going to be used by the inferior. And this address has some of those bits that would get cleaned set....
I'll revert the patch for now.

@felipepiovezan
Copy link
Contributor Author

Reverted yesterday in: a203546 20250812 fpiove.. Revert "[lldb] Call FixUpPointer in WritePointerToMemory"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants