Commit 17cb69cebc

Shawn Landden <shawn@git.icu>
2018-09-08 05:14:30
fix elf auxv handling
Auxillery vectors are not guaranteed to be in any order, this just happens to work on x86_64.
1 parent 7d6d1d1
Changed files (5)
std/os/linux/arm64.zig
@@ -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"
std/os/linux/vdso.zig
@@ -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);
std/os/index.zig
@@ -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 {
std/special/bootstrap.zig
@@ -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));
std/elf.zig
@@ -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,