2016-12-26 24 views
3

Это урезанная версия этой проблемы я столкнулся на 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.

ответ

0

Я не знаю, что происходит с переездами, но самый простой способ сделать то, что вы пытаетесь выполнить, - использовать скрипт компоновщика. Это позволит вам объединить все разделы .mydata_XXX_type и предоставить символы для начала и конца сгруппированных разделов. Что-то вроде этого:

SECTIONS 
{ 
    .mydata : 
    { 
     start = .; 
     *(.mydata*); 
     end_loc = .; 
    } 
} 

Что вы будете использовать с файлом сборки, как это:

.macro gen_data, type 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

(я использовал ассемблер макросы вместо макросов C, потому что они гораздо легче работать.) Вы бы использовать две вышеуказанные файлы, как это:

as -o test.o test.s 
    ld -o test test.o test.ld 

Если вы знаете все возможные раздел «типы», то вы делаете это без использования линкера сценарий, опираясь на тот факт, компоновщик помещает неизвестные участки в прикажите сначала встретиться с ними. Например:

.section .mydata_start, "aw" 
start: 
    .section .mydata_foo_type, "aw" 
    .section .mydata_bar_type, "aw" 
    .section .mydata_baz_type, "aw" 
    .section .mydata_end, "aw" 
end_loc: 

    .macro gen_data, type 
    .ifndef .mydata_\()\type\()_type 
    .error "gen_data invoked with unknown type '\type\()'" 
    .endif 
    .pushsection .mydata_\()\type\()_type, "aw" 
    .word 1 
    .popsection 
    .endm 

    .text 
    gen_data foo 
    gen_data bar 
    gen_data baz 
    # gen_data unk 

    .section .head, "aw" 
    .quad start 
    .quad end_loc 

Если у вас есть несколько файлов ассемблера с помощью макроса убедитесь, что все ассемблерные файлы включают .section директивы, указанные выше в начале, так что не имеет значения, в каком порядке они появляются в командной строке компоновщика ,

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