Каким образом локальное хранилище потока через ключевое слово gcc __thread реализовано в x86_64? - PullRequest
0 голосов
/ 05 июня 2018

Я копаюсь в libc и нашел интересную последовательность asm, которую пытаюсь понять.glibc-2.27/malloc/malloc.c имеет:

 static __thread tcache_perthread_struct *tcache = NULL;
 ...
 # define MAYBE_INIT_TCACHE() \                                                                                                                                                 
      if (__glibc_unlikely (tcache == NULL)) \
 ....                                                                                                                                          
 void *                                                                                                                                                                         
 __libc_malloc (size_t bytes) {
 ...
    MAYBE_INIT_TCACHE()

gcc переводит его в:

   96a97:       48 8b 2d da 42 35 00    mov    0x3542da(%rip),%rbp        # 3ead78 <.got+0x18>        
   ...     
   96aa6:       64 48 8b 4d 00          mov    %fs:0x0(%rbp),%rcx                                                                     

во время выполнения mov 0x3542da(%rip),%rbp даст отрицательное значение, то есть:

(gdb) p $rbp
$1 = (void *) 0xfffffffffffffec0

Сегмент% fs загружается в __libc_setup_tls с помощью syscall arch_prct (как я узнал в другом потоке), и, похоже, существует цикл по заголовкам программ типа PT_TLS, который, вероятно, определяет агрегированные размеры переменных tls, помеченные с помощьюключевое слово __thread в gcc.Переменные с пометкой __thread, кажется, доступны ниже tcb struct pthread с использованием отрицательных индексов.Отрицательные индексы переменных tls, по-видимому, находятся в глобальной таблице смещений, в приведенном выше примере, т.е.

 0x3542da(%rip) ... # 3ead78 <.got+0x18> 

Вопрос: Есть ли описание, какие элементы (libc, ld, gcc) участвуют в GOT?Расчет индексов TLS и как это делается подробно?Я предполагаю, что, возможно, существует предварительно рассчитанный макет, но как обрабатываются библиотеки, загружаемые через libdl?и т.д ...

...