Exemple minimal de Linux IA-32 qui illustre son utilisation
principal.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
lien.ld
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text :
{
*(.text)
*(.before)
KEEP(*(.keep));
*(.keep)
*(.after)
}
}
Compilez et exécutez :
as --32 -o main.o main.S
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o
./main.out
echo $?
Sortie :
1
Si nous commentons le KEEP
la sortie est :
2
Si on est soit :
- ajouter un mannequin
mov keep, %eax
- supprimer
--gc-sections
La sortie retourne à 1
.
Testé sur Ubuntu 14.04, Binutils 2.25.
Explication
Il n'y a aucune référence au symbole keep
et, par conséquent, la section qu'il contient .keep
.
Par conséquent, si le garbage collection est activé et que nous n'utilisons pas de KEEP
pour faire une exception, cette section ne sera pas mise dans l'exécutable.
Puisque nous ajoutons 4 à l'adresse de before
si le keep
n'est pas présente, alors l'état de sortie sera 2
qui est présent sur le prochain .after
section.
TODO : rien ne se passe si on supprime le "a"
de .keep
ce qui le rend allouable. Je ne comprends pas pourquoi il en est ainsi : cette section sera placée dans la section .text
qui, en raison de son nom magique, sera allouable.
8 votes
KEEP est documenté dans ce version du manuel.