2015-05-21 18 views
7

Tôi chỉ đang nghiên cứu cách TLS (lưu trữ cục bộ) được triển khai trên các hệ thống Linux. Tài liệu ELF Handling for Thread-Local Storage giải thích cách yêu cầu của một chương trình cho các biến thread-local có thể được mã hóa trong một nhị phân ELF và cách "thời gian chạy" nên xử lý các tệp nhị phân đó. Tuy nhiên, nó không rõ ràng với tôi cho dù trong thực tế "thời gian chạy" mà thiết lập các khu vực TLS sẽ là hạt nhân Linux (và mã của nó để tải ELF nhị phân) hoặc một số mã khởi tạo trong libc. NGUYÊN NHÂN Ai đó có thể giải thích ngắn gọn?Trên Linux, TLS được thiết lập bởi hạt nhân hay bằng libc (hoặc thời gian chạy ngôn ngữ khác)?

(Bối cảnh: Tôi đang cố gắng liên kết tĩnh và chạy một ứng dụng, nhưng nó sẽ làm thay đổi khi bắt đầu. Trong gdb, tôi có thể thấy mã segfaulting là một số mã init từ libc. sử dụng địa chỉ tương đối với GS, nhưng GS bằng không.)

+2

glibc và musl là nguồn mở; bạn có thể kiểm tra mã nguồn cho chúng. –

+3

Bạn đang thảo luận về TLS (lưu trữ cục bộ) hoặc TLS (bảo mật lớp truyền tải)? Nội dung đề xuất bộ nhớ cục bộ; tag [tag: ssl] gợi ý cái sau. Bạn đã đồng bộ hóa chưa? Tôi đã xóa [tag: ssl] và thêm [tag: thread-local-storage], mặc dù [tag: tls] không tự hiển nhiên được ánh xạ tới [tag: ssl]. –

+0

@JonathanLeffler, tôi đã thêm tls, có nghĩa là lưu trữ cục bộ. Cảm ơn bạn đã sửa lỗi. –

Trả lời

4

Khởi tạo bộ nhớ cục bộ là một phần của mã khởi động do libc cung cấp. Khi liên kết tĩnh, trình liên kết của bạn nên thêm khởi tạo TLS vào mã khởi động được liên kết trong chương trình của bạn.

Ví dụ, glibc có __libc_setup_tls_dl_tls_setup (trong số khác, những thứ liên quan) trong libc.a, mà sẽ được thêm vào các mã khởi động của chương trình của bạn nếu bạn liên kết qua, nói rằng, gcc -static. (Đối với các chương trình được liên kết động, các hàm _dl_ ... là một phần của trình tải liên kết động ELF, ld-linux.so, không được sử dụng để chạy chương trình được liên kết tĩnh.)

Khởi tạo TLS đúng cách trong liên kết tĩnh thực thi được, do đó, là kết quả của sự cộng tác giữa thư viện C của bạn (cung cấp mã) và chuỗi công cụ của bạn (mà phải hiểu cách liên kết đúng cách trong tất cả các mã khởi động cần thiết).

Sự tham gia của hạt nhân trong quá trình khởi tạo TLS không đáng kể. (Về cơ bản, nó chỉ phải đảm bảo rằng phần .tdata có sẵn cho libc để khởi tạo.) Xem ELF file TLS and LOAD program sections để biết chi tiết.

+0

Điều này không trả lời câu hỏi quan trọng về cách phân đoạn GS được thiết lập để trỏ đến phần TLS. Đó là điều mà chỉ hạt nhân mới có thể làm được. –

+0

Tôi chưa xem 'glibc', nhưng tôi chỉ kiểm tra' musl'. Nó khởi tạo TLS khi khởi động (như bạn đã nói), nhưng sau đó cũng sử dụng một 'set_thread_area' syscall để tạo một mục trong quá trình 'LDT trỏ đến không gian được cấp phát cho TLS. Sau đó, libc đặt thanh ghi '% gs' để nó đề cập đến mục LDT cho TLS. (Đây là x86-32 - x86-64 sử dụng thanh ghi phân đoạn khác.) –

Các vấn đề liên quan