| ... | ... | @@ -272,6 +272,12 @@ fn _start() callconv(.Naked) noreturn { |
| 272 | 272 | : [tos] "={rax}" (-> *std.os.plan9.Tos), |
| 273 | 273 | ); |
| 274 | 274 | } |
| 275 | |
| 276 | // Note that we maintain a very low level of trust with regards to ABI guarantees at this point. |
| 277 | // We will redundantly align the stack, clear the link register, etc. While e.g. the Linux |
| 278 | // kernel is usually good about upholding the ABI guarantees, the same cannot be said of dynamic |
| 279 | // linkers; musl's ldso, for example, opts to not align the stack when invoking the dynamic |
| 280 | // linker explicitly. |
| 275 | 281 | asm volatile (switch (native_arch) { |
| 276 | 282 | .x86_64 => |
| 277 | 283 | \\ xorl %%ebp, %%ebp |
| ... | ... | @@ -291,6 +297,7 @@ fn _start() callconv(.Naked) noreturn { |
| 291 | 297 | \\ mov fp, #0 |
| 292 | 298 | \\ mov lr, #0 |
| 293 | 299 | \\ mov x0, sp |
| 300 | \\ and sp, x0, #-16 |
| 294 | 301 | \\ b %[posixCallMainAndExit] |
| 295 | 302 | , |
| 296 | 303 | .arm, .armeb, .thumb, .thumbeb => |
| ... | ... | @@ -322,30 +329,23 @@ fn _start() callconv(.Naked) noreturn { |
| 322 | 329 | \\ jsr (%%pc, %%a0) |
| 323 | 330 | , |
| 324 | 331 | .mips, .mipsel => |
| 325 | | // The lr is already zeroed on entry, as specified by the ABI. |
| 326 | | \\ addiu $fp, $zero, 0 |
| 332 | \\ move $fp, $0 |
| 333 | \\ move $ra, $0 |
| 327 | 334 | \\ move $a0, $sp |
| 328 | | \\ .set push |
| 329 | | \\ .set noat |
| 330 | | \\ addiu $1, $zero, -16 |
| 331 | | \\ and $sp, $sp, $1 |
| 332 | | \\ .set pop |
| 335 | \\ and $sp, -8 |
| 333 | 336 | \\ j %[posixCallMainAndExit] |
| 334 | 337 | , |
| 335 | 338 | .mips64, .mips64el => |
| 336 | | // The lr is already zeroed on entry, as specified by the ABI. |
| 337 | | \\ addiu $fp, $zero, 0 |
| 339 | \\ move $fp, $0 |
| 340 | \\ move $ra, $0 |
| 338 | 341 | \\ move $a0, $sp |
| 339 | | \\ .set push |
| 340 | | \\ .set noat |
| 341 | | \\ daddiu $1, $zero, -16 |
| 342 | | \\ and $sp, $sp, $1 |
| 343 | | \\ .set pop |
| 342 | \\ and $sp, -16 |
| 344 | 343 | \\ j %[posixCallMainAndExit] |
| 345 | 344 | , |
| 346 | 345 | .powerpc, .powerpcle => |
| 347 | | // Setup the initial stack frame and clear the back chain pointer. |
| 346 | // Set up the initial stack frame, and clear the back chain pointer. |
| 348 | 347 | \\ mr 3, 1 |
| 348 | \\ clrrwi 1, 1, 4 |
| 349 | 349 | \\ li 0, 0 |
| 350 | 350 | \\ stwu 1, -16(1) |
| 351 | 351 | \\ stw 0, 0(1) |
| ... | ... | @@ -353,7 +353,7 @@ fn _start() callconv(.Naked) noreturn { |
| 353 | 353 | \\ b %[posixCallMainAndExit] |
| 354 | 354 | , |
| 355 | 355 | .powerpc64, .powerpc64le => |
| 356 | | // Setup the initial stack frame and clear the back chain pointer. |
| 356 | // Set up the ToC and initial stack frame, and clear the back chain pointer. |
| 357 | 357 | \\ addis 2, 12, .TOC. - %[_start]@ha |
| 358 | 358 | \\ addi 2, 2, .TOC. - %[_start]@l |
| 359 | 359 | \\ mr 3, 1 |
| ... | ... | @@ -365,18 +365,22 @@ fn _start() callconv(.Naked) noreturn { |
| 365 | 365 | , |
| 366 | 366 | .s390x => |
| 367 | 367 | // Set up the stack frame (register save area and cleared back-chain slot). |
| 368 | | // Note: Stack pointer is guaranteed by ABI to be 8-byte aligned as required. |
| 369 | | \\ lgr %r2, %r15 |
| 370 | | \\ aghi %r15, -160 |
| 371 | | \\ lghi %r0, 0 |
| 372 | | \\ stg %r0, 0(%r15) |
| 368 | \\ lgr %%r2, %%r15 |
| 369 | \\ lghi %%r0, -16 |
| 370 | \\ ngr %%r15, %%r0 |
| 371 | \\ aghi %%r15, -160 |
| 372 | \\ lghi %%r0, 0 |
| 373 | \\ stg %%r0, 0(%%r15) |
| 373 | 374 | \\ jg %[posixCallMainAndExit] |
| 374 | 375 | , |
| 375 | 376 | .sparc64 => |
| 376 | | // argc is stored after a register window (16 registers) plus stack bias |
| 377 | | \\ mov %%g0, %%i6 |
| 378 | | \\ add %%o6, 2175, %%l0 |
| 379 | | \\ mov %%l0, %%o0 |
| 377 | // argc is stored after a register window (16 registers * 8 bytes) plus the stack bias |
| 378 | // (2047 bytes). |
| 379 | \\ mov %%g0, %%fp |
| 380 | \\ add %%sp, 2175, %%o0 |
| 381 | \\ add %%sp, 2047, %%sp |
| 382 | \\ and %%sp, -16, %%sp |
| 383 | \\ sub %%sp, 2047, %%sp |
| 380 | 384 | \\ ba,a %[posixCallMainAndExit] |
| 381 | 385 | , |
| 382 | 386 | else => @compileError("unsupported arch"), |