56 lines
1.3 KiB
Rust
56 lines
1.3 KiB
Rust
/// read the value in the given tls slot
|
|
pub unsafe fn read_tls(index: u32) -> usize {
|
|
let mut tls_slot: usize;
|
|
core::arch::asm!(
|
|
"mov {x}, gs:[1480h + {y:r} * 8]",
|
|
x = out(reg) tls_slot,
|
|
y = in(reg) index
|
|
);
|
|
tls_slot
|
|
}
|
|
|
|
/// write a value into the given tls slot
|
|
pub unsafe fn write_tls(index: u32, value: usize) {
|
|
core::arch::asm!(
|
|
"mov gs:[1480h + {y:r} * 8], {x}",
|
|
x = in(reg) value,
|
|
y = in(reg) index
|
|
);
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn read_tls_bitmap() -> u64 {
|
|
let mut _tls: u64 = 0;
|
|
core::arch::asm!(
|
|
"mov {x}, gs:[60h]", // TEB->PEB
|
|
"mov {x}, [{x} + 80h]", // PEB->TlsBitmap
|
|
x = out(reg) _tls,
|
|
);
|
|
_tls
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn write_tls_bitmap(value: u64) {
|
|
let peb: u64 = 0;
|
|
core::arch::asm!(
|
|
"mov {x}, gs:[60h]", // TEB->PEB
|
|
"mov [{x} + 80h], {y}", // PEB->TlsBitmap
|
|
x = in(reg) peb,
|
|
y = in(reg) value,
|
|
);
|
|
}
|
|
|
|
/// acquires a tls slot
|
|
pub unsafe fn acquire_tls() -> Option<u32> {
|
|
let bitmap = read_tls_bitmap();
|
|
(0..64)
|
|
.filter(|i| bitmap & ( 1 << i ) == 0)
|
|
.inspect(|i|{
|
|
write_tls_bitmap(bitmap | ( 1 << i))
|
|
}).next()
|
|
}
|
|
|
|
/// free's the given tls slot
|
|
pub unsafe fn release_tls(slot: u32) {
|
|
write_tls_bitmap(read_tls_bitmap() & !(1 << slot ))
|
|
} |