diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -66,6 +66,10 @@ return pid; } +int internal_dlinfo(void *handle, int request, void *p) { + UNIMPLEMENTED(); +} + uptr GetThreadSelf() { return reinterpret_cast(thrd_current()); } tid_t GetTid() { return GetThreadSelf(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libc.h b/compiler-rt/lib/sanitizer_common/sanitizer_libc.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_libc.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libc.h @@ -72,6 +72,8 @@ uptr internal_getpid(); uptr internal_getppid(); +int internal_dlinfo(void *handle, int request, void *p); + // Threading uptr internal_sched_yield(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -735,6 +735,10 @@ return internal_syscall(SYSCALL(getppid)); } +int internal_dlinfo(void *handle, int request, void *p) { + return dlinfo(handle, request, p); +} + uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { #if SANITIZER_FREEBSD return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -208,6 +208,10 @@ return getpid(); } +int internal_dlinfo(void *handle, int request, void *p) { + UNIMPLEMENTED(); +} + int internal_sigaction(int signum, const void *act, void *oldact) { return sigaction(signum, (const struct sigaction *)act, (struct sigaction *)oldact); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -265,6 +265,11 @@ return _REAL(getppid); } +int internal_dlinfo(void *handle, int request, void *p) { + DEFINE__REAL(int, dlinfo, void *a, int b, void *c); + return _REAL(dlinfo, handle, request, p); +} + uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) { DEFINE__REAL(int, __getdents30, int a, void *b, size_t c); return _REAL(__getdents30, fd, dirp, count); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -20,15 +20,15 @@ #include "sanitizer_platform.h" #include "sanitizer_platform_limits_posix.h" -// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that -// incorporates the map structure. -#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + 560))) // Get sys/_types.h, because that tells us whether 64-bit inodes are // used in struct dirent below. #include namespace __sanitizer { +void *__sanitizer_get_link_map_by_dlopen_handle(void *handle); +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle) + extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; #if defined(__powerpc64__) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -52,6 +52,7 @@ #include // #include +#include #include #include #include @@ -86,9 +87,15 @@ // Include these after system headers to avoid name clashes and ambiguities. #include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" #include "sanitizer_platform_limits_freebsd.h" namespace __sanitizer { +void *__sanitizer_get_link_map_by_dlopen_handle(void *handle) { + void *p = nullptr; + return internal_dlinfo(handle, RTLD_DI_LINKMAP, &p) == 0 ? p : nullptr; +} + unsigned struct_cap_rights_sz = sizeof(cap_rights_t); unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -19,18 +19,11 @@ #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" -#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \ - ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift)))) - -#if defined(__x86_64__) -#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 264) -#elif defined(__i386__) -#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 136) -#endif - namespace __sanitizer { +void *__sanitizer_get_link_map_by_dlopen_handle(void *handle); +# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + (link_map *)__sanitizer_get_link_map_by_dlopen_handle(handle) + extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; extern unsigned struct_rusage_sz; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -213,6 +213,7 @@ #include #include #include +#include #include #include #include @@ -258,9 +259,15 @@ // Include these after system headers to avoid name clashes and ambiguities. #include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" #include "sanitizer_platform_limits_netbsd.h" namespace __sanitizer { +void *__sanitizer_get_link_map_by_dlopen_handle(void* handle) { + void *p = nullptr; + return internal_dlinfo(handle, RTLD_DI_LINKMAP, &p) == 0 ? p : nullptr; +} + unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); unsigned struct_rusage_sz = sizeof(struct rusage); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cpp @@ -49,6 +49,10 @@ return getpid(); } +int internal_dlinfo(void *handle, int request, void *p) { + UNIMPLEMENTED(); +} + bool FileExists(const char *filename) { struct stat st; if (stat(filename, &st)) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -94,6 +94,10 @@ return GetProcessId(GetCurrentProcess()); } +int internal_dlinfo(void *handle, int request, void *p) { + UNIMPLEMENTED(); +} + // In contrast to POSIX, on Windows GetCurrentThreadId() // returns a system-unique identifier. tid_t GetTid() {