mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 16:45:27 +00:00
Merge pull request #20822 from alexrp/start-mips-fixes
`start`: A handful of MIPS fixes
This commit is contained in:
commit
7342017404
@ -289,17 +289,42 @@ fn _start() callconv(.Naked) noreturn {
|
||||
,
|
||||
.mips, .mipsel =>
|
||||
\\ move $fp, $0
|
||||
\\ bal 1f
|
||||
\\ .gpword .
|
||||
\\ .gpword %[posixCallMainAndExit]
|
||||
\\ 1:
|
||||
\\ lw $gp, 0($ra)
|
||||
\\ subu $gp, $ra, $gp
|
||||
\\ lw $25, 4($ra)
|
||||
\\ addu $25, $25, $gp
|
||||
\\ move $ra, $0
|
||||
\\ move $a0, $sp
|
||||
\\ and $sp, -8
|
||||
\\ j %[posixCallMainAndExit]
|
||||
\\ subu $sp, $sp, 16
|
||||
\\ jalr $25
|
||||
,
|
||||
.mips64, .mips64el =>
|
||||
\\ move $fp, $0
|
||||
// This is needed because early MIPS versions don't support misaligned loads. Without
|
||||
// this directive, the hidden `nop` inserted to fill the delay slot after `bal` would
|
||||
// cause the two doublewords to be aligned to 4 bytes instead of 8.
|
||||
\\ .balign 8
|
||||
\\ bal 1f
|
||||
\\ .gpdword .
|
||||
\\ .gpdword %[posixCallMainAndExit]
|
||||
\\ 1:
|
||||
// The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
|
||||
// We need to set it up in order for dynamically-linked / position-independent code to
|
||||
// work.
|
||||
\\ ld $gp, 0($ra)
|
||||
\\ dsubu $gp, $ra, $gp
|
||||
\\ ld $25, 8($ra)
|
||||
\\ daddu $25, $25, $gp
|
||||
\\ move $ra, $0
|
||||
\\ move $a0, $sp
|
||||
\\ and $sp, -16
|
||||
\\ j %[posixCallMainAndExit]
|
||||
\\ dsubu $sp, $sp, 16
|
||||
\\ jalr $25
|
||||
,
|
||||
.powerpc, .powerpcle =>
|
||||
// Set up the initial stack frame, and clear the back chain pointer.
|
||||
@ -389,7 +414,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: {
|
||||
@ -407,12 +431,17 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn {
|
||||
break :init @as([*]elf.Phdr, @ptrFromInt(at_phdr))[0..at_phnum];
|
||||
};
|
||||
|
||||
// Apply the initial relocations as early as possible in the startup
|
||||
// process.
|
||||
// Apply the initial relocations as early as possible in the startup process. We cannot
|
||||
// make calls yet on some architectures (e.g. MIPS) *because* they haven't been applied yet,
|
||||
// so this must be fully inlined.
|
||||
if (builtin.position_independent_executable) {
|
||||
std.os.linux.pie.relocate(phdrs);
|
||||
@call(.always_inline, 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
|
||||
|
Loading…
Reference in New Issue
Block a user