| ... | ... | @@ -302,8 +302,8 @@ fn posixCallMainAndExit() noreturn { |
| 302 | 302 | // no, seriously, give me that stack space, I wasn't joking. |
| 303 | 303 | { |
| 304 | 304 | var i: usize = 0; |
| 305 | | var at_phnum: usize = undefined; |
| 306 | 305 | var at_phdr: usize = undefined; |
| 306 | var at_phnum: usize = undefined; |
| 307 | 307 | while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) { |
| 308 | 308 | switch (auxv[i].a_type) { |
| 309 | 309 | std.elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val, |
| ... | ... | @@ -311,38 +311,42 @@ fn posixCallMainAndExit() noreturn { |
| 311 | 311 | else => continue, |
| 312 | 312 | } |
| 313 | 313 | } |
| 314 | | const phdrs = (@intToPtr([*]std.elf.Phdr, at_phdr))[0..at_phnum]; |
| 315 | | for (phdrs) |*phdr| { |
| 316 | | switch (phdr.p_type) { |
| 317 | | std.elf.PT_GNU_STACK => { |
| 318 | | const wanted_stack_size = phdr.p_memsz; |
| 319 | | assert(wanted_stack_size % std.mem.page_size == 0); |
| 320 | | |
| 321 | | std.os.setrlimit(.STACK, .{ |
| 322 | | .cur = wanted_stack_size, |
| 323 | | .max = wanted_stack_size, |
| 324 | | }) catch { |
| 325 | | // If this is a debug build, it will be useful to find out |
| 326 | | // why this failed. If it is a release build, we allow the |
| 327 | | // stack overflow to cause a segmentation fault. Memory safety |
| 328 | | // is not compromised, however, depending on runtime state, |
| 329 | | // the application may crash due to provided stack space not |
| 330 | | // matching the known upper bound. |
| 331 | | if (builtin.mode == .Debug) { |
| 332 | | @panic("unable to increase stack size"); |
| 333 | | } |
| 334 | | }; |
| 335 | | break; |
| 336 | | }, |
| 337 | | else => {}, |
| 338 | | } |
| 339 | | } |
| 314 | expandStackSize(at_phdr, at_phnum); |
| 340 | 315 | } |
| 341 | 316 | } |
| 342 | 317 | |
| 343 | 318 | std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp })); |
| 344 | 319 | } |
| 345 | 320 | |
| 321 | fn expandStackSize(at_phdr: usize, at_phnum: usize) void { |
| 322 | const phdrs = (@intToPtr([*]std.elf.Phdr, at_phdr))[0..at_phnum]; |
| 323 | for (phdrs) |*phdr| { |
| 324 | switch (phdr.p_type) { |
| 325 | std.elf.PT_GNU_STACK => { |
| 326 | const wanted_stack_size = phdr.p_memsz; |
| 327 | assert(wanted_stack_size % std.mem.page_size == 0); |
| 328 | |
| 329 | std.os.setrlimit(.STACK, .{ |
| 330 | .cur = wanted_stack_size, |
| 331 | .max = wanted_stack_size, |
| 332 | }) catch { |
| 333 | // If this is a debug build, it will be useful to find out |
| 334 | // why this failed. If it is a release build, we allow the |
| 335 | // stack overflow to cause a segmentation fault. Memory safety |
| 336 | // is not compromised, however, depending on runtime state, |
| 337 | // the application may crash due to provided stack space not |
| 338 | // matching the known upper bound. |
| 339 | if (builtin.mode == .Debug) { |
| 340 | @panic("unable to increase stack size"); |
| 341 | } |
| 342 | }; |
| 343 | break; |
| 344 | }, |
| 345 | else => {}, |
| 346 | } |
| 347 | } |
| 348 | } |
| 349 | |
| 346 | 350 | fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { |
| 347 | 351 | std.os.argv = argv[0..argc]; |
| 348 | 352 | std.os.environ = envp; |
| ... | ... | @@ -356,6 +360,13 @@ fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) |
| 356 | 360 | var env_count: usize = 0; |
| 357 | 361 | while (c_envp[env_count] != null) : (env_count += 1) {} |
| 358 | 362 | const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; |
| 363 | |
| 364 | if (builtin.os.tag == .linux) { |
| 365 | const at_phdr = std.c.getauxval(std.elf.AT_PHDR); |
| 366 | const at_phnum = std.c.getauxval(std.elf.AT_PHNUM); |
| 367 | expandStackSize(at_phdr, at_phnum); |
| 368 | } |
| 369 | |
| 359 | 370 | return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), c_argv, envp }); |
| 360 | 371 | } |
| 361 | 372 | |