@@ -47,7 +47,7 @@ const TLSVariant = enum {
47
47
};
48
48
49
49
const 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 ,
51
51
.x86_64 , .i386 = > TLSVariant .VariantII ,
52
52
else = > @compileError ("undefined tls_variant for this architecture" ),
53
53
};
@@ -57,8 +57,7 @@ const tls_tcb_size = switch (builtin.arch) {
57
57
// ARM EABI mandates enough space for two pointers: the first one points to
58
58
// the DTV while the second one is unspecified but reserved
59
59
.arm , .armeb , .aarch64 , .aarch64_be = > 2 * @sizeOf (usize ),
60
- .i386 , .x86_64 = > @sizeOf (usize ),
61
- else = > 0 ,
60
+ else = > @sizeOf (usize ),
62
61
};
63
62
64
63
// 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) {
67
66
else = > false ,
68
67
};
69
68
69
+ // Controls if the TP points to the end of the TCB instead of its beginning
70
+ const tls_tp_points_past_tcb = switch (builtin .arch ) {
71
+ .riscv32 , .riscv64 , .mipsel , .powerpc64 , .powerpc64le = > true ,
72
+ else = > false ,
73
+ };
74
+
70
75
// Check if the architecture-specific parameters look correct
71
76
comptime {
72
77
if (tls_tcb_align_size and tls_variant != TLSVariant .VariantI ) {
@@ -78,10 +83,12 @@ comptime {
78
83
// make the generated code more efficient
79
84
80
85
const tls_tp_offset = switch (builtin .arch ) {
86
+ .mipsel = > 0x7000 ,
81
87
else = > 0 ,
82
88
};
83
89
84
90
const tls_dtv_offset = switch (builtin .arch ) {
91
+ .mipsel = > 0x8000 ,
85
92
else = > 0 ,
86
93
};
87
94
@@ -119,7 +126,8 @@ pub fn setThreadPointer(addr: usize) void {
119
126
);
120
127
},
121
128
.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 );
123
131
},
124
132
.riscv64 = > {
125
133
asm volatile (
@@ -251,7 +259,8 @@ pub fn copyTLS(addr: usize) usize {
251
259
@memcpy (@intToPtr ([* ]u8 , addr + tls_img .data_offset ), tls_img .data_src .ptr , tls_img .data_src .len );
252
260
253
261
// 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 ;
255
264
}
256
265
257
266
var main_thread_tls_buffer : [256 ]u8 align (32 ) = undefined ;
0 commit comments