¿Qué significa MANTENER en un script enlazador?


El manual LD no explica lo que hace el comando KEEP. A continuación se muestra un fragmento de un script enlazador de terceros que cuenta con KEEP. ¿Qué hace el comando KEEP en ld?

SECTIONS
{  
    .text :
    {
        . = ALIGN(4);
        _text = .;
        PROVIDE(stext = .);
        KEEP(*(.isr_vector))
        KEEP(*(.init))
        *(.text .text.*)        
        *(.rodata .rodata.*)        
        *(.gnu.linkonce.t.*)
        *(.glue_7)
        *(.glue_7t)
        *(.gcc_except_table)
        *(.gnu.linkonce.r.*)
        . = ALIGN(4);
        _etext = .;
        _sidata = _etext;
        PROVIDE(etext = .);   
            _fini = . ;
                *(.fini)

    } >flash
Author: Randomblue, 2012-03-22

2 answers

Afaik LD mantiene los símbolos en la sección incluso si los símbolos no están referenciados. (gc gc-sections).

Generalmente se usa para secciones que tienen algún significado especial en el proceso de inicio binario, más o menos para marcar las raíces del árbol de dependencias.


(Para Sabuncu más abajo)

Árbol de dependencias :

Si elimina el código no utilizado, analiza el código y marca todas las secciones accesibles (código+variables globales + constantes).

Así que elige una sección, márquelo como" usado "y vea a qué otra sección hace referencia, luego marque esas secciones como" usado " y verifique a qué hacen referencia, etc.

Las secciones que no están marcadas como "usadas" son redundantes y pueden ser eliminadas.

Dado que una sección puede hacer referencia a varias otras secciones (por ejemplo, un procedimiento que llama a tres otras diferentes), si dibujas el resultado, obtienes un árbol.

Raíces:

El principio anterior sin embargo nos deja con un problema: lo que es ¿la sección" primera " que siempre se usa? El primer nodo raíz del árbol, por así decirlo? Esto es lo que hace "keep ()", le dice al enlazador qué secciones (si están disponibles) son las primeras en mirar. Como consecuencia, estos siempre están vinculados.

Normalmente estas son secciones que se llaman desde el cargador de programa para realizar tareas relacionadas con la vinculación dinámica (puede ser opcional, y depende del OS/formato de archivo), y el punto de entrada del programa.

 40
Author: Marco van de Voort,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-29 17:01:15

Ejemplo mínimo de Linux IA-32 que ilustra su uso

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

Link.ld :

ENTRY(_start)
SECTIONS
{
    . = 0x400000;
    .text :
    {
        *(.text)
        *(.before)
        KEEP(*(.keep));
        *(.keep)
        *(.after)
    }
}

Compilar y ejecutar:

as --32 -o main.o main.S
ld --gc-sections -m elf_i386 -o main.out -T link.ld main.o
./main.out
echo $?

Salida:

1

Si comentamos la línea KEEP la salida es:

2

Si nosotros:

  • añadir un maniquí mov keep, %eax
  • eliminar --gc-sections

La salida vuelve a 1.

Probado en Ubuntu 14.04, Binutils 2.25.

Explicación:

No hay referencia al símbolo keep, y por lo tanto su sección contenedora .keep.

Por lo tanto, si la recolección de basura está habilitada y no usamos KEEP para hacer una excepción, esa sección no se pondrá en el ejecutable.

Dado que estamos agregando 4 a la dirección de before, si la sección keep no está presente, entonces el estado de salida será 2, que está presente en la siguiente .after apartado.

TODO: no pasa nada si eliminamos el "a" de .keep, lo que lo hace asignable. No entiendo por qué es así: esa sección se pondrá dentro del segmento .text, que debido a su nombre mágico será asignable.

 9
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-08 10:58:08