2015-08-20 3 views
1

По причинам, я хочу, чтобы некоторые записи в секции PLT. Мне удалось сделать это для некоторых записей, однако некоторые функции никогда не вставлены в PLT.Ввод записей в разделе PLT

так, позволяет сказать, что у меня есть main.c:

int main(){ 
// some code 
strcmp(a,b); //suppose a, b strings 
// more code 
// suppose that result of strcmp is used, so it won't be optimised away 
} 

и help.c:

// declaration 
void forceplt() __attribute__((__used__)); 
// definition 
void forceplt(){ 
abs(-1); 
__aeabi_dadd(0, 0); 
} 

Затем я скомпилировать и скомпоновать выше двух перемещаемых объектов, в исполняемый объект. Чтобы убедиться, что функции abs и dadd останутся в секции PLT, я компилирую helper.o с использованием -O0. main.o может быть скомпилирован с более высоким уровнем, скажем, `-O1 '.

На исполняемом объекте я ожидаю увидеть записи всех трех функций: strcmp, abs и dadd. Однако, это не так.

Я что-то упустил? Возможно ли, что компоновщик пропускает некоторые вещи, потому что он выясняет, что их никогда не называют? Несмотря на использование O0 для помощника и используемый атрибут для функции forceplt?

Помогите мне сделать правильный праздник .. десять. млн. вопросов!

Cheers!

ответ

2

abs и strcmp признаны специально GCC, и, похоже, компилятор выясняет, что эти звонки бесполезны даже в -O0. Если вы посмотрите на сборку сборки (gcc foo.c -S -o-), вы увидите, что соответствующей инструкции вызова нет.

Записи PLT не генерируются компилятором: их нет в файлах .o. Они генерируются редактором ссылок, когда они находят соответствующее перемещение в одном из своих файлов .o. Чтобы создать запись PLT, вам необходимо создать подходящую запись перемещения в одном из ваших файлов .o. A .o перемещение всегда применяется к части раздела файла .o: вам нужно иметь несколько байтов памяти в некотором разделе некоторого .o, что вы переместитесь с перемещением, поддерживающим PLT. Это может быть либо (возможно, бесполезная) инструкция, либо некоторые (возможно, бесполезные) байты.

Решение состоит в том, чтобы создавать (в сборе) инструкции, в которых явно используются ожидаемые записи PLT. С x86_64 это может быть сделано с:

.text 
    .type forceplt2,@function 
forceplt2: 
    callq [email protected] 

Я предполагаю, что это написано, как это в ARM:

.text 
    .type forceplt2,%function 
forceplt2: 
    bl [email protected] 

Или вы можете генерировать исходные байты для вашего переезда (на x86_64 снова):

.data 
    .align 8 
    .type forceplt3, @object 
    .size forceplt3, 8 
forceplt3: 
    .quad [email protected] 

On x_86_64, вы должны быть в состоянии использовать либо @GOT, @GOTPLT, @GOTOFF, @GOTPCREL, @PLT или @PLTOFF. Я не уверен, как это должно быть написано for ARM.

Любое из этих решений выдаст подходящую запись перемещения, которая заставит редактор ссылок испустить запись PLT и запись PLT GOT.

Смежные вопросы