github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/binary_info/entrypoint_darwin_arm64.go (about) 1 //go:build arm64 && darwin 2 // +build arm64,darwin 3 4 package binary_info 5 6 import "unsafe" 7 8 9 10 /* #cgo CFLAGS: 11 #include <mach-o/getsect.h> 12 #include <stdlib.h> 13 #include <mach-o/dyld.h> 14 #include <string.h> 15 16 bool str_ends_with(const char* str, const char* pattern, int pattern_size){ 17 int str_size = strlen(str); 18 int delta = str_size-pattern_size; 19 if (delta<0){ 20 return false; 21 } 22 return strcmp(str+delta,pattern) == 0; 23 } 24 25 uint64_t StaticBaseAddress(void) { 26 uint64_t addr = 0; 27 const struct segment_command_64* command = getsegbyname("__TEXT"); 28 if (command) { 29 addr = command->vmaddr; 30 } 31 return addr; 32 } 33 34 intptr_t ImageSlide(char* imagePath) { 35 for (uint32_t i = 0; i < _dyld_image_count(); i++) { 36 // Iterate over all loaded images and check if there is a match to the imagePath 37 if (strcmp(_dyld_get_image_name(i), imagePath) == 0) { 38 return _dyld_get_image_vmaddr_slide(i); 39 } 40 } 41 42 // If we didn't find a match, it's possible that the image path we search is a suffix of one of the loaded images, so it's best effort to use that. 43 // I saw that it happens when running the tests with our "make test". In this case the loaded image path is "/private/<imagePath>" 44 // instead of <imagePath> 45 int imagePathLen = strlen(imagePath); 46 for (uint32_t i = 0; i < _dyld_image_count(); i++) { 47 if (str_ends_with(_dyld_get_image_name(i), imagePath, imagePathLen)) { 48 return _dyld_get_image_vmaddr_slide(i); 49 } 50 } 51 return 0; 52 } 53 54 uint64_t DynamicBaseAddress(char* imagePath) { 55 return StaticBaseAddress() + ImageSlide(imagePath); 56 } 57 */ 58 import "C" 59 60 61 62 63 func GetEntrypoint(imagePath string) uint64 { 64 cPath := C.CString(imagePath) 65 defer C.free(unsafe.Pointer(cPath)) 66 return uint64(C.DynamicBaseAddress(cPath)) 67 }