Адрес константы символа функции C между компиляциями - PullRequest
0 голосов
/ 04 ноября 2018

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

Адреса, полученные на виртуальной машине под управлением Arch Linux с помощью команды readelf с опцией -W и --dyn-syms.

Причина, по которой я спрашиваю, состоит в том, что Мне интересно, можно ли использовать адрес шаблонной функции C ++ в качестве uuid для типа объекта. Это представляет интерес для моей подпрограммы сериализации, где я хотел бы нравится настраивать систему идентификаторов, которая является постоянной между компиляциями (типы объектов регистрируются статически во время инициализации, поэтому порядок не определен).

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

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

Это обеспечивается опциями GCC -fPIE (позиционно-независимый исполняемый файл), -fPIC (позиционно-независимый код), * ​​1009 *. Исполняемые файлы ELF могут быть скомпонованы как позиция зависимая или независимая , но общие объекты (библиотеки) будут всегда создаваться как позиция независимая как Вы должны иметь возможность загружать их в случайном месте, предоставленном вам ОС. Со страницы MAN в GCC:

-fPIC
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. 

-fpie
-fPIE
These options are similar to -fpic and -fPIC, but generated position independent code can be only linked into executables. Usually these options are used when -pie GCC option will be used during linking.

-pie
Produce a position independent executable on targets which support it. For predictable results, you must also specify the same set of options that were used to generate code (-fpie, -fPIE, or model suboptions) when you specify this option.

При загрузке общего объекта PIC вы не можете предполагать, что он будет находиться в одном и том же месте при каждом запуске, поскольку на него может влиять ASLR, управляемый ядром.

В любом случае, я не считаю хорошей практикой использовать адреса памяти в качестве uuids для классов, поскольку они могут измениться, даже в большей степени, если эти классы шаблонов реализованы как часть общего объекта.

0 голосов
/ 04 ноября 2018

Если процесс сборки не изменится (т.е. компилятор, компоновщик, файлы Makefile и код останутся прежними), адрес static в файле ELF также не изменится. Но если какой-либо компонент изменится, все ставки отключены.

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

...