Skip to content

start: Don't artificially limit some posixCallMainAndExit() logic to Linux #23916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 18, 2025
Merged
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion lib/std/os/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ pub const user_desc = arch_bits.user_desc;
pub const getcontext = arch_bits.getcontext;

pub const tls = @import("linux/tls.zig");
pub const pie = @import("linux/pie.zig");
pub const BPF = @import("linux/bpf.zig");
pub const IOCTL = @import("linux/ioctl.zig");
pub const SECCOMP = @import("linux/seccomp.zig");
Expand Down
File renamed without changes.
76 changes: 38 additions & 38 deletions lib/std/start.zig
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ fn _start() callconv(.naked) noreturn {
,
.csky =>
// The CSKY ABI assumes that `gb` is set to the address of the GOT in order for
// position-independent code to work. We depend on this in `std.os.linux.pie` to locate
// position-independent code to work. We depend on this in `std.pie` to locate
// `_DYNAMIC` as well.
// r8 = FP
\\ grs t0, 1f
Expand Down Expand Up @@ -514,33 +514,33 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn {
while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
const envp = @as([*][*:0]u8, @ptrCast(envp_optional))[0..envp_count];

if (native_os == .linux) {
// Find the beginning of the auxiliary vector
const auxv: [*]elf.Auxv = @ptrCast(@alignCast(envp.ptr + envp_count + 1));

var at_hwcap: usize = 0;
const phdrs = init: {
var i: usize = 0;
var at_phdr: usize = 0;
var at_phnum: usize = 0;
while (auxv[i].a_type != elf.AT_NULL) : (i += 1) {
switch (auxv[i].a_type) {
elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
elf.AT_HWCAP => at_hwcap = auxv[i].a_un.a_val,
else => continue,
}
// Find the beginning of the auxiliary vector
const auxv: [*]elf.Auxv = @ptrCast(@alignCast(envp.ptr + envp_count + 1));

var at_hwcap: usize = 0;
const phdrs = init: {
var i: usize = 0;
var at_phdr: usize = 0;
var at_phnum: usize = 0;
while (auxv[i].a_type != elf.AT_NULL) : (i += 1) {
switch (auxv[i].a_type) {
elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
elf.AT_HWCAP => at_hwcap = auxv[i].a_un.a_val,
else => continue,
}
break :init @as([*]elf.Phdr, @ptrFromInt(at_phdr))[0..at_phnum];
};

// Apply the initial relocations as early as possible in the startup process. We cannot
// make calls yet on some architectures (e.g. MIPS) *because* they haven't been applied yet,
// so this must be fully inlined.
if (builtin.position_independent_executable) {
@call(.always_inline, std.os.linux.pie.relocate, .{phdrs});
}
break :init @as([*]elf.Phdr, @ptrFromInt(at_phdr))[0..at_phnum];
};

// Apply the initial relocations as early as possible in the startup process. We cannot
// make calls yet on some architectures (e.g. MIPS) *because* they haven't been applied yet,
// so this must be fully inlined.
if (builtin.position_independent_executable) {
@call(.always_inline, std.pie.relocate, .{phdrs});
}

if (native_os == .linux) {
// This must be done after PIE relocations have been applied or we may crash
// while trying to access the global variable (happens on MIPS at least).
std.os.linux.elf_aux_maybe = auxv;
Expand All @@ -567,20 +567,20 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn {
// Here we look for the stack size in our program headers and use setrlimit
// to ask for more stack space.
expandStackSize(phdrs);
}

const opt_init_array_start = @extern([*]*const fn () callconv(.c) void, .{
.name = "__init_array_start",
.linkage = .weak,
});
const opt_init_array_end = @extern([*]*const fn () callconv(.c) void, .{
.name = "__init_array_end",
.linkage = .weak,
});
if (opt_init_array_start) |init_array_start| {
const init_array_end = opt_init_array_end.?;
const slice = init_array_start[0 .. init_array_end - init_array_start];
for (slice) |func| func();
}
const opt_init_array_start = @extern([*]*const fn () callconv(.c) void, .{
.name = "__init_array_start",
.linkage = .weak,
});
const opt_init_array_end = @extern([*]*const fn () callconv(.c) void, .{
.name = "__init_array_end",
.linkage = .weak,
});
if (opt_init_array_start) |init_array_start| {
const init_array_end = opt_init_array_end.?;
const slice = init_array_start[0 .. init_array_end - init_array_start];
for (slice) |func| func();
}

std.posix.exit(callMainWithArgs(argc, argv, envp));
Expand Down
1 change: 1 addition & 0 deletions lib/std/std.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub const net = @import("net.zig");
pub const os = @import("os.zig");
pub const once = @import("once.zig").once;
pub const pdb = @import("pdb.zig");
pub const pie = @import("pie.zig");
pub const posix = @import("posix.zig");
pub const process = @import("process.zig");
pub const sort = @import("sort.zig");
Expand Down
Loading