-
Notifications
You must be signed in to change notification settings - Fork 581
i#5383: macOS a64 client threads and private TLS #7300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
@@ -1246,7 +1246,7 @@ signal_thread_inherit(dcontext_t *dcontext, void *clone_record) | |||
* FIXME: are current pending or blocked inherited? | |||
*/ | |||
#ifdef MACOS | |||
if (record->app_thread_xsp != 0) { | |||
if (record->app_thread_xsp == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really understand this code but you'll get heap oob/uaf asserts if this condition is !=
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is freeing the clone record.
See the comment in clone_record_t:
#ifdef MACOS
/* XXX i#1403: once we have lower-level, earlier thread interception we can
* likely switch to something closer to what we do on Linux.
* This is used for bsdthread_create, where app_thread_xsp is NULL;
* for vfork, app_thread_xsp is non-NULL and this is unused.
*/
This change != to == looks suspect. Please double check vs this pasted comment: if bsdthread_create ends up different on aarch64 please update that comment; does it need separate handling a64 vs x86.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so please correct me if I'm wrong (and it's been like three months since I looked at this code, so I'm probably wrong), but in the MACOS case create_clone_record
sets app_thread_xsp to NULL iff the clone record is heap-allocated. So I think the only case in which we want to free it is if it's NULL.
Lines 796 to 803 in 0502fd3
if (app_thread_xsp == NULL) { | |
record = HEAP_TYPE_ALLOC(GLOBAL_DCONTEXT, clone_record_t, ACCT_THREAD_MGT, | |
true /*prot*/); | |
record->app_thread_xsp = 0; | |
record->continuation_pc = thread_func; | |
record->thread_arg = thread_arg; | |
record->clone_flags = CLONE_THREAD | CLONE_VM | CLONE_SIGHAND | SIGCHLD; | |
} else { |
Some messy stuff I'm not sure if there's a better way to do:
You'll get a backtrace like this if we do not maintain a valid thread register during entry and exit.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for contributing. I have mostly style comments but also some points need clarifying.
@@ -1246,7 +1246,7 @@ signal_thread_inherit(dcontext_t *dcontext, void *clone_record) | |||
* FIXME: are current pending or blocked inherited? | |||
*/ | |||
#ifdef MACOS | |||
if (record->app_thread_xsp != 0) { | |||
if (record->app_thread_xsp == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is freeing the clone record.
See the comment in clone_record_t:
#ifdef MACOS
/* XXX i#1403: once we have lower-level, earlier thread interception we can
* likely switch to something closer to what we do on Linux.
* This is used for bsdthread_create, where app_thread_xsp is NULL;
* for vfork, app_thread_xsp is non-NULL and this is unused.
*/
This change != to == looks suspect. Please double check vs this pasted comment: if bsdthread_create ends up different on aarch64 please update that comment; does it need separate handling a64 vs x86.
I think I addressed everything, except for the clone record free. I left a comment about that in the review and in the code, please see if it makes sense. |
Sorry, i was testing this some more and found out the mach syscalls via I've patched the drlibc asm to use the normal (non-indirect) convention (i.e. args in x0-x7, number in x16). Currently it seems like mach syscalls use negated syscall numbers, which works on my machine and matches the shipped asm on macOS 14.4.1:
This seems to differ from how it's done in drlibc_x86.asm (which ors |
OK -- i took this opportunity to also implement dynamorio_mach_dep_syscall, so now this PR uses the raw machdep syscall instead of the |
Adds macOS ARM64 support for client threads and private TLS (under
-private_loader
-- though we don't implement a full private loader yet).dynamorio_mach_syscall
anddynamorio_mach_dep_syscall
now use the correct a64 calling conventionThe end result is that client threads can start and terminate properly, and multithreaded applications can also terminate without crashing. I did not test attach/detach, but I'm guessing it's still broken (there is no injector implementation anyway iiuc)