From: Damjan Jovanovic Subject: [PATCH] ntdll: get struct link_map fully working on all FreeBSD versions Message-Id: Date: Sun, 15 Nov 2020 09:52:13 +0200 autoheader and autoconf need to be run. Signed-off-by: Damjan Jovanovic --- configure.ac | 3 +++ dlls/ntdll/unix/loader.c | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 666219f5f36..455dc07b0e3 100644 --- a/configure.ac +++ b/configure.ac @@ -2219,6 +2219,9 @@ CFLAGS="$ac_save_CFLAGS" dnl Check for -ldl AC_SEARCH_LIBS(dlopen, dl) WINE_CHECK_LIB_FUNCS(dladdr dlinfo,[$DL_LIBS]) +AC_CHECK_MEMBERS([struct link_map.l_base],,, +[#include +#include ]) dnl Check for -lpoll for Mac OS X/Darwin if test "$ac_cv_func_poll" = no diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index c2b6ea603e3..43ddc6f166b 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1412,9 +1412,30 @@ found: caddr_t relocbase = (caddr_t)map->l_addr; #ifdef __FreeBSD__ - /* On older FreeBSD versions, l_addr was the absolute load address, now it's the relocation offset. */ + /* l_addr changed meaning from absolute load address (which is now l_base) + * to relocation offset, but also got moved within the struct, breaking + * the ABI via struct layout change: + * + * OLD header: NEW header: + * typedef struct link_map { typedef struct link_map { + * caddr_t l_addr; caddr_t l_base; + * ... ... + * ... caddr_t l_addr; + * }; }; + * + * OLD ld-elf.so: NEW ld-elf.so: + * ... exports _rtld_version_laddr_offset + * + * Since the header change and rtld change aren't coupled, we have to + * worry about the interaction between link.h version at compile time, + * and ld-elf.so version at runtime... + */ +#ifdef HAVE_STRUCT_LINK_MAP_L_BASE if (!dlsym(RTLD_DEFAULT, "_rtld_version_laddr_offset")) - if (!get_relocbase(map->l_addr, &relocbase)) return; + if (!get_relocbase(map->l_base, &relocbase)) return; +#else + if (!get_relocbase(map->l_addr, &relocbase)) return; +#endif #endif switch (dyn->d_tag) {