authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-21 23:10:45+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-21 19:53:39-04:00
loga11c20e26a6efd977656459710ae3d37fcbb2846
tree9d21b66b14be4cd8349f95bece5e4b8c8ac8aef6
parent4dd17a7c9e3e5220a088087b3729354d6b85b279

Fix TLS for VariantI arches with a twist


1 files changed, 14 insertions(+), 5 deletions(-)

std/os/linux/tls.zig+14-5
......@@ -47,7 +47,7 @@ const TLSVariant = enum {
4747};
4848
4949const tls_variant = switch (builtin.arch) {
50 .arm, .armeb, .aarch64, .aarch64_be, .riscv32, .riscv64 => TLSVariant.VariantI,
50 .arm, .armeb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mipsel => TLSVariant.VariantI,
5151 .x86_64, .i386 => TLSVariant.VariantII,
5252 else => @compileError("undefined tls_variant for this architecture"),
5353};
......@@ -57,8 +57,7 @@ const tls_tcb_size = switch (builtin.arch) {
5757 // ARM EABI mandates enough space for two pointers: the first one points to
5858 // the DTV while the second one is unspecified but reserved
5959 .arm, .armeb, .aarch64, .aarch64_be => 2 * @sizeOf(usize),
60 .i386, .x86_64 => @sizeOf(usize),
61 else => 0,
60 else => @sizeOf(usize),
6261};
6362
6463// Controls if the TCB should be aligned according to the TLS segment p_align
......@@ -67,6 +66,12 @@ const tls_tcb_align_size = switch (builtin.arch) {
6766 else => false,
6867};
6968
69// Controls if the TP points to the end of the TCB instead of its beginning
70const tls_tp_points_past_tcb = switch (builtin.arch) {
71 .riscv32, .riscv64, .mipsel, .powerpc64, .powerpc64le => true,
72 else => false,
73};
74
7075// Check if the architecture-specific parameters look correct
7176comptime {
7277 if (tls_tcb_align_size and tls_variant != TLSVariant.VariantI) {
......@@ -78,10 +83,12 @@ comptime {
7883// make the generated code more efficient
7984
8085const tls_tp_offset = switch (builtin.arch) {
86 .mipsel => 0x7000,
8187 else => 0,
8288};
8389
8490const tls_dtv_offset = switch (builtin.arch) {
91 .mipsel => 0x8000,
8592 else => 0,
8693};
8794
......@@ -119,7 +126,8 @@ pub fn setThreadPointer(addr: usize) void {
119126 );
120127 },
121128 .arm => |arm| {
122 _ = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr);
129 const rc = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr);
130 assert(rc == 0);
123131 },
124132 .riscv64 => {
125133 asm volatile (
......@@ -251,7 +259,8 @@ pub fn copyTLS(addr: usize) usize {
251259 @memcpy(@intToPtr([*]u8, addr + tls_img.data_offset), tls_img.data_src.ptr, tls_img.data_src.len);
252260
253261 // Return the corrected (if needed) value for the tp register
254 return addr + tls_img.tcb_offset + tls_tp_offset;
262 return addr + tls_tp_offset +
263 if (tls_tp_points_past_tcb) tls_img.data_offset else tls_img.tcb_offset;
255264}
256265
257266var main_thread_tls_buffer: [256]u8 align(32) = undefined;