Это урезанная версия этой проблемы я столкнулся на AArch64:Использования .reloc от сборки
Я этот макрос, который держит демпинг некоторых данных в раздел.
#define GEN_DATA(_type) \ .pushsection .mydata_##_type, "aw"; \ .ifndef start; \ start:; \ .endif; \ .word 1; \ .reloc end_loc, R_AARCH64_ABS64, .; \ .popsection
В конце концов я хотел, чтобы захватить начало и конец аналогичных типов в структуре, как это:
.pushsection .head, "aw" .quad start end_loc: .quad 0 .popsection
я могу отслеживать, где раздел начинается с start
символа. Я не знаю заранее, сколько вызовов GEN_DATA()
будет в сборке, поэтому я не могу определить end
. Я не знаю, сколько будет использовано _type
s раздела, поэтому нельзя помещать скрипт символа охраны. Поэтому я решил оставить запись о переезде для end_loc
, так что компоновщик в конечном итоге исправит место, где заканчивается весь раздел. Да, будет много записей о перемещении для того же end_loc
, но поскольку они являются абсолютными переселениями, я считаю, что они не конфликтуют.
У меня была догадка, но в финальной двоичной системе end_loc
исправляется с неправильным адресом. Я буду обвинять его в нескольких записях переноса, но странно, что все в порядке, если я также добавлю фиктивную дополнительную запись перемещения - I.e. Я изменяю структуры выше:
#define GEN_DATA(_type) \ .pushsection .mydata_##_type, "aw"; \ .ifndef start; \ start:; \ .endif; \ .word 1; \ .reloc end_loc, R_AARCH64_ABS64, .; \ .reloc dummy_loc, R_AARCH64_ABS64, .; \ .popsection
и:
.pushsection .head, "aw" .quad start end_loc: .quad 0 dummy_loc: .quad 0 .popsection
Вот и мне интересно:
Почему
end_loc
получение устроились неправильно? Что случилось с несколькими абзацами абсолютного переселения, если вообще? Разве линкер не должен идти через них по порядку, а последний вступает в силу?Почему просто добавление фиктивного перемещения делает все правильно?
В принципе, что происходит ?!
И, наконец, есть ли альтернативы, которые я мог бы попробовать?
EDIT: Я теперь нажал образец кода на Git repository. Используйте make
и make broken=1
для просмотра разборки. Потребности Linaro AArch64 tool chain в $PATH
.