Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start: A handful of MIPS fixes #20822

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions lib/std/start.zig
Original file line number Diff line number Diff line change
Expand Up @@ -330,17 +330,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
alexrp marked this conversation as resolved.
Show resolved Hide resolved
\\ 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
alexrp marked this conversation as resolved.
Show resolved Hide resolved
\\ 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.
Expand Down Expand Up @@ -430,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: {
Expand All @@ -448,12 +472,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});
alexrp marked this conversation as resolved.
Show resolved Hide resolved
}

// 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
Expand Down