Source
pub fn setThreadPointer(addr: usize) void {
@setRuntimeSafety(false);
@disableInstrumentation();
switch (native_arch) {
.x86 => {
var user_desc: linux.user_desc = .{
.entry_number = area_desc.gdt_entry_number,
.base_addr = addr,
.limit = 0xfffff,
.flags = .{
.seg_32bit = 1,
.contents = 0, // Data
.read_exec_only = 0,
.limit_in_pages = 1,
.seg_not_present = 0,
.useable = 1,
},
};
const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, @intFromPtr(&user_desc) });
assert(rc == 0);
const gdt_entry_number = user_desc.entry_number;
// We have to keep track of our slot as it's also needed for clone()
area_desc.gdt_entry_number = gdt_entry_number;
// Update the %gs selector
asm volatile ("movl %[gs_val], %%gs"
:
: [gs_val] "r" (gdt_entry_number << 3 | 3),
);
},
.x86_64 => {
const rc = @call(.always_inline, linux.syscall2, .{ .arch_prctl, linux.ARCH.SET_FS, addr });
assert(rc == 0);
},
.aarch64, .aarch64_be => {
asm volatile (
\\ msr tpidr_el0, %[addr]
:
: [addr] "r" (addr),
);
},
.arc => {
// We apparently need to both set r25 (TP) *and* inform the kernel...
asm volatile (
\\ mov r25, %[addr]
:
: [addr] "r" (addr),
);
const rc = @call(.always_inline, linux.syscall1, .{ .arc_settls, addr });
assert(rc == 0);
},
.arm, .armeb, .thumb, .thumbeb => {
const rc = @call(.always_inline, linux.syscall1, .{ .set_tls, addr });
assert(rc == 0);
},
.m68k => {
const rc = linux.syscall1(.set_thread_area, addr);
assert(rc == 0);
},
.hexagon => {
asm volatile (
\\ ugp = %[addr]
:
: [addr] "r" (addr),
);
},
.loongarch32, .loongarch64 => {
asm volatile (
\\ move $tp, %[addr]
:
: [addr] "r" (addr),
);
},
.riscv32, .riscv64 => {
asm volatile (
\\ mv tp, %[addr]
:
: [addr] "r" (addr),
);
},
.csky, .mips, .mipsel, .mips64, .mips64el => {
const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr });
assert(rc == 0);
},
.powerpc, .powerpcle => {
asm volatile (
\\ mr 2, %[addr]
:
: [addr] "r" (addr),
);
},
.powerpc64, .powerpc64le => {
asm volatile (
\\ mr 13, %[addr]
:
: [addr] "r" (addr),
);
},
.s390x => {
asm volatile (
\\ lgr %%r0, %[addr]
\\ sar %%a1, %%r0
\\ srlg %%r0, %%r0, 32
\\ sar %%a0, %%r0
:
: [addr] "r" (addr),
: "r0"
);
},
.sparc, .sparc64 => {
asm volatile (
\\ mov %[addr], %%g7
:
: [addr] "r" (addr),
);
},
else => @compileError("Unsupported architecture"),
}
}