authorgravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-09-08 03:14:30+00:00
committergravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-09-08 14:47:21+00:00
log17cb69cebcb05bbc9d9f7cf01c41a97b71f8a499
tree6ccd66f27a3e52a365aa33bb4c2d5abfc2ab9ce2
parent7d6d1d1f607629625413d62c51b0c9f4c81cefe5

fix elf auxv handling

Auxillery vectors are not guaranteed to be in any order, this just happens to work on x86_64.

5 files changed, 18 insertions(+), 13 deletions(-)

std/elf.zig+5
...@@ -859,6 +859,11 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {...@@ -859,6 +859,11 @@ pub const Elf_MIPS_ABIFlags_v0 = extern struct {
859 flags2: Elf32_Word,859 flags2: Elf32_Word,
860};860};
861861
862pub const Auxv = switch (@sizeOf(usize)) {
863 4 => Elf32_auxv_t,
864 8 => Elf64_auxv_t,
865 else => @compileError("expected pointer size of 32 or 64"),
866};
862pub const Ehdr = switch (@sizeOf(usize)) {867pub const Ehdr = switch (@sizeOf(usize)) {
863 4 => Elf32_Ehdr,868 4 => Elf32_Ehdr,
864 8 => Elf64_Ehdr,869 8 => Elf64_Ehdr,
std/os/index.zig+8-3
...@@ -633,16 +633,21 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {...@@ -633,16 +633,21 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
633 };633 };
634}634}
635635
636pub var linux_aux_raw = []usize{0} ** 38;636pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = undefined;
637pub var posix_environ_raw: [][*]u8 = undefined;637pub var posix_environ_raw: [][*]u8 = undefined;
638638
639/// See std.elf for the constants.639/// See std.elf for the constants.
640pub fn linuxGetAuxVal(index: usize) usize {640pub fn linuxGetAuxVal(index: usize) usize {
641 if (builtin.link_libc) {641 if (builtin.link_libc) {
642 return usize(std.c.getauxval(index));642 return usize(std.c.getauxval(index));
643 } else {643 } else if (linux_elf_aux_maybe) |auxv| {
644 return linux_aux_raw[index];644 var i: usize = 0;
645 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
646 if (auxv[i].a_type == index)
647 return auxv[i].a_un.a_val;
648 }
645 }649 }
650 return 0;
646}651}
647652
648pub fn getBaseAddress() usize {653pub fn getBaseAddress() usize {
std/os/linux/arm64.zig+2-4
...@@ -282,10 +282,8 @@ pub const SYS_io_pgetevents = 292;...@@ -282,10 +282,8 @@ pub const SYS_io_pgetevents = 292;
282pub const SYS_syscalls = 293;282pub const SYS_syscalls = 293;
283283
284pub const VDSO_USEFUL = true;284pub const VDSO_USEFUL = true;
285pub const VDSO_CGT_SYM = "__vdso_clock_gettime";285pub const VDSO_CGT_SYM = "__kernel_clock_gettime";
286pub const VDSO_CGT_VER = "LINUX_2.6";286pub const VDSO_CGT_VER = "LINUX_2.6.39";
287pub const VDSO_GETCPU_SYM = "__vdso_getcpu";
288pub const VDSO_GETCPU_VER = "LINUX_2.6";
289287
290pub fn syscall0(number: usize) usize {288pub fn syscall0(number: usize) usize {
291 return asm volatile ("svc #0"289 return asm volatile ("svc #0"
std/os/linux/vdso.zig+1-1
...@@ -5,7 +5,7 @@ const cstr = std.cstr;...@@ -5,7 +5,7 @@ const cstr = std.cstr;
5const mem = std.mem;5const mem = std.mem;
66
7pub fn lookup(vername: []const u8, name: []const u8) usize {7pub fn lookup(vername: []const u8, name: []const u8) usize {
8 const vdso_addr = std.os.linux_aux_raw[std.elf.AT_SYSINFO_EHDR];8 const vdso_addr = std.os.linuxGetAuxVal(std.elf.AT_SYSINFO_EHDR);
9 if (vdso_addr == 0) return 0;9 if (vdso_addr == 0) return 0;
1010
11 const eh = @intToPtr(*elf.Ehdr, vdso_addr);11 const eh = @intToPtr(*elf.Ehdr, vdso_addr);
std/special/bootstrap.zig+2-5
...@@ -59,11 +59,8 @@ fn posixCallMainAndExit() noreturn {...@@ -59,11 +59,8 @@ fn posixCallMainAndExit() noreturn {
59 const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];59 const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
60 if (builtin.os == builtin.Os.linux) {60 if (builtin.os == builtin.Os.linux) {
61 const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);61 const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);
62 var i: usize = 0;62 std.os.linux_elf_aux_maybe = @ptrCast([*]std.elf.Auxv, auxv);
63 while (auxv[i] != 0) : (i += 2) {63 std.debug.assert(std.os.linuxGetAuxVal(std.elf.AT_PAGESZ) == std.os.page_size);
64 if (auxv[i] < std.os.linux_aux_raw.len) std.os.linux_aux_raw[auxv[i]] = auxv[i + 1];
65 }
66 std.debug.assert(std.os.linux_aux_raw[std.elf.AT_PAGESZ] == std.os.page_size);
67 }64 }
6865
69 std.os.posix.exit(callMainWithArgs(argc, argv, envp));66 std.os.posix.exit(callMainWithArgs(argc, argv, envp));