Skip to content
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
54 changes: 29 additions & 25 deletions lib/std/start.zig
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ fn _start() callconv(.Naked) noreturn {
: [tos] "={rax}" (-> *std.os.plan9.Tos),
);
}

// Note that we maintain a very low level of trust with regards to ABI guarantees at this point.
// We will redundantly align the stack, clear the link register, etc. While e.g. the Linux
// kernel is usually good about upholding the ABI guarantees, the same cannot be said of dynamic
// linkers; musl's ldso, for example, opts to not align the stack when invoking the dynamic
// linker explicitly.
asm volatile (switch (native_arch) {
.x86_64 =>
\\ xorl %%ebp, %%ebp
Expand All @@ -291,6 +297,7 @@ fn _start() callconv(.Naked) noreturn {
\\ mov fp, #0
\\ mov lr, #0
\\ mov x0, sp
\\ and sp, x0, #-16
\\ b %[posixCallMainAndExit]
,
.arm, .armeb, .thumb, .thumbeb =>
Expand Down Expand Up @@ -322,38 +329,31 @@ fn _start() callconv(.Naked) noreturn {
\\ jsr (%%pc, %%a0)
,
.mips, .mipsel =>
// The lr is already zeroed on entry, as specified by the ABI.
\\ addiu $fp, $zero, 0
\\ move $fp, $0
\\ move $ra, $0
\\ move $a0, $sp
\\ .set push
\\ .set noat
\\ addiu $1, $zero, -16
\\ and $sp, $sp, $1
\\ .set pop
\\ and $sp, -8
\\ j %[posixCallMainAndExit]
,
.mips64, .mips64el =>
// The lr is already zeroed on entry, as specified by the ABI.
\\ addiu $fp, $zero, 0
\\ move $fp, $0
\\ move $ra, $0
\\ move $a0, $sp
\\ .set push
\\ .set noat
\\ daddiu $1, $zero, -16
\\ and $sp, $sp, $1
\\ .set pop
\\ and $sp, -16
\\ j %[posixCallMainAndExit]
,
.powerpc, .powerpcle =>
// Setup the initial stack frame and clear the back chain pointer.
// Set up the initial stack frame, and clear the back chain pointer.
\\ mr 3, 1
\\ clrrwi 1, 1, 4
\\ li 0, 0
\\ stwu 1, -16(1)
\\ stw 0, 0(1)
\\ mtlr 0
\\ b %[posixCallMainAndExit]
,
.powerpc64, .powerpc64le =>
// Setup the initial stack frame and clear the back chain pointer.
// Set up the ToC and initial stack frame, and clear the back chain pointer.
\\ addis 2, 12, .TOC. - %[_start]@ha
\\ addi 2, 2, .TOC. - %[_start]@l
\\ mr 3, 1
Expand All @@ -365,18 +365,22 @@ fn _start() callconv(.Naked) noreturn {
,
.s390x =>
// Set up the stack frame (register save area and cleared back-chain slot).
// Note: Stack pointer is guaranteed by ABI to be 8-byte aligned as required.
\\ lgr %r2, %r15
\\ aghi %r15, -160
\\ lghi %r0, 0
\\ stg %r0, 0(%r15)
\\ lgr %%r2, %%r15
\\ lghi %%r0, -16
\\ ngr %%r15, %%r0
\\ aghi %%r15, -160
\\ lghi %%r0, 0
\\ stg %%r0, 0(%%r15)
\\ jg %[posixCallMainAndExit]
,
.sparc64 =>
// argc is stored after a register window (16 registers) plus stack bias
\\ mov %%g0, %%i6
\\ add %%o6, 2175, %%l0
\\ mov %%l0, %%o0
// argc is stored after a register window (16 registers * 8 bytes) plus the stack bias
// (2047 bytes).
\\ mov %%g0, %%fp
\\ add %%sp, 2175, %%o0
\\ add %%sp, 2047, %%sp
\\ and %%sp, -16, %%sp
\\ sub %%sp, 2047, %%sp
\\ ba,a %[posixCallMainAndExit]
,
else => @compileError("unsupported arch"),
Expand Down