/// 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 { 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 )) }