| author | |
| committer | |
| log | 2323da3a680f48207d35db26f63ea0553e74d956 |
| tree | 4670d28b0cae89d11d18e66a68a2fc30a1ed85db |
| parent | e4c262b804dded7e47aea0bb61f4578b94a7fa86 |
4 files changed, 46 insertions(+), 0 deletions(-)
std/os/bits/linux/arm-eabi.zig+24| ... | @@ -474,6 +474,30 @@ pub const VDSO_USEFUL = true; | ... | @@ -474,6 +474,30 @@ pub const VDSO_USEFUL = true; |
| 474 | pub const VDSO_CGT_SYM = "__vdso_clock_gettime"; | 474 | pub const VDSO_CGT_SYM = "__vdso_clock_gettime"; |
| 475 | pub const VDSO_CGT_VER = "LINUX_2.6"; | 475 | pub const VDSO_CGT_VER = "LINUX_2.6"; |
| 476 | 476 | ||
| 477 | pub const HWCAP_SWP = 1 << 0; | ||
| 478 | pub const HWCAP_HALF = 1 << 1; | ||
| 479 | pub const HWCAP_THUMB = 1 << 2; | ||
| 480 | pub const HWCAP_26BIT = 1 << 3; | ||
| 481 | pub const HWCAP_FAST_MULT = 1 << 4; | ||
| 482 | pub const HWCAP_FPA = 1 << 5; | ||
| 483 | pub const HWCAP_VFP = 1 << 6; | ||
| 484 | pub const HWCAP_EDSP = 1 << 7; | ||
| 485 | pub const HWCAP_JAVA = 1 << 8; | ||
| 486 | pub const HWCAP_IWMMXT = 1 << 9; | ||
| 487 | pub const HWCAP_CRUNCH = 1 << 10; | ||
| 488 | pub const HWCAP_THUMBEE = 1 << 11; | ||
| 489 | pub const HWCAP_NEON = 1 << 12; | ||
| 490 | pub const HWCAP_VFPv3 = 1 << 13; | ||
| 491 | pub const HWCAP_VFPv3D16 = 1 << 14; | ||
| 492 | pub const HWCAP_TLS = 1 << 15; | ||
| 493 | pub const HWCAP_VFPv4 = 1 << 16; | ||
| 494 | pub const HWCAP_IDIVA = 1 << 17; | ||
| 495 | pub const HWCAP_IDIVT = 1 << 18; | ||
| 496 | pub const HWCAP_VFPD32 = 1 << 19; | ||
| 497 | pub const HWCAP_IDIV = HWCAP_IDIVA | HWCAP_IDIVT; | ||
| 498 | pub const HWCAP_LPAE = 1 << 20; | ||
| 499 | pub const HWCAP_EVTSTRM = 1 << 21; | ||
| 500 | |||
| 477 | pub const msghdr = extern struct { | 501 | pub const msghdr = extern struct { |
| 478 | msg_name: ?*sockaddr, | 502 | msg_name: ?*sockaddr, |
| 479 | msg_namelen: socklen_t, | 503 | msg_namelen: socklen_t, |
std/os/linux/arm-eabi.zig+8| ... | @@ -78,3 +78,11 @@ pub fn syscall6( | ... | @@ -78,3 +78,11 @@ pub fn syscall6( |
| 78 | 78 | ||
| 79 | /// This matches the libc clone function. | 79 | /// This matches the libc clone function. |
| 80 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 80 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 81 | |||
| 82 | // LLVM calls this when the read-tp-hard feature is set to false. Currently, there is no way to pass | ||
| 83 | // that to llvm via zig. See https://github.com/ziglang/zig/issues/2883 | ||
| 84 | pub nakedcc fn getThreadPointer() usize { | ||
| 85 | return asm volatile("mrc p15, 0, %[ret], c13, c0, 3" | ||
| 86 | : [ret] "=r" (-> usize) | ||
| 87 | ); | ||
| 88 | } | ||
| \ No newline at end of file | |||
std/os/linux/tls.zig+12| ... | @@ -133,6 +133,7 @@ pub fn initTLS() void { | ... | @@ -133,6 +133,7 @@ pub fn initTLS() void { |
| 133 | var at_phent: usize = undefined; | 133 | var at_phent: usize = undefined; |
| 134 | var at_phnum: usize = undefined; | 134 | var at_phnum: usize = undefined; |
| 135 | var at_phdr: usize = undefined; | 135 | var at_phdr: usize = undefined; |
| 136 | var at_hwcap: usize = undefined; | ||
| 136 | 137 | ||
| 137 | var i: usize = 0; | 138 | var i: usize = 0; |
| 138 | while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) { | 139 | while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) { |
| ... | @@ -140,10 +141,21 @@ pub fn initTLS() void { | ... | @@ -140,10 +141,21 @@ pub fn initTLS() void { |
| 140 | elf.AT_PHENT => at_phent = auxv[i].a_un.a_val, | 141 | elf.AT_PHENT => at_phent = auxv[i].a_un.a_val, |
| 141 | elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val, | 142 | elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val, |
| 142 | elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val, | 143 | elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val, |
| 144 | elf.AT_HWCAP => at_phdr = auxv[i].a_un.a_val, | ||
| 143 | else => continue, | 145 | else => continue, |
| 144 | } | 146 | } |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 149 | // If the cpu is arm-based, check if it supports the TLS register | ||
| 150 | if (builtin.arch == builtin.Arch.arm and builtin.os == .linux) { | ||
| 151 | if (at_hwcap & std.os.linux.HWCAP_TLS == 0) { | ||
| 152 | // If the CPU does not support TLS via a coprocessor register, | ||
| 153 | // it could be accessed via a kernel helper function | ||
| 154 | // see musl/src/thread/arm/ for details | ||
| 155 | @panic("cpu does not support TLS via coprocessor register"); | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 147 | // Sanity check | 159 | // Sanity check |
| 148 | assert(at_phent == @sizeOf(elf.Phdr)); | 160 | assert(at_phent == @sizeOf(elf.Phdr)); |
| 149 | 161 |
std/special/c.zig+2| ... | @@ -25,6 +25,8 @@ comptime { | ... | @@ -25,6 +25,8 @@ comptime { |
| 25 | @export("strncmp", strncmp, .Strong); | 25 | @export("strncmp", strncmp, .Strong); |
| 26 | @export("strerror", strerror, .Strong); | 26 | @export("strerror", strerror, .Strong); |
| 27 | @export("strlen", strlen, .Strong); | 27 | @export("strlen", strlen, .Strong); |
| 28 | } else if (builtin.arch == builtin.Arch.arm and builtin.os == .linux) { | ||
| 29 | @export("__aeabi_read_tp", std.os.linux.getThreadPointer, .Strong); | ||
| 28 | } | 30 | } |
| 29 | } | 31 | } |
| 30 | 32 |