Minimal Linux IA-32 esempio che illustra il suo utilizzo
main.S:
.section .text
.global _start
_start:
/* Dummy access so that after will be referenced and kept. */
mov after, %eax
/*mov keep, %eax*/
/* Exit system call. */
mov $1, %eax
/* Take the exit status 4 bytes after before. */
mov $4, %ebx
mov before(%ebx), %ebx
int $0x80
.section .before
before: .long 0
/* TODO why is the `"a"` required? */
.section .keep, "a"
keep: .long 1
.section .after
after: .long 2
collegamento.ld:
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text :
{
*(.text)
*(.before)
KEEP(*(.keep));
*(.keep)
*(.after)
}
}
Compilare ed eseguire:
as --32 -o main.o main.S
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o
./main.out
echo $?
uscita:
1
Se noi commentare la riga KEEP
l'output è:
2
Se ci sia:
- Aggiungiamo un manichino
mov keep, %eax
- rimuovere
--gc-sections
L'uscita risale al 1
.
Testato su Ubuntu 14.04, Binutils 2.25.
Spiegazione:
Non v'è alcun riferimento al simbolo keep
, e quindi la sua contenenti sezione .keep
.
Pertanto, se la garbage collection è abilitata e non si utilizza KEEP
per fare un'eccezione, quella sezione non verrà inserita nell'eseguibile.
Poiché stiamo aggiungendo 4 all'indirizzo di before
, se la sezione keep
non è presente, allora lo stato di uscita sarà 2
, che è presente sulla sezione successiva .after
.
TODO: non succede nulla se rimuoviamo il "a"
da .keep
, che lo rende allocabile. Non capisco perché sia così: quella sezione verrà inserita nel segmento .text
, che a causa del suo nome magico sarà allocabile.
fonte
2015-10-08 10:44:42
KEEP è documentato in [questo] (https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep) versione del manuale. – alexei