Как получить во время компиляции смещение переменной thread_local

Используя gcc под linux, я ищу способ получить смещение локальной переменной потока относительно локальной области хранения потока.
Это смещение — то, что содержится в скомпилированном объектном файле.
На мой взгляд, должен быть макрос или build_in, чтобы получить его.

Код, который выдает во время выполнения, выглядит следующим образом. Что мне нужно, это получить эту константу во время компиляции.

#include <iostream>
#include <thread>

thread_local int x;

template<typename T>
intptr_t getOffset(T& t){
return (intptr_t)&t-(intptr_t)pthread_self();
}

int main(int argc, char **argv)
{
std::cout<<"offset:"<<getOffset<int>(x)<<std::endl;
}

2

Решение

На мой взгляд, должен быть макрос или build_in, чтобы получить его.

Такой макрос было бы нелегко / дешево реализовать. Прежде всего, вы можете определить такое смещение только при компиляции исполняемого файла, потому что для динамической библиотеки это будет зависеть от относительной позиции библиотеки в списке зависимостей исполняемого файла, который ее загружает (или даже не находиться в статическом блоке TLS, если библиотека загружается динамически через dlopenследовательно, не доступны через постоянное смещение от TCB).

Теперь, даже если вы попытаетесь определить смещение в исполняемом файле, вы можете сделать это только для thread_local переменные в самом исполняемом файле, потому что размеры сегментов thread_local для библиотек (и их смещения) определяются только при запуске программы (вероятно, потому, что версия загруженной библиотеки может быть новее, чем та, с которой был связан исполняемый файл и, следовательно, thread_local размер сегмента также может быть разным).

Наконец, даже для переменных исполняемого файла это будет зависеть от относительного порядка объектных файлов и статических / динамических библиотек во время ссылки, поэтому вам потребуется специальная поддержка статического компоновщика для вычисления смещения.

Вы можете предложить разработчикам Binutils рассмотреть возможность добавления перемещения во время компоновки для вычисления смещения thread_local в исполняемом файле или даже перемещения во время выполнения для вычисления thread_local в общем случае, но им потребуются убедительные сценарии использования для рассмотрения такого предложения.

В качестве обходного пути для бедного человека вы можете скомпилировать код два раза и извлечь смещения из symtab:

$ readelf -sW tmp.o | awk '/TLS/{print $8 " " $2}'
yyy 0000000000000000
xxx 0000000000000004
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]