From 9f356aa92c33cf75e71170888cf5b7a8e4b90421 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Mon, 2 Feb 2026 17:06:23 +0100 Subject: [PATCH] amd64 TLS --- assets/img/Elfdiagram.png | Bin 0 -> 36673 bytes assets/img/compiler-pipeline.jpg | Bin 0 -> 11508 bytes assets/img/sisyphus.jpeg | Bin 0 -> 33465 bytes content/blog/MOP2/AMD64-TLS.adoc | 565 +++++++++++++++++++++++++++++++ templates/header.ftl | 11 +- 5 files changed, 572 insertions(+), 4 deletions(-) create mode 100644 assets/img/Elfdiagram.png create mode 100644 assets/img/compiler-pipeline.jpg create mode 100644 assets/img/sisyphus.jpeg create mode 100644 content/blog/MOP2/AMD64-TLS.adoc diff --git a/assets/img/Elfdiagram.png b/assets/img/Elfdiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd26f2b372f8eb65cd634d177c1d94d37f2b1b7 GIT binary patch literal 36673 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 Yw1e~%sR^I2DEMQjYpU}?+xh1I1?MXl1^@s6 literal 0 HcmV?d00001 diff --git a/assets/img/compiler-pipeline.jpg b/assets/img/compiler-pipeline.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aab90d4e3184797b8f7cc86e653e2427e8005ee8 GIT binary patch literal 11508 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 I3xALPFXWq4l>h($ literal 0 HcmV?d00001 diff --git a/content/blog/MOP2/AMD64-TLS.adoc b/content/blog/MOP2/AMD64-TLS.adoc new file mode 100644 index 0000000..2168c0d --- /dev/null +++ b/content/blog/MOP2/AMD64-TLS.adoc @@ -0,0 +1,565 @@ += Implementing TLS (Thread Local storage) for x86_64 +Kamil Kowalczyk +2026-01-31 +:jbake-type: post +:jbake-tags: MOP2 osdev +:jbake-status: published +:og-image: img/sisyphus.jpeg +:og-title: x86_64 thread-local storage implementation + + +In this article I'd like to explore the implementation details of thread local storage on x86_64/amd64 +for my operating system with compliance to System V ABI. + +full code is as always at: https://git.kamkow1lair.pl/kamkow1/MOP3 + +== Preface + +We're going to implement the bare working minimum of the ABI, just enough to make `__thread` +keyword work in Clang and GCC. The spec is more complicated than that. We're going to implement *static* +TLS (there's also dynamic TLS, you can look up `__tls_get_addr` if you're interested in going further). + +Also I'd like to share this article as a very useful resource regarding the TLS: https://maskray.me/blog/2021-02-14-all-about-thread-local-storage. +It's more generally about TLS, but made for a great learning resource for me and I really recommend you read it too. + +Other resources: + +* Spec reference: https://uclibc.org/docs/tls.pdf +* OSDev Wiki: https://wiki.osdev.org/Thread_Local_Storage + +== What is thread local storage? + +Thread local storage is a type of storage in a multitasked application, where each task has it's own copy +of it, distinct from other tasks. + +.Example of TLS in C11 +[source,c] +---- +#include +#include +#include + +thread_local int counter = 0; + +int thread_func(void *arg) { + int id = *(int*)arg; + counter++; // Each thread increments its own copy + printf("Thread %d: counter = %d\n", id, counter); + return 0; +} + +int main() { + thrd_t threads[4]; + int ids[4] = {1, 2, 3, 4}; + + for (int i = 0; i < 4; i++) { + thrd_create(&threads[i], thread_func, &ids[i]); + } + + for (int i = 0; i < 4; i++) { + thrd_join(threads[i], NULL); + } + + printf("Main thread counter: %d\n", counter); // Main's own copy + return 0; +} +---- + +Although the application is accessing and modifying a global variable, it's actually different memories being +used under the hood. Each thread has it's own copy to work with. + +What is `thread_local`? In the pre-C23 world it's a macro, which expands to the `_Thread_local` keyword, which +is the same as compiler specific `__thread` in GCC and Clang. + +== Reverse engineering + +We're going to learn how the TLS works via reverse engineering. We need to understand it, before getting +to Implementing it ourselves. Let's look at the disassembly first, generated by Clang 21.1.0 on https://godbolt.org. + +I've added some comments here, so everything is nice and easy to read. + +.Assembly generated from Clang +[source,x86asm] +---- +/* int thread_func(void *arg) */ +thread_func: + /* Push new stack frame */ + push rbp + mov rbp, rsp + mov qword ptr [rbp - 8], rdi /* store arg on the stack frame */ + + + /* Read the ID value */ + /* int id = *(int*)arg; */ + mov rax, qword ptr [rbp - 8] + mov eax, dword ptr [rax] + mov dword ptr [rbp - 12], eax + + + /* counter++; */ + mov rax, qword ptr fs:[0] /* ?????????? */ + lea rax, [rax + counter@TPOFF] + mov ecx, dword ptr [rax] + add ecx, 1 /* do the ++ */ + mov dword ptr [rax], ecx + + /* return 0; */ + xor eax, eax + pop rbp + ret + +/* The rest is irrelevant here... */ + +counter: + .long 0 +---- + +What is `fs:[0]` (also written commonly as `%fs:0` in GNU syntax)? + +We're going to refer to fs as `%fs` (GNU syntax), because that's how I write my assembly, but you can look +up the analogous syntax for you assembler (like nasm or fasm). + +== x86 segmentation + +`%fs` is an x86 segment register. There are also other segment registers: + +- `%cs` code segment +- `%ds` data segment +- `%ss` stack segment +- `%es` extra segment +- `%fs`, `%gs` general segments + +=== Real mode (16 bit) + +x86_64 (yes, a 64 bit CPU) boots up first in 16 bit mode or the "real mode". In real mode we only have 16 bit +registers, so one might think that we can address only up to 64K of memory. Segmentation let's us use more +memory, because it changes the logical addressing scheme. Instead of pointing to a specific byte +in memory, we an point to a block of memory and displace from the base of it to get the byte - and thus we +can address more than 64K. Early x86 CPUs (like the OG Intel 8086) could address up to 1MB. + +This explains the `%fs:0` syntax. We have a `%fs` base and a `0` displacement. + +A good explaination can be also found on the OSDev wiki: https://wiki.osdev.org/Segmentation. + +Also reading the `GDT` article will come in handy: https://wiki.osdev.org/Global_Descriptor_Table. From now on +I will assume we're already working with 64 bit GDT and we're going to skip the 32 bit mode entirely in this +article. + +=== Long mode (64 bit) + +Real mode uses 16 bit addresses as the segment base, so analogously 64 bit segmentation will use 64 bit addresses. + +=== Segment registers are different + +Segment registers are not like your typical `%rax` or `%rcx` - at least some. You can freely write to `%ds`, +`%ss`, `%es` and that's it! `%cs`, `%fs`, `%gs` are special in that they cannot be written to manually. +`%cs` can be reloaded by for example `lretq` instruction, `%fs` and `%gs` require writing to an `MSR` +(will explain in a bit). + +== Detour about MSRs + +MSR mean Model-Specific Register. Intel basically wanted to add unstable features and didn't want to +clutter up their architecture with experimental slop. Some of the MSRs were useful enough that they made it into +future Intel CPUs and stayed with us. Generaly speaking, MSRs control OS-related stuff about the CPU. + +MSRs are used with the `rdmsr`/`wrmsr` instructions. The scheme is like so: + +[source,x86asm] +---- +movl NUMBER_OF_MSR, %ecx +movl VALUE_BITS_LOW, %eax +movl VALUE_BITS_HIGH, %edx +wrmsr + +movl NUMBER_OF_MSR, %ecx +rdmsr +/* now %eax contains high bits and %edx low bits. These two shall be concatinated into a 64 bit value */ +---- + +== `%fs` and MSRs + +I've mentioned previously that the `%fs` and `%gs` registers can be written to by writing to an MSR - but which one? + +The MSR we care about is called (in the Intel manual) `IA32_FS_BASE`. To address the confusion early on I'll say +that some people call it slightly differently, for eg. in the Xen hypervisor code it's called `MSR_FS_BASE`. My +kernel takes the definition header from Xen, so that's why I will use Xen's naming scheme, but `IA32_FS_BASE` +would be the *official* name. + +Looking at the file `kernel/amd64/msr-index.h` we can see a juicy `#define`: + +.kernel/amd64/msr-index.h +[source,c] +---- +#define MSR_FS_BASE _AC (0xc0000100, U) /* 64bit FS base */ +---- + +The magic MSR number is `0xc0000100`. Here's how I'm using it: + +.kernel/amd64/sched1.c +[source,c] +---- +void do_sched (struct proc* proc, spin_lock_t* cpu_lock, spin_lock_ctx_t* ctxcpu) { + spin_lock_ctx_t ctxpr; + + spin_lock (&proc->lock, &ctxpr); + + thiscpu->tss.rsp0 = proc->pdata.kernel_stack; /* set TSS kernel stack */ + thiscpu->syscall_kernel_stack = proc->pdata.kernel_stack; /* set syscall entry stack */ + amd64_wrmsr (MSR_FS_BASE, proc->pdata.fs_base); /* switch to proc's fs base */ + + spin_unlock (&proc->lock, &ctxpr); + spin_unlock (cpu_lock, ctxcpu); + + amd64_do_sched ((void*)&proc->pdata.regs, (void*)proc->procgroup->pd.cr3_paddr); +} +---- + +The MSR helpers are written like so: + +.kernel/amd64/msr.c +[source,c] +---- +/// Read a model-specific register +uint64_t amd64_rdmsr (uint32_t msr) { + uint32_t low, high; + __asm__ volatile ("rdmsr" : "=a"(low), "=d"(high) : "c"(msr)); + return ((uint64_t)high << 32 | (uint64_t)low); +} + +/// Write a model-specific register +void amd64_wrmsr (uint32_t msr, uint64_t value) { + uint32_t low = (uint32_t)(value & 0xFFFFFFFF); + uint32_t high = (uint32_t)(value >> 32); + __asm__ volatile ("wrmsr" ::"c"(msr), "a"(low), "d"(high)); +} +---- + +What we do is we swap out base value of `%fs` for each process and every process has it's own TLS! +When processes are switched, the new `MSR_FS_BASE` is written. + +== So what is `%fs:0` again? + +We've managed to establish what `%fs` is, but what `%fs:0` is? + +The authors of System V TLS ABI for x86_64 were quite smart. `%fs` CANNOT be accessed on it's own, sort of. We +can't use it like a regular pointer to the TLS. We can only use segment registers with a displacement. +So when we can't use `%fs`, we can use `%fs:0`! `%fs` points to the TLS + 8 byte pointer back to itself, so then +`%fs:0` can become a pointer to the real TLS memory block. + +Also, the TLS variable offsets are negative! + +[source,text] +---- +The TLS memory: + + Var 1 Var 2 Var 3 Var 4 .... The pointer ++-------------------------------------------------------------------------------+ +| | | | | | | | | | <---+ ++-------------------------------------------------------------------------------+ | + | + ^ | + | | + TLS (fs base) | + | + %fs:0 --------------+ +---- + +If this is too difficult to grasp (don't worry, I've spent days banging by head against a wall mysekf), I'll show you now +the code, which handles the TLS in a bit. Now we're going to take another detour to discuss how the TLS looks like +from the perspective of the *ELF* file format. + +== TLS and ELF relationship + +I'm not going to go out of my way to explain the ELF format entirely - it's out of scope for today, but I'll link +a useful article here: https://wiki.osdev.org/ELF. It's a great read on the basics of the ELF format. + +++++ +
+ ELF file diagram +
+++++ +~https://wiki.osdev.org/images/f/fe/Elfdiagram.png~ + +ELF has the so-called "sections". A section is a piece of data that makes up the final executable. A section can +be `.text` where your executable code resides or `.rodata` where your read-only data sits (like string literals). + +ELF also has a special TLS section. This may seem confusing, since why would ELF store some sort of TLS, when +each task must have it's own? The TLS section is actually a template/"meta" section. It's not the actual TLS, but +rather a template of how should the TLS be contructed. + +For example: + +[source,c] +---- +__thread int a = 123; + +void my_thread (void) { + printf ("a = %d\n", a); + + a = 456; + + printf ("a = %d\n", a); +} +---- + +The first printf will display 123, because the TLS template says that `a` shall have initial value of 123, but +then the thread is free to modify it's own version. It just starts out with what is provided by the ELF file. + +=== Linking the user application + +An ELF application has to be linked after we've compiled all the necessary object files. + +++++ +
+ Compiler pipeline +
+++++ +~https://media.geeksforgeeks.org/wp-content/uploads/20250208151053192719/linker-660.jpg~ + +To get the exact ELF layout we need (remember, we're making our own OS), we can use a linker script. + +[source,text] +---- +OUTPUT_FORMAT(elf64-x86-64) + +ENTRY(_start) + +PHDRS { + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; + bss PT_LOAD; + tls PT_TLS; /* <------ !!!! */ +} + +SECTIONS { + . = 0x0000500000000000; + + /* The executable code instructions */ + .text : { + *(.text .text.*) + *(.ltext .ltext.*) + } :text + + . = ALIGN(0x1000); + + /* Read-only data */ + .rodata : { + *(.rodata .rodata.*) + } :rodata + + . = ALIGN(0x1000); + + /* initialized data */ + .data : { + *(.data .data.*) + *(.ldata .ldata.*) + } :data + + . = ALIGN(0x1000); + + __bss_start = .; + + /* uninitialized data */ + .bss : { + *(.bss .bss.*) + *(.lbss .lbss.*) + } :bss + + __bss_end = .; + + . = ALIGN(0x1000); + + __tdata_start = .; + + /* initialized TLS data */ + .tdata : { + *(.tdata .tdata.*) + } :tls /* <------ !!!! */ + + __tdata_end = .; + + __tbss_start = .; + + /* uninitialized TLS data */ + .tbss : { + *(.tbss .tbss.*) + } :tls /* <------ !!!! */ + + __tbss_end = .; + + __tls_size = __tbss_end - __tdata_start; + + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } +} +---- + +`PT_TLS` is the "program header" type - in this case we say that we want this part of the executable to be of +TLS type. This will help our OS' loader distinguish between different parts of the app and how should it act upon +them. + +Also note that we mark `.tdata` and `.tbss` both as `:tls`. This just tells the linker to merge those sections +together into a `tls` section (which we mark as `PT_TLS`). + +== Loader + +Now let's take a look inside the ELF loader: + +[source,c] +---- + case PT_TLS: { +#if defined(__x86_64__) + if (phdr->p_memsz > 0) { + /* What is the aligment we need to use? */ + size_t tls_align = phdr->p_align ? phdr->p_align : sizeof (uintptr_t); + /* Size of the TLS memory block (variables go here) */ + size_t tls_size = align_up (phdr->p_memsz, tls_align); + /* Size needed - TLS block size + 8 bytes (64 bits) for back pointer */ + size_t tls_total_needed = tls_size + sizeof (uintptr_t); + /* amount of pages to allocate */ + size_t blks = div_align_up (tls_total_needed, PAGE_SIZE); + /* Initialize TLS template in the procgroup. This will be copied into individual TLSes */ + proc->procgroup->tls.tls_tmpl_pages = blks; + proc->procgroup->tls.tls_tmpl_size = tls_size; + proc->procgroup->tls.tls_tmpl_total_size = tls_total_needed; + + /* malloc () and zero out */ + proc->procgroup->tls.tls_tmpl = malloc (blks * PAGE_SIZE); + memset (proc->procgroup->tls.tls_tmpl, 0, blks * PAGE_SIZE); + + /* copy initialized stuff */ + memcpy (proc->procgroup->tls.tls_tmpl, (void*)((uintptr_t)elf + phdr->p_offset), + phdr->p_filesz); + + proc_init_tls (proc); + } +#endif + } break; +---- + +[source,c] +---- +void proc_init_tls (struct proc* proc) { + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + + /* This application doesn't use TLS */ + if (proc->procgroup->tls.tls_tmpl == NULL) + return; + + size_t tls_size = proc->procgroup->tls.tls_tmpl_size; + size_t pages = proc->procgroup->tls.tls_tmpl_pages; + + uintptr_t tls_paddr; + uint32_t flags = MM_PG_USER | MM_PG_PRESENT | MM_PG_RW; + + /* allocate a new TLS memory space and map it into the procgroup's address space */ + uintptr_t tls_vaddr = procgroup_map (proc->procgroup, 0, pages, flags, &tls_paddr); + + uintptr_t k_tls_addr = (uintptr_t)hhdm->offset + tls_paddr; + + /* zero and copy the template contents */ + memset ((void*)k_tls_addr, 0, pages * PAGE_SIZE); + memcpy ((void*)k_tls_addr, (void*)proc->procgroup->tls.tls_tmpl, tls_size); + + /* kernel address and user address + size will point to the tls pointer */ + uintptr_t ktcb = k_tls_addr + tls_size; + uintptr_t utcb = tls_vaddr + tls_size; + + /* write the pointer value, which makes the TLS point to itself */ + *(uintptr_t*)ktcb = utcb; + + /* store as fs_base for switching during scheduling */ + proc->pdata.fs_base = utcb; + /* save allocation address to later free it when not needed */ + proc->pdata.tls_vaddr = tls_vaddr; +} +---- + +== Conclusion + +And that's it! we can use the TLS now in user apps! + +[source,c] +---- +#define MUTEX 2000 + +LOCAL volatile char letter = 'c'; + +void app_proc1 (void) { + letter = 'a'; + + for (;;) { + mutex_lock (MUTEX); + + for (int i = 0; i < 3; i++) + test (letter); + + mutex_unlock (MUTEX); + } + + process_quit (); +} + +void app_proc2 (void) { + letter = 'b'; + + for (;;) { + mutex_lock (MUTEX); + + for (int i = 0; i < 3; i++) + test (letter); + + mutex_unlock (MUTEX); + } + + process_quit (); +} + +void app_proc3 (void) { + letter = 'c'; + + for (;;) { + mutex_lock (MUTEX); + + for (int i = 0; i < 3; i++) + test (letter); + + mutex_unlock (MUTEX); + } + + process_quit (); +} + +void app_main (void) { + mutex_create (MUTEX); + + letter = 'a'; + + process_spawn (&app_proc1, NULL); + process_spawn (&app_proc2, NULL); + process_spawn (&app_proc3, NULL); + + for (;;) { + mutex_lock (MUTEX); + + for (int i = 0; i < 3; i++) + test (letter); + + mutex_unlock (MUTEX); + } +} +---- + +=== My personal thoughts + +image::/img/sisyphus.jpeg["Literally me"] +~https://miro.medium.com/1*zW3S02mX5hqkpBBx1YUWhQ.jpeg~ + +This was difficult... Way too difficult to implement. When reading the spec and then trying to make it work, I've +noticed that all this pointer/size/alignment trickery is just so we can go around the face that x86_64 doesn't +have a built-in architectural mechanism to support such thing as TLS. All you have is a bunch of free registers +and it's up to you to make something out of that. I guess ARM is better in this case, because there's a single +source of authority that produces the CPU and sets the rules to abide by. diff --git a/templates/header.ftl b/templates/header.ftl index 240faac..40c182c 100644 --- a/templates/header.ftl +++ b/templates/header.ftl @@ -4,10 +4,13 @@ <#if (content.title)??>${content.title}<#else>JBake</#if> - - - + + + + <#if content['og-image']??> + + @@ -29,4 +32,4 @@
- \ No newline at end of file +