diff --git a/lib/std/start.zig b/lib/std/start.zig index fcc7fcd10021bb08f632d49586c6c56b281be426..5bbb4dadce768158cb73a2b2a0083b31dbf02df5 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -455,7 +455,6 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { if (native_os == .linux) { // Find the beginning of the auxiliary vector const auxv: [*]elf.Auxv = @ptrCast(@alignCast(envp.ptr + envp_count + 1)); - std.os.linux.elf_aux_maybe = auxv; var at_hwcap: usize = 0; const phdrs = init: { @@ -479,6 +478,10 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { std.os.linux.pie.relocate(phdrs); } + // This must be done after PIE relocations have been applied or we may crash + // while trying to access the global variable (happens on MIPS at least). + std.os.linux.elf_aux_maybe = auxv; + if (!builtin.single_threaded) { // ARMv6 targets (and earlier) have no support for TLS in hardware. // FIXME: Elide the check for targets >= ARMv7 when the target feature API