2015-05-21 17 views
7

Sadece Linux sistemlerinde TLS (thread-local storage) uygulamasının nasıl çalıştığını inceliyorum. ELF Handling for Thread-Local Storage belgesi, bir programın iş parçacığı yerel değişkenleri için gereksinimlerinin bir ELF ikili kodunda nasıl kodlanabileceğini ve "çalışma zamanı" nın bu ikili dosyaları nasıl işleyeceğini açıklamaktadır. Bununla birlikte, pratikte TLS alan (lar) ını oluşturan "çalışma zamanı" nın Linux çekirdeği (ve ELF ikili dosyalarını yükleme kodu) veya libc'de bazı başlatma kodu olup olmayacağı açık değildir. Birisi kısaca açıklayabilir mi?Linux'ta, çekirdek tarafından veya TLC (veya başka bir dil çalışma zamanı) tarafından kurulan TLS nedir?

(Arka plan: Bir uygulamayı statik olarak bağlamaya ve çalıştırmaya çalışıyorum, ancak başlangıçta segfaults. Gdb'de, segfault kodunun libc'den bir init kodu olduğunu görebiliyorum. Statik bir değişken okumaya çalışıyor GS'ye göre bir adres kullanılarak, ancak GS sıfırdır.)

+2

glibc ve musl açık kaynaklıdır; onlar için kaynak kodunu kontrol edebilirsiniz. –

+3

TLS (iş parçacığı depolama alanı) veya TLS (aktarım katmanı güvenliği) hakkında mı konuşuyorsunuz? İçerik, iş parçacığı yerel depolama önerir; tag [tag: ssl] ikincisini önerir. Sen eş anlamlı mıydın? [Tag: ssl] etiketini kaldırdım ve [tag: thread-local-storage] özelliğini ekledim, ancak [tag: tls] kendiliğinden açıkça [tag: ssl] ile eşlenmedi. –

+0

@JonathanLeffler, thread-local-storage anlamına gelen tls ekledim. Hatayı düzeltdiğiniz için teşekkürler. –

cevap

4

İş parçacığı depolaması başlatma, libc tarafından sağlanan başlatma kodunun bir parçasıdır. Statik olarak bağlandığında, linker'ınız TLS başlatmayı programınıza bağlı başlangıç ​​koduna eklemelidir.

Örneğin, glibc sahiptir __libc_setup_tls ve _dl_tls_setup sen gcc -static, diyelim ki, üzerinden bağlantı halinde programın başlatılması koduna eklenecektir libc.a yılında, (diğer, ilgili şeyler arasında). (Dinamik bağlantılı programlara _dl_ için ... fonksiyonları statik olarak bağlanan programını çalıştırmak için kullanılmaz ELF dinamik bağlayıcı-yükleyici, ld-linux.so, bir parçasıdır.) Statik olarak bağlanan içinde

Uygun TLS başlatma Bu nedenle, C kitaplığınız (kodu sağlayan) ile takım zinciriniz arasındaki işbirliğinin bir sonucu olur (bu, gerekli tüm başlangıç ​​kodunun nasıl düzgün bir şekilde bağlanacağını anlamalıdır).

Çekirdeğin TLS başlatmasındaki rolü küçüktür. (Temel olarak, sadece .tdata bölümünün başlatma için libc için mevcut olduğundan emin olmanız gerekir.) Ayrıntılar için bkz. ELF file TLS and LOAD program sections.

+0

Bu, GS segmentinin TLS bölümünü işaret edecek şekilde nasıl ayarlandığı konusunda önemli bir soruyu yanıtlamıyor. Bu sadece çekirdeğin yapabileceği bir şey. –

+0

Henüz 'glibc'ye bakmadım, ama sadece musl'ı kontrol ettim. TLS'yi başlangıçta başlatır (dediğiniz gibi), ancak daha sonra TLS için ayrılan alana işaret eden LDT işleminde bir giriş yapmak için bir 'set_thread_area' syscall kullanır. Daha sonra libc, '% gs' kaydını TLS için LDT girişine yönlendirecek şekilde ayarlar. (Bu x86-32 üzerindedir - x86-64 farklı bir bölüm kaydı kullanır.) –

İlgili konular