diff --git a/configure b/configure index 81df494524d..dee9369bfaf 100755 --- a/configure +++ b/configure @@ -6888,6 +6888,7 @@ for ac_header in \ stropts.h \ sys/asoundlib.h \ sys/attr.h \ + sys/auxv.h \ sys/cdio.h \ sys/elf32.h \ sys/epoll.h \ @@ -15302,6 +15303,7 @@ for ac_func in \ futimes \ futimesat \ getattrlist \ + getauxval \ getopt_long_only \ getpwuid \ gettimeofday \ diff --git a/configure.ac b/configure.ac index f5b587c80a0..0a3b3b12cf5 100644 --- a/configure.ac +++ b/configure.ac @@ -465,6 +465,7 @@ AC_CHECK_HEADERS(\ stropts.h \ sys/asoundlib.h \ sys/attr.h \ + sys/auxv.h \ sys/cdio.h \ sys/elf32.h \ sys/epoll.h \ @@ -2012,6 +2013,7 @@ AC_CHECK_FUNCS(\ futimes \ futimesat \ getattrlist \ + getauxval \ getopt_long_only \ getpwuid \ gettimeofday \ diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 0506f6bc107..830dd3a0304 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -185,13 +185,56 @@ done: return status; } -#ifdef __APPLE__ +#ifdef __linux__ + +#ifdef HAVE_ELF_H +# include +#endif +#ifdef HAVE_LINK_H +# include +#endif +#ifdef HAVE_SYS_AUXV_H +# include +#endif +#ifndef HAVE_GETAUXVAL +static unsigned long getauxval( unsigned long id ) +{ + extern char **__wine_main_environ; + char **ptr = __wine_main_environ; + ElfW(auxv_t) *auxv; + + while (*ptr) ptr++; + while (!*ptr) ptr++; + for (auxv = (ElfW(auxv_t) *)ptr; auxv->a_type; auxv++) + if (auxv->a_type == id) return auxv->a_un.a_val; + return 0; +} +#endif + +static ULONG_PTR get_image_addr(void) +{ + ULONG_PTR size, num, phdr_addr = getauxval( AT_PHDR ); + ElfW(Phdr) *phdr; + + if (!phdr_addr) return 0; + phdr = (ElfW(Phdr) *)phdr_addr; + size = getauxval( AT_PHENT ); + num = getauxval( AT_PHNUM ); + while (num--) + { + if (phdr->p_type == PT_PHDR) return phdr_addr - phdr->p_offset; + phdr = (ElfW(Phdr) *)((char *)phdr + size); + } + return 0; +} + +#elif defined(__APPLE__) #include #include -static ULONG64 get_dyld_image_info_addr(void) +static ULONG_PTR get_image_addr(void) { - ULONG64 ret = 0; + ULONG_PTR ret = 0; #ifdef TASK_DYLD_INFO struct task_dyld_info dyld_info; mach_msg_type_number_t size = TASK_DYLD_INFO_COUNT; @@ -200,7 +243,13 @@ static ULONG64 get_dyld_image_info_addr(void) #endif return ret; } -#endif /* __APPLE__ */ + +#else +static ULONG_PTR get_image_addr(void) +{ + return 0; +} +#endif /*********************************************************************** * thread_init @@ -219,9 +268,6 @@ HANDLE thread_init(void) NTSTATUS status; struct ntdll_thread_data *thread_data; static struct debug_info debug_info; /* debug info for initial thread */ -#ifdef __APPLE__ - ULONG64 dyld_image_info; -#endif virtual_init(); @@ -270,20 +316,7 @@ HANDLE thread_init(void) InitializeListHead( &ldr.InLoadOrderModuleList ); InitializeListHead( &ldr.InMemoryOrderModuleList ); InitializeListHead( &ldr.InInitializationOrderModuleList ); -#ifdef __APPLE__ - dyld_image_info = get_dyld_image_info_addr(); -#ifdef __LP64__ -#ifdef WORDS_BIGENDIAN - peb->Reserved[1] = dyld_image_info & 0xFFFFFFFF; - peb->Reserved[0] = dyld_image_info >> 32; -#else - peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF; - peb->Reserved[1] = dyld_image_info >> 32; -#endif -#else - peb->Reserved[0] = dyld_image_info & 0xFFFFFFFF; -#endif -#endif + *(ULONG_PTR *)peb->Reserved = get_image_addr(); /* * Starting with Vista, the first user to log on has session id 1. diff --git a/include/config.h.in b/include/config.h.in index 9706e1420e1..1d4d6faf4a9 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -201,6 +201,9 @@ /* Define to 1 if you have the `getattrlist' function. */ #undef HAVE_GETATTRLIST +/* Define to 1 if you have the `getauxval' function. */ +#undef HAVE_GETAUXVAL + /* Define to 1 if you have the `getnameinfo' function. */ #undef HAVE_GETNAMEINFO @@ -1035,6 +1038,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ATTR_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_AUXV_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CDIO_H