This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.
fnposixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn {
// We're not ready to panic until thread local storage is initialized.@setRuntimeSafety(false);
// Code coverage instrumentation might try to use thread local variables.@disableInstrumentation();
constargc = argc_argv_ptr[0];
constargv: [*][*:0]u8 = @ptrCast(argc_argv_ptr + 1);
constenvp_optional: [*:null]?[*:0]u8 = @ptrCast(@alignCast(argv + argc + 1));
varenvp_count: usize = 0;
while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
constenvp = envp_optional[0..envp_count :null];
// Find the beginning of the auxiliary vectorconstauxv: [*]elf.Auxv = @ptrCast(@alignCast(envp.ptr + envp_count + 1));
varat_hwcap: usize = 0;
constphdrs = init: {
vari: usize = 0;
varat_phdr: usize = 0;
varat_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.link_mode == .staticandbuiltin.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;
if (!builtin.single_threaded) {
// ARMv6 targets (and earlier) have no support for TLS in hardware.
// FIXME: Elide the check for targets >= ARMv7 when the target feature API
// becomes less verbose (and more usable).
if (comptimenative_arch.isArm()) {
if (at_hwcap & std.os.linux.HWCAP.TLS == 0) {
// FIXME: Make __aeabi_read_tp call the kernel helper kuser_get_tls
// For the time being use a simple trap instead of a @panic call to
// keep the binary bloat under control.
@trap();
}
}
// Initialize the TLS area.std.os.linux.tls.initStatic(phdrs);
}
// The way Linux executables represent stack size is via the PT_GNU_STACK
// program header. However the kernel does not recognize it; it always gives 8 MiB.
// Here we look for the stack size in our program headers and use setrlimit
// to ask for more stack space.
expandStackSize(phdrs);
}
constopt_init_array_start = @extern([*]const *constfn () callconv(.c) void, .{
.name = "__init_array_start",
.linkage = .weak,
});
constopt_init_array_end = @extern([*]const *constfn () callconv(.c) void, .{
.name = "__init_array_end",
.linkage = .weak,
});
if (opt_init_array_start) |init_array_start| {
constinit_array_end = opt_init_array_end.?;
constslice = init_array_start[0 .. init_array_end - init_array_start];
for (slice) |func| func();
}
std.process.exit(callMainWithArgs(argc, argv, envp));
}