feat: macOS feasibility incorporation#71
feat: macOS feasibility incorporation#71saleha-muzammil wants to merge 34 commits intocharmoniumQ:mainfrom
Conversation
probe_src/libprobe/src/prov_buffer.c
Outdated
There was a problem hiding this comment.
Don't we not need this ifdef since x & CLONE_VFORK will always be 0?
There was a problem hiding this comment.
incorporated ( removed CLONE_VFORKdefinition from prov_buffer.c )
| * Generate a macOS interpose struct | ||
| * Types from: http://opensource.apple.com/source/dyld/dyld-210.2.3/include/mach-o/dyld-interposing.h | ||
| */ | ||
| #define OSX_INTERPOSE_STRUCT(NEW, OLD) \ |
There was a problem hiding this comment.
Normally, pre-processor macros would be the right way to eliminate duplicated code.
In this particular case, the C code is generated from Python in generator/gen_libc_hooks.py, and there isn't a good way to emit code that calls the C preprocessor macros. It would be better to implement the logic directly in Python.
Therefore, for the above file, can you write out what it should be after expanding the pre-processor macros?
There was a problem hiding this comment.
My concern is that in Linux, the shared library needs to define a function with the name we want to interpose (e.g., open), and load the real/underlying function with a new name (e.g., unwrapped_open) using dlsym.
In Mac, it seems that we define a function with the new name (e.g., my_open), and call the real/underlying function with the original name (open)
__attribute__ ((section ("__DATA,__interpose"))) = {
(const void*)(unsigned long)&my_open,
(const void*)(unsigned long)&open
};
The meaning of the name open is reversed: in Linux its the wrapper; in Mac it's the underlying function.
There was a problem hiding this comment.
This is of course salvageable. We should always call unwrapped_open and wrapped_open to eliminate confusion, but alias one of them to the "original name" based on platform.
#ifdef linux
#define wrapped_open open
#else if apple
#define unwrapped_open open
#endif
We hardly ever call the wrapped versions, always the unwrapped, which are already called as unwrapped_ in our code.
But I wanted to confirm that this is the only way to interpose functions in Mac before doing that. So please let me know.
Co-authored-by: Jenna Fligor <jenna@fligor.net>
Co-authored-by: Jenna Fligor <jenna@fligor.net>
Co-authored-by: Jenna Fligor <jenna@fligor.net>
| if (!__process_inited) { | ||
| __process_inited = true; | ||
|
|
||
| DEBUG("Initializing process"); | ||
| init_function_pointers(); | ||
| check_function_pointers(); | ||
| init_process_global_state(); | ||
|
|
||
| pthread_key_create(&tld_key, free); | ||
|
|
||
| __process_inited_done = true; | ||
| } | ||
| while (!__process_inited_done) { | ||
| sched_yield(); | ||
| } | ||
|
|
There was a problem hiding this comment.
I think there may be a race if multiple threads try to init at the same. I think I specified the algorihtm incorrectly (slightly the first time). Here's what it should be:
if (is process inited) {
if (test_and_set(is first thread)) {
... do your process initialization you have here
is process initted = true;
} else {
// process is not initted, but someone else is already handling it.
while (!process is inited) { sched_yield(); }
}
}
// process is inited here. Yay!
There was a problem hiding this comment.
test_and_set should be replaced __sync_bool_compare_and_swap
Description:
Making
PROBEfeasible for macOS systems.Changes:
Worked out how to interpose in macOS, added a test program (
test_program.c), which interposes thefopencall and calls the underlying call. The mentioned changes are in filesinterpose.h,interpose.c,test_program.c. Steps to runtest_program.cwith interposition:clang -dynamiclib -o libinterpose.dylib interpose.cclang -o test_program test_program.cexport DYLD_INSERT_LIBRARIES=$(pwd)/libinterpose.dylib./test_programAdded macOS architecture in
flake.nixEdited
Makefileto be adjustable for both linux and macOS.The rest of the changes have been made either to add replacement libraries for macOS, added
ifndefwith code blocks which are linux or macOS specific. Added dummy definitions liketypedef thrd_t intfor macros which are not available on macOS. Guarded dummy definitions withifndefQuestions and next steps: