Module: wine Branch: master Commit: ac1761d1dae8bf114a05e28ed6886deba6c2c860 URL: https://gitlab.winehq.org/wine/wine/-/commit/ac1761d1dae8bf114a05e28ed6886de...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jun 19 17:32:01 2023 +0200
loader: Build the preloader as PIE on 64-bit.
---
configure | 38 +++++++++++++++++++++++++++++++++++++- configure.ac | 11 ++++++++++- loader/preloader.c | 7 ++++--- 3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/configure b/configure index e2f60383fa0..f41b9cd687f 100755 --- a/configure +++ b/configure @@ -10245,11 +10245,47 @@ if test "x$ac_cv_cflags__Wl___export_dynamic" = xyes then : WINELOADER_LDFLAGS="-Wl,--export-dynamic" fi + WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs"
case $host_os in linux*) as_fn_append WINELOADER_LDFLAGS " -pie" - WINEPRELOADER_LDFLAGS="-static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7d400000" + case $HOST_ARCH in + i386|arm) + as_fn_append WINEPRELOADER_LDFLAGS " -static -Wl,-Ttext=0x7d400000" ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -static-pie" >&5 +printf %s "checking whether the compiler supports -static-pie... " >&6; } +if test ${ac_cv_cflags__static_pie+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_wine_try_cflags_saved=$CFLAGS +CFLAGS="$CFLAGS -static-pie" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(int argc, char **argv) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_cflags__static_pie=yes +else $as_nop + ac_cv_cflags__static_pie=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS=$ac_wine_try_cflags_saved +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags__static_pie" >&5 +printf "%s\n" "$ac_cv_cflags__static_pie" >&6; } +if test "x$ac_cv_cflags__static_pie" = xyes +then : + as_fn_append WINEPRELOADER_LDFLAGS " -static-pie" +else $as_nop + as_fn_append WINEPRELOADER_LDFLAGS " -static -Wl,-Ttext=0x7d7d00000000" +fi + ;; + esac ;; *) case $HOST_ARCH in diff --git a/configure.ac b/configure.ac index 562d50209a6..bed7b2dec28 100644 --- a/configure.ac +++ b/configure.ac @@ -769,11 +769,20 @@ case $host_os in
WINE_TRY_CFLAGS([-Wl,-z,defs],[UNIXLDFLAGS="$UNIXLDFLAGS -Wl,-z,defs"]) WINE_TRY_CFLAGS([-Wl,--export-dynamic],[WINELOADER_LDFLAGS="-Wl,--export-dynamic"]) + WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs"
case $host_os in linux*) AS_VAR_APPEND([WINELOADER_LDFLAGS],[" -pie"]) - WINEPRELOADER_LDFLAGS="-static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7d400000" + case $HOST_ARCH in + i386|arm) + AS_VAR_APPEND([WINEPRELOADER_LDFLAGS],[" -static -Wl,-Ttext=0x7d400000"]) ;; + *) + WINE_TRY_CFLAGS([-static-pie], + [AS_VAR_APPEND([WINEPRELOADER_LDFLAGS],[" -static-pie"])], + [AS_VAR_APPEND([WINEPRELOADER_LDFLAGS],[" -static -Wl,-Ttext=0x7d7d00000000"])]) + ;; + esac ;; *) case $HOST_ARCH in diff --git a/loader/preloader.c b/loader/preloader.c index 3fbee0877d4..4045db64822 100644 --- a/loader/preloader.c +++ b/loader/preloader.c @@ -351,7 +351,7 @@ __ASM_GLOBAL_FUNC(_start, "movq %rsp,%rax\n\t" "leaq -144(%rsp),%rsp\n\t" /* allocate some space for extra aux values */ "movq %rax,(%rsp)\n\t" /* orig stack pointer */ - "movq $thread_data,%rsi\n\t" + "movq thread_data(%rip),%rsi\n\t" "movq $0x1002,%rdi\n\t" /* ARCH_SET_FS */ "movq $158,%rax\n\t" /* SYS_arch_prctl */ "syscall\n\t" @@ -439,7 +439,8 @@ __ASM_GLOBAL_FUNC(_start, "mov x0, SP\n\t" "sub SP, SP, #144\n\t" /* allocate some space for extra aux values */ "str x0, [SP]\n\t" /* orig stack pointer */ - "ldr x0, =thread_data\n\t" + "adrp x0, thread_data\n\t" + "add x0, x0, :lo12:thread_data\n\t" "msr tpidr_el0, x0\n\t" "mov x0, SP\n\t" /* ptr to orig stack pointer */ "bl wld_start\n\t" @@ -1398,7 +1399,7 @@ void* wld_start( void **stack ) page_size = get_auxiliary( av, AT_PAGESZ, 4096 ); page_mask = page_size - 1;
- preloader_start = (char *)_start - ((unsigned long)_start & page_mask); + preloader_start = (char *)((unsigned long)_start & ~page_mask); preloader_end = (char *)((unsigned long)(_end + page_mask) & ~page_mask);
#ifdef DUMP_AUX_INFO