en archivos de objeto.
Los archivos de objeto son efectivamente un paso intermedio antes de la salida ejecutable final (generada por el enlazador).
El vinculador toma los archivos de objeto y las bibliotecas especificadas (que son paquetes de archivos de objeto) y resuelve los registros de reubicación (o 'corrección').
Estos registros de reubicación se realizan cuando el compilador/ensamblador no conoce la dirección de una función o variable utilizada en el código fuente, y genera una referencia para ello por nombre, que puede ser resuelta por el vinculador.
Por ejemplo, supongamos que desea un programa para imprimir un mensaje a la pantalla, separado en dos archivos de origen, y que desea ensamblarlos por separado y unirlas (ejemplo usando Linux x86-64 llamadas al sistema) -
main.asm:
bits 64
section .text
extern do_message
global _start
_start:
call do_message
mov rax, 1
int 0x80
message.asm:
bits 64
section .text
global do_message
do_message:
mov rdi, message
mov rcx, dword -1
xor rax, rax
repnz scasb
sub rdi, message
mov rax, 4
mov rbx, 1
mov rcx, message
mov rdx, rdi
int 0x80
ret
section .data
message: db "hello world",10,0
Si el montaje de estos y buscar a la salida del fichero objeto de main.asm (por ejemplo, objdump -d main.o), se le no Por ejemplo, 'call do_message' tiene una dirección de 00 00 00 00, que no es válida.
0000000000000000 <_start>:
0: e8 00 00 00 00 callq 5 <_start+0x5>
5: 48 c7 c0 01 00 00 00 mov $0x1,%rax
c: cd 80 int $0x80
embargo, un registro de reubicación se hace para los 4 bytes de la dirección:
$ objdump -r main.o
main.o: file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000000000000001 R_X86_64_PC32 do_message+0xfffffffffffffffc
000000000000000d R_X86_64_32 .data
el desplazamiento es '1' y el tipo es 'R_X86_64_PC32' que le dice al enlazador para resolver esta referencia y coloque la dirección resuelta en el desplazamiento especificado.
Cuando se vincula el programa final con 'ld -o programa main.o message.o', las deslocalizaciones se resuelven, y si no se resuelve nada, se queda con un ejecutable.
Cuando estamos objdump -d 'el ejecutable, podemos ver la dirección resuelta:
00000000004000f0 <_start>:
4000f0: e8 0b 00 00 00 callq 400100 <do_message>
4000f5: 48 c7 c0 01 00 00 00 mov $0x1,%rax
4000fc: cd 80 int $0x80
El mismo tipo de reubicaciones se utilizan para las variables, así como funciones. El mismo proceso ocurre cuando vincula su programa con múltiples bibliotecas grandes, como libc - usted define una función llamada 'main' a la cual libc tiene una referencia externa - entonces libc se inicia antes de su programa y llama a su función 'main' cuando ejecutas el ejecutable
En realidad no necesariamente 1: 1 –