diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-09-04 14:39:36 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-04 14:39:36 -0400 |
| commit | 090f2ffb820ab10773322636d3c940bbfd6028be (patch) | |
| tree | 7a36bef3a48854cb08cb9bbc6a727212f0ff7858 /std/os/linux | |
| parent | e540e5b8ec1d90b86d6f41814507e6ae4ae5edd8 (diff) | |
| parent | df06976e73e37a36009fb5f43c2310ad610a4a2e (diff) | |
| download | zig-090f2ffb820ab10773322636d3c940bbfd6028be.tar.gz zig-090f2ffb820ab10773322636d3c940bbfd6028be.zip | |
Merge pull request #3152 from Snektron/arm-support-improvement
Arm support improvement (part 1)
Diffstat (limited to 'std/os/linux')
| -rw-r--r-- | std/os/linux/arm-eabi.zig | 96 | ||||
| -rw-r--r-- | std/os/linux/arm64.zig | 7 | ||||
| -rw-r--r-- | std/os/linux/tls.zig | 13 |
3 files changed, 116 insertions, 0 deletions
diff --git a/std/os/linux/arm-eabi.zig b/std/os/linux/arm-eabi.zig new file mode 100644 index 0000000000..c8a5bbe378 --- /dev/null +++ b/std/os/linux/arm-eabi.zig @@ -0,0 +1,96 @@ +pub fn syscall0(number: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number) + : "memory" + ); +} + +pub fn syscall1(number: usize, arg1: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1) + : "memory" + ); +} + +pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2) + : "memory" + ); +} + +pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3) + : "memory" + ); +} + +pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4) + : "memory" + ); +} + +pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5) + : "memory" + ); +} + +pub fn syscall6( + number: usize, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, + arg6: usize, +) usize { + return asm volatile ("svc #0" + : [ret] "={r0}" (-> usize) + : [number] "{r7}" (number), + [arg1] "{r0}" (arg1), + [arg2] "{r1}" (arg2), + [arg3] "{r2}" (arg3), + [arg4] "{r3}" (arg4), + [arg5] "{r4}" (arg5), + [arg6] "{r5}" (arg6) + : "memory" + ); +} + +/// This matches the libc clone function. +pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; + +// LLVM calls this when the read-tp-hard feature is set to false. Currently, there is no way to pass +// that to llvm via zig, see https://github.com/ziglang/zig/issues/2883. +// LLVM expects libc to provide this function as __aeabi_read_tp, so it is exported if needed from special/c.zig. +pub extern fn getThreadPointer() usize { + return asm volatile("mrc p15, 0, %[ret], c13, c0, 3" + : [ret] "=r" (-> usize) + ); +}
\ No newline at end of file diff --git a/std/os/linux/arm64.zig b/std/os/linux/arm64.zig index 94cf8818de..28da9af1c6 100644 --- a/std/os/linux/arm64.zig +++ b/std/os/linux/arm64.zig @@ -2,6 +2,7 @@ pub fn syscall0(number: usize) usize { return asm volatile ("svc #0" : [ret] "={x0}" (-> usize) : [number] "{x8}" (number) + : "memory", "cc" ); } @@ -10,6 +11,7 @@ pub fn syscall1(number: usize, arg1: usize) usize { : [ret] "={x0}" (-> usize) : [number] "{x8}" (number), [arg1] "{x0}" (arg1) + : "memory", "cc" ); } @@ -19,6 +21,7 @@ pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize { : [number] "{x8}" (number), [arg1] "{x0}" (arg1), [arg2] "{x1}" (arg2) + : "memory", "cc" ); } @@ -29,6 +32,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize { [arg1] "{x0}" (arg1), [arg2] "{x1}" (arg2), [arg3] "{x2}" (arg3) + : "memory", "cc" ); } @@ -40,6 +44,7 @@ pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz [arg2] "{x1}" (arg2), [arg3] "{x2}" (arg3), [arg4] "{x3}" (arg4) + : "memory", "cc" ); } @@ -52,6 +57,7 @@ pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz [arg3] "{x2}" (arg3), [arg4] "{x3}" (arg4), [arg5] "{x4}" (arg5) + : "memory", "cc" ); } @@ -73,6 +79,7 @@ pub fn syscall6( [arg4] "{x3}" (arg4), [arg5] "{x4}" (arg5), [arg6] "{x5}" (arg6) + : "memory", "cc" ); } diff --git a/std/os/linux/tls.zig b/std/os/linux/tls.zig index a10d68663b..3c55013f47 100644 --- a/std/os/linux/tls.zig +++ b/std/os/linux/tls.zig @@ -118,6 +118,9 @@ pub fn setThreadPointer(addr: usize) void { : [addr] "r" (addr) ); }, + .arm => |arm| { + _ = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr); + }, else => @compileError("Unsupported architecture"), } } @@ -130,6 +133,7 @@ pub fn initTLS() void { var at_phent: usize = undefined; var at_phnum: usize = undefined; var at_phdr: usize = undefined; + var at_hwcap: usize = undefined; var i: usize = 0; while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) { @@ -137,6 +141,7 @@ pub fn initTLS() void { elf.AT_PHENT => at_phent = auxv[i].a_un.a_val, 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_phdr = auxv[i].a_un.a_val, else => continue, } } @@ -156,6 +161,14 @@ pub fn initTLS() void { } if (tls_phdr) |phdr| { + // If the cpu is arm-based, check if it supports the TLS register + if (builtin.arch == builtin.Arch.arm and hwcap & std.os.linux.HWCAP_TLS == 0) { + // If the CPU does not support TLS via a coprocessor register, + // a kernel helper function can be used instead on certain linux kernels. + // See linux/arch/arm/include/asm/tls.h and musl/src/thread/arm/__set_thread_area.c. + @panic("TODO: Implement ARM fallback TLS functionality"); + } + // Offsets into the allocated TLS area var tcb_offset: usize = undefined; var dtv_offset: usize = undefined; |
