Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On Linux, is TLS set up by the kernel or by libc (or other language runtime)?

I'm just studying how TLS (thread-local storage) is implemented on Linux systems. The document ELF Handling for Thread-Local Storage explains how a program's requirements for thread-local variables can be encoded in an ELF binary, and how the "runtime" should handle such binaries.

However, it's not clear to me whether in practice the "runtime" which sets up the TLS area(s) will be the Linux kernel (and its code for loading ELF binaries) or some initialization code in libc. Could someone explain briefly?

(Background: I'm trying to statically-link and run an application, but it segfaults on start. In gdb, I can see the segfaulting code is some init code from libc. It's trying to read a static variable using an address relative to GS, but GS is zero.)

like image 498
Alex D Avatar asked May 21 '15 14:05

Alex D


People also ask

How does TLS work in Linux?

The TLS protocol works on two layers where the TLS record protocol provides security to connections. The TLS handshake protocol brings together the client and the server for security key negotiation. Both client and the server authenticate each other before any data transmission.

Is LIBC part of the kernel?

There is actually no libc in kernel space. Libc is user-space library, and you can't use it from kernel-space.

What is LIBC So 6 in Linux?

The pathname /lib/libc. so. 6 (or something similar) is normally a symbolic link that points to the location of the glibc library, and executing this pathname will cause glibc to display various information about the version installed on your system.

How is thread local storage implemented?

Thread-local storage (TLS) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread. The run-time model GCC uses to implement this originates in the IA-64 processor-specific ABI, but has since been migrated to other processors as well.


1 Answers

Thread-local storage initialisation is part of the libc-provided start-up code. When statically linking, your linker should add the TLS initialisation to the start-up code linked into your program.

For example, glibc has __libc_setup_tls and _dl_tls_setup (among other, related things) in libc.a, which will be added to the initialisation code of your program if you link via, say, gcc -static. (For dynamically-linked programs the _dl_... functions are part of the ELF dynamic linker-loader, ld-linux.so, which isn't used to run a statically-linked program.)

Proper TLS initialisation in a statically-linked executable is, therefore, a result of collaboration between your C library (which provides the code) and your toolchain (which has to understand how to properly link in all the necessary start-up code).

The kernel's involvement in TLS initialisation is minor. (Basically, it just has to ensure that the .tdata section is available to libc for initialisation.) See ELF file TLS and LOAD program sections for details.

like image 107
user3113526 Avatar answered Oct 17 '22 22:10

user3113526