fix elf auxv handling

Auxillery vectors are not guaranteed to be in any order, this
just happens to work on x86_64.
master
Shawn Landden 2018-09-08 03:14:30 +00:00
parent 7d6d1d1f60
commit 17cb69cebc
5 changed files with 18 additions and 13 deletions

View File

@ -859,6 +859,11 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
flags2: Elf32_Word,
};
pub const Auxv = switch (@sizeOf(usize)) {
4 => Elf32_auxv_t,
8 => Elf64_auxv_t,
else => @compileError("expected pointer size of 32 or 64"),
};
pub const Ehdr = switch (@sizeOf(usize)) {
4 => Elf32_Ehdr,
8 => Elf64_Ehdr,

View File

@ -633,16 +633,21 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
};
}
pub var linux_aux_raw = []usize{0} ** 38;
pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = undefined;
pub var posix_environ_raw: [][*]u8 = undefined;
/// See std.elf for the constants.
pub fn linuxGetAuxVal(index: usize) usize {
if (builtin.link_libc) {
return usize(std.c.getauxval(index));
} else {
return linux_aux_raw[index];
} else if (linux_elf_aux_maybe) |auxv| {
var i: usize = 0;
while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
if (auxv[i].a_type == index)
return auxv[i].a_un.a_val;
}
}
return 0;
}
pub fn getBaseAddress() usize {

View File

@ -282,10 +282,8 @@ pub const SYS_io_pgetevents = 292;
pub const SYS_syscalls = 293;
pub const VDSO_USEFUL = true;
pub const VDSO_CGT_SYM = "__vdso_clock_gettime";
pub const VDSO_CGT_VER = "LINUX_2.6";
pub const VDSO_GETCPU_SYM = "__vdso_getcpu";
pub const VDSO_GETCPU_VER = "LINUX_2.6";
pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
pub const VDSO_CGT_VER = "LINUX_2.6.39";
pub fn syscall0(number: usize) usize {
return asm volatile ("svc #0"

View File

@ -5,7 +5,7 @@ const cstr = std.cstr;
const mem = std.mem;
pub fn lookup(vername: []const u8, name: []const u8) usize {
const vdso_addr = std.os.linux_aux_raw[std.elf.AT_SYSINFO_EHDR];
const vdso_addr = std.os.linuxGetAuxVal(std.elf.AT_SYSINFO_EHDR);
if (vdso_addr == 0) return 0;
const eh = @intToPtr(*elf.Ehdr, vdso_addr);

View File

@ -59,11 +59,8 @@ fn posixCallMainAndExit() noreturn {
const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
if (builtin.os == builtin.Os.linux) {
const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);
var i: usize = 0;
while (auxv[i] != 0) : (i += 2) {
if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];
}
std.debug.assert(std.os.linux_aux_raw[std.elf.AT_PAGESZ] == std.os.page_size);
std.os.linux_elf_aux_maybe = @ptrCast([*]std.elf.Auxv, auxv);
std.debug.assert(std.os.linuxGetAuxVal(std.elf.AT_PAGESZ) == std.os.page_size);
}
std.os.posix.exit(callMainWithArgs(argc, argv, envp));