traductor traducir significado significa script que para pagina ingles idioma español codigo cambiar boton atributo linker ld linker-scripts

linker - traducir - ¿Qué significa KEEP en un script de enlazador?



script significado español (2)

Afaik LD mantiene los símbolos en la sección incluso si no se hace referencia a los símbolos. (--gc-secciones).

Usualmente 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 a continuación)

Árbol de dependencia :

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

Así que eliges una sección, la marcas como "usada" y ves a qué otra sección hace referencia, luego marcas esa sección como "usada", y verificas a qué se refieren, etc.

La sección que no está marcada como "utilizada" es redundante y puede eliminarse.

Como una sección puede hacer referencia a otras secciones múltiples (por ejemplo, un procedimiento llamando a otras tres diferentes), si dibuja el resultado obtendrá un árbol.

Roots:

Sin embargo, el principio anterior nos deja con un problema: ¿cuál es la "primera" sección 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 en.

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 formato de archivo / SO) y el punto de entrada del programa.

El manual LD no explica qué hace el comando KEEP . A continuación se muestra un fragmento de un script de enlazador de terceros que presenta 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


Ejemplo de Linux IA-32 mínimo 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 muñeco 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 contiene .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 colocará en el ejecutable.

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

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