This is an archive of the discontinued LLVM Phabricator instance.

Write the # of addressable bits into Mach-O corefiles, read it back out again
ClosedPublic

Authored by jasonmolenda on Jul 20 2021, 12:58 AM.

Details

Summary

On systems where we have an address mask, add support to process save-core to note the number of bits used for addressing in the corefile in an LC_NOTE, and look for that value in a corefile and set the mask in the Process.

In a live debug session on Apple Silicon using arm64e, debugserver reports the number of bits used for addressing. Corefiles of those same processes don't currently record this information any place, making them hard to use. This is a simple patch to add the LC_NOTE and read it back in again, nothing fancy.

I added a couple of comments on the masks to note that the mask uses 1 bits to indicate bits not used in addressing, open to disagreements about this but it always seemed backwards to me (I know we're following what the Linux kernel provides) and I will confuse myself if I'm not careful. Basically, leaving notes so Future Jason doesn't have to puzzle over the right answer quite so long, because I'm sure I'll forget this again.

Diff Detail

Event Timeline

jasonmolenda created this revision.Jul 20 2021, 12:58 AM
jasonmolenda requested review of this revision.Jul 20 2021, 12:58 AM
JDevlieghere added inline comments.Jul 20 2021, 10:49 AM
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
5575–5613

Given that this function and the one below are basically doing the same thing, would it make sense to make this a generic helper that takes a lambda so we can share the logic to get to the LC_NOTE data?

lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
544–545
if (addr_t address_mask = core_objfile->GetAddressMask()) {
shafik added a subscriber: shafik.Jul 20 2021, 3:19 PM
shafik added inline comments.
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
5575–5613

I also noticed in one of the places we are doing this work we do:

memset(data_owner, 0, sizeof(data_owner));

Should we be doing this in all places? We can also do that simpler by:

char data_owner[17]{0}

Update patch to address Jonas' suggestion of not duplicating the code to write the LC_NOTE load command & payloads (I was annoyed by this too but didn't deal with it in my first pass). Also add a test, although it only is really tested on an arm64e testsuite run where the compiler is doing PAC auth on return addresses.

One more bit I meant to do -- added output to "process status --verbose" to show the addressing masks in effect. There's no other way to check what lldb is currently using for ptrauth masks currently, to debug/confirm what lldb is using.

There's the target.process.virtual-addressable-bits setting, but this is separate from what lldb might pick up dynamically (from lldb-server, debugserver, a core file) so querying that setting will show 0 if lldb is using the dynamically determined mask.

I couldn't think of any place better to put this, this will do for now.

This revision was not accepted when it landed; it landed in state Needs Review.Jul 22 2021, 1:07 AM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.