mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Merge pull request #20777 from alexrp/start-abi-hardening
`start`: Harden against program interpreters that don't adhere fully to the ABI
This commit is contained in:
commit
ed847b85c2
@ -272,6 +272,12 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
: [tos] "={rax}" (-> *std.os.plan9.Tos),
|
: [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) {
|
asm volatile (switch (native_arch) {
|
||||||
.x86_64 =>
|
.x86_64 =>
|
||||||
\\ xorl %%ebp, %%ebp
|
\\ xorl %%ebp, %%ebp
|
||||||
@ -291,6 +297,7 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
\\ mov fp, #0
|
\\ mov fp, #0
|
||||||
\\ mov lr, #0
|
\\ mov lr, #0
|
||||||
\\ mov x0, sp
|
\\ mov x0, sp
|
||||||
|
\\ and sp, x0, #-16
|
||||||
\\ b %[posixCallMainAndExit]
|
\\ b %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.arm, .armeb, .thumb, .thumbeb =>
|
.arm, .armeb, .thumb, .thumbeb =>
|
||||||
@ -322,30 +329,23 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
\\ jsr (%%pc, %%a0)
|
\\ jsr (%%pc, %%a0)
|
||||||
,
|
,
|
||||||
.mips, .mipsel =>
|
.mips, .mipsel =>
|
||||||
// The lr is already zeroed on entry, as specified by the ABI.
|
\\ move $fp, $0
|
||||||
\\ addiu $fp, $zero, 0
|
\\ move $ra, $0
|
||||||
\\ move $a0, $sp
|
\\ move $a0, $sp
|
||||||
\\ .set push
|
\\ and $sp, -8
|
||||||
\\ .set noat
|
|
||||||
\\ addiu $1, $zero, -16
|
|
||||||
\\ and $sp, $sp, $1
|
|
||||||
\\ .set pop
|
|
||||||
\\ j %[posixCallMainAndExit]
|
\\ j %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.mips64, .mips64el =>
|
.mips64, .mips64el =>
|
||||||
// The lr is already zeroed on entry, as specified by the ABI.
|
\\ move $fp, $0
|
||||||
\\ addiu $fp, $zero, 0
|
\\ move $ra, $0
|
||||||
\\ move $a0, $sp
|
\\ move $a0, $sp
|
||||||
\\ .set push
|
\\ and $sp, -16
|
||||||
\\ .set noat
|
|
||||||
\\ daddiu $1, $zero, -16
|
|
||||||
\\ and $sp, $sp, $1
|
|
||||||
\\ .set pop
|
|
||||||
\\ j %[posixCallMainAndExit]
|
\\ j %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.powerpc, .powerpcle =>
|
.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
|
\\ mr 3, 1
|
||||||
|
\\ clrrwi 1, 1, 4
|
||||||
\\ li 0, 0
|
\\ li 0, 0
|
||||||
\\ stwu 1, -16(1)
|
\\ stwu 1, -16(1)
|
||||||
\\ stw 0, 0(1)
|
\\ stw 0, 0(1)
|
||||||
@ -353,7 +353,7 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
\\ b %[posixCallMainAndExit]
|
\\ b %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.powerpc64, .powerpc64le =>
|
.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
|
\\ addis 2, 12, .TOC. - %[_start]@ha
|
||||||
\\ addi 2, 2, .TOC. - %[_start]@l
|
\\ addi 2, 2, .TOC. - %[_start]@l
|
||||||
\\ mr 3, 1
|
\\ mr 3, 1
|
||||||
@ -365,18 +365,22 @@ fn _start() callconv(.Naked) noreturn {
|
|||||||
,
|
,
|
||||||
.s390x =>
|
.s390x =>
|
||||||
// Set up the stack frame (register save area and cleared back-chain slot).
|
// 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
|
||||||
\\ lgr %r2, %r15
|
\\ lghi %%r0, -16
|
||||||
\\ aghi %r15, -160
|
\\ ngr %%r15, %%r0
|
||||||
\\ lghi %r0, 0
|
\\ aghi %%r15, -160
|
||||||
\\ stg %r0, 0(%r15)
|
\\ lghi %%r0, 0
|
||||||
|
\\ stg %%r0, 0(%%r15)
|
||||||
\\ jg %[posixCallMainAndExit]
|
\\ jg %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
.sparc64 =>
|
.sparc64 =>
|
||||||
// argc is stored after a register window (16 registers) plus stack bias
|
// argc is stored after a register window (16 registers * 8 bytes) plus the stack bias
|
||||||
\\ mov %%g0, %%i6
|
// (2047 bytes).
|
||||||
\\ add %%o6, 2175, %%l0
|
\\ mov %%g0, %%fp
|
||||||
\\ mov %%l0, %%o0
|
\\ add %%sp, 2175, %%o0
|
||||||
|
\\ add %%sp, 2047, %%sp
|
||||||
|
\\ and %%sp, -16, %%sp
|
||||||
|
\\ sub %%sp, 2047, %%sp
|
||||||
\\ ba,a %[posixCallMainAndExit]
|
\\ ba,a %[posixCallMainAndExit]
|
||||||
,
|
,
|
||||||
else => @compileError("unsupported arch"),
|
else => @compileError("unsupported arch"),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user