For ARMv8.3 pointer auth signing, lldb needs to know how many bits are valid for addressing, and strip the high bits off of addresses before looking them up. During the initial bringup, we didn't have dynamic ways of getting these values so we hardcoded a default addressing mask in lldb, and there are still some cases where we need to support this, where we still don't have the value dynamically declared.
There are three parts to this patch, all needed to construct a test. The most important part is that when I print ptrauth values, I always print the actual uint64_t with ptrauth bits included, then I strip the bits and see if it resolves to an address that lldb knows about. If so, then I use the normal formatter. For this test case, I needed this behavior in our function pointer formatter. Our normal output might look like
(lldb) p fmain
(int (*)(...)) $0 = 0x0000000100003f90 (a.out`main at main.c:3)
and with an ARMv8.3 ABI with ptrauth bits, you might see
(lldb) p fmain
(int (*)(...)) $0 = 0xe46bff0100003f8c (0xe46bff0100003f8c)
which is not helpful. So this patch does
(lldb) p fmain
(int (*)(...)) $0 = 0xe46bff0100003f8c (actual=0x0000000100003f8c a.out`main at main.c:3)
I never want to hide the ptrauth bit reality from the user - because they may be debugging a problem with ptrauth signing itself. The three parts of the patch:
- ABIMacOSX_arm64::FixAddress changed so if no mask is specified, uses the default mask.
- ObjectFileMachO::GetAllArchSpecs when reading a Mach-O binary, we were previously clearing the Vendor from the Triple that we create for the binary (so it would be arm64e--). This loses information - realistically, any binary in a Mach-O container is most likely following the Darwin ABIs and I want to retain the vendor so we can select the correct ABI instead of grabbing any random arm64 ABI.
- ArchSpec::SetArchitecture - explicitly set the vendor to Apple when we have a Mach-O architecture.
- formatters::CXXFunctionPointerSummaryProvider the formatter change above.
The test case for this is a main.c with main() and a function pointer global to main, fmain(). Then there is a standalone program that creates this specific corefile without any metadata about the addressing bits -- lldb itself always adds this metadata, so I couldn't use lldb's built-in process save-core functionality. It's a tiny corefile that only has 8 bytes of DATA memory where the function pointer is stored. I have ideas for how I can use this test case for some upcoming changes I want to make, so I expect to get more use out of this test case.
You could do if (Process *process = ....