| ... | @@ -9,8 +9,6 @@ const elf = std.elf; | ... | @@ -9,8 +9,6 @@ const elf = std.elf; |
| 9 | const native_arch = builtin.cpu.arch; | 9 | const native_arch = builtin.cpu.arch; |
| 10 | const native_os = builtin.os.tag; | 10 | const native_os = builtin.os.tag; |
| 11 | | 11 | |
| 12 | var argc_argv_ptr: [*]usize = undefined; | | |
| 13 | | | |
| 14 | const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start"; | 12 | const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start"; |
| 15 | | 13 | |
| 16 | // The self-hosted compiler is not fully capable of handling all of this start.zig file. | 14 | // The self-hosted compiler is not fully capable of handling all of this start.zig file. |
| ... | @@ -277,41 +275,42 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -277,41 +275,42 @@ fn _start() callconv(.Naked) noreturn { |
| 277 | asm volatile (switch (native_arch) { | 275 | asm volatile (switch (native_arch) { |
| 278 | .x86_64 => | 276 | .x86_64 => |
| 279 | \\ xorl %%ebp, %%ebp | 277 | \\ xorl %%ebp, %%ebp |
| 280 | \\ movq %%rsp, %[argc_argv_ptr] | 278 | \\ movq %%rsp, %%rdi |
| 281 | \\ andq $-16, %%rsp | 279 | \\ andq $-16, %%rsp |
| 282 | \\ callq %[posixCallMainAndExit:P] | 280 | \\ callq %[posixCallMainAndExit:P] |
| 283 | , | 281 | , |
| 284 | .x86 => | 282 | .x86 => |
| 285 | \\ xorl %%ebp, %%ebp | 283 | \\ xorl %%ebp, %%ebp |
| 286 | \\ movl %%esp, %[argc_argv_ptr] | 284 | \\ movl %%esp, %%eax |
| 287 | \\ andl $-16, %%esp | 285 | \\ andl $-16, %%esp |
| | 286 | \\ subl $12, %%esp |
| | 287 | \\ pushl %%eax |
| 288 | \\ calll %[posixCallMainAndExit:P] | 288 | \\ calll %[posixCallMainAndExit:P] |
| 289 | , | 289 | , |
| 290 | .aarch64, .aarch64_be => | 290 | .aarch64, .aarch64_be => |
| 291 | \\ mov fp, #0 | 291 | \\ mov fp, #0 |
| 292 | \\ mov lr, #0 | 292 | \\ mov lr, #0 |
| 293 | \\ mov x0, sp | 293 | \\ mov x0, sp |
| 294 | \\ str x0, %[argc_argv_ptr] | | |
| 295 | \\ b %[posixCallMainAndExit] | 294 | \\ b %[posixCallMainAndExit] |
| 296 | , | 295 | , |
| 297 | .arm, .armeb, .thumb, .thumbeb => | 296 | .arm, .armeb, .thumb, .thumbeb => |
| 298 | \\ mov fp, #0 | 297 | \\ mov fp, #0 |
| 299 | \\ mov lr, #0 | 298 | \\ mov lr, #0 |
| 300 | \\ str sp, %[argc_argv_ptr] | 299 | \\ mov a1, sp |
| 301 | \\ and sp, #-16 | 300 | \\ and sp, #-16 |
| 302 | \\ b %[posixCallMainAndExit] | 301 | \\ b %[posixCallMainAndExit] |
| 303 | , | 302 | , |
| 304 | .riscv64 => | 303 | .riscv64 => |
| 305 | \\ li s0, 0 | 304 | \\ li s0, 0 |
| 306 | \\ li ra, 0 | 305 | \\ li ra, 0 |
| 307 | \\ sd sp, %[argc_argv_ptr] | 306 | \\ mv a0, sp |
| 308 | \\ andi sp, sp, -16 | 307 | \\ andi sp, sp, -16 |
| 309 | \\ tail %[posixCallMainAndExit]@plt | 308 | \\ tail %[posixCallMainAndExit]@plt |
| 310 | , | 309 | , |
| 311 | .mips, .mipsel => | 310 | .mips, .mipsel => |
| 312 | // The lr is already zeroed on entry, as specified by the ABI. | 311 | // The lr is already zeroed on entry, as specified by the ABI. |
| 313 | \\ addiu $fp, $zero, 0 | 312 | \\ addiu $fp, $zero, 0 |
| 314 | \\ sw $sp, %[argc_argv_ptr] | 313 | \\ move $a0, $sp |
| 315 | \\ .set push | 314 | \\ .set push |
| 316 | \\ .set noat | 315 | \\ .set noat |
| 317 | \\ addiu $1, $zero, -16 | 316 | \\ addiu $1, $zero, -16 |
| ... | @@ -322,7 +321,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -322,7 +321,7 @@ fn _start() callconv(.Naked) noreturn { |
| 322 | .mips64, .mips64el => | 321 | .mips64, .mips64el => |
| 323 | // The lr is already zeroed on entry, as specified by the ABI. | 322 | // The lr is already zeroed on entry, as specified by the ABI. |
| 324 | \\ addiu $fp, $zero, 0 | 323 | \\ addiu $fp, $zero, 0 |
| 325 | \\ sd $sp, %[argc_argv_ptr] | 324 | \\ move $a0, $sp |
| 326 | \\ .set push | 325 | \\ .set push |
| 327 | \\ .set noat | 326 | \\ .set noat |
| 328 | \\ daddiu $1, $zero, -16 | 327 | \\ daddiu $1, $zero, -16 |
| ... | @@ -332,7 +331,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -332,7 +331,7 @@ fn _start() callconv(.Naked) noreturn { |
| 332 | , | 331 | , |
| 333 | .powerpc, .powerpcle => | 332 | .powerpc, .powerpcle => |
| 334 | // Setup the initial stack frame and clear the back chain pointer. | 333 | // Setup the initial stack frame and clear the back chain pointer. |
| 335 | \\ stw 1, %[argc_argv_ptr] | 334 | \\ mr 3, 1 |
| 336 | \\ li 0, 0 | 335 | \\ li 0, 0 |
| 337 | \\ stwu 1, -16(1) | 336 | \\ stwu 1, -16(1) |
| 338 | \\ stw 0, 0(1) | 337 | \\ stw 0, 0(1) |
| ... | @@ -342,7 +341,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -342,7 +341,7 @@ fn _start() callconv(.Naked) noreturn { |
| 342 | .powerpc64, .powerpc64le => | 341 | .powerpc64, .powerpc64le => |
| 343 | // Setup the initial stack frame and clear the back chain pointer. | 342 | // Setup the initial stack frame and clear the back chain pointer. |
| 344 | // TODO: Support powerpc64 (big endian) on ELFv2. | 343 | // TODO: Support powerpc64 (big endian) on ELFv2. |
| 345 | \\ std 1, %[argc_argv_ptr] | 344 | \\ mr 3, 1 |
| 346 | \\ li 0, 0 | 345 | \\ li 0, 0 |
| 347 | \\ stdu 0, -32(1) | 346 | \\ stdu 0, -32(1) |
| 348 | \\ mtlr 0 | 347 | \\ mtlr 0 |
| ... | @@ -352,12 +351,12 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -352,12 +351,12 @@ fn _start() callconv(.Naked) noreturn { |
| 352 | // argc is stored after a register window (16 registers) plus stack bias | 351 | // argc is stored after a register window (16 registers) plus stack bias |
| 353 | \\ mov %%g0, %%i6 | 352 | \\ mov %%g0, %%i6 |
| 354 | \\ add %%o6, 2175, %%l0 | 353 | \\ add %%o6, 2175, %%l0 |
| 355 | \\ ba %[posixCallMainAndExit] | 354 | \\ mov %%l0, %%o0 |
| 356 | \\ stx %%l0, %[argc_argv_ptr] | 355 | \\ ba,a %[posixCallMainAndExit] |
| 357 | , | 356 | , |
| 358 | else => @compileError("unsupported arch"), | 357 | else => @compileError("unsupported arch"), |
| 359 | } | 358 | } |
| 360 | : [argc_argv_ptr] "=m" (argc_argv_ptr), | 359 | : |
| 361 | : [posixCallMainAndExit] "X" (&posixCallMainAndExit), | 360 | : [posixCallMainAndExit] "X" (&posixCallMainAndExit), |
| 362 | ); | 361 | ); |
| 363 | } | 362 | } |
| ... | @@ -385,7 +384,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -385,7 +384,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 385 | std.os.windows.ntdll.RtlExitUserProcess(@as(std.os.windows.UINT, @bitCast(result))); | 384 | std.os.windows.ntdll.RtlExitUserProcess(@as(std.os.windows.UINT, @bitCast(result))); |
| 386 | } | 385 | } |
| 387 | | 386 | |
| 388 | fn posixCallMainAndExit() callconv(.C) noreturn { | 387 | fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { |
| 389 | const argc = argc_argv_ptr[0]; | 388 | const argc = argc_argv_ptr[0]; |
| 390 | const argv = @as([*][*:0]u8, @ptrCast(argc_argv_ptr + 1)); | 389 | const argv = @as([*][*:0]u8, @ptrCast(argc_argv_ptr + 1)); |
| 391 | | 390 | |