почему такая разница? Почему 2 разных подхода?
То, что вы описали, является ленивым перемещением.
Вам не обязательно использовать его, и вы не будете его использовать, если, например. LD_BIND_NOW=1
установлен в среде.
Это оптимизация: она позволяет уменьшить объем работы, которую должен выполнять динамический компоновщик, когда конкретный вызов программы не использует множество возможных путей выполнения программы.
Представьте себе программу, которая может вызывать foo()
, bar()
или baz()
, в зависимости от аргументов, и которая вызывает точно одну из подпрограмм в любом заданном выполнении.
Если бы вы не использовали отложенное перемещение, динамический загрузчик должен был бы разрешить все 3 подпрограммы при запуске программы. Ленивая релокация позволяет динамическому загрузчику выполнять только одну релокацию, которая действительно требуется в каждом заданном выполнении (вызываемая одна функция), и точно в нужное время (когда функция вызывается).
Почему же переменные не могут быть разрешены таким же образом?
Потому что у динамического загрузчика нет удобного способа узнать, когда выполнять это перемещение.
Предположим, что глобальными переменными являются a
, b
и c
, и что foo()
ссылается на a
и b
, bar()
ссылается на b
и c
, а baz()
ссылается на a
и c
. Теоретически динамический загрузчик может сканировать тела foo
, bar
и baz
и строить карту "при вызове foo
, то также разрешать глобальные переменные a
и b
" и т. д. Но гораздо проще и быстрее просто разрешать все ссылки на глобальные переменные в запускать.
person
Employed Russian
schedule
29.05.2018