compilación gcc y archivos de objeto

1 Conceptos básicos

Compilación gcc 4 etapas: preprocesamiento, compilación, ensamblaje, vinculación

Preprocesamiento (cpp): procesamiento de archivos de cabecera, definiciones de macros, compilación condicional, etc .;
compilación (ccl): inspección de código, generación de archivos ensamblados .s;
ensamblado (as): generación de símbolos relocables (globales, funciones externas, etc.). o Archivo objeto;
proceso de enlace (ld): Combina todos los códigos y datos en un solo archivo, que se puede cargar en la memoria para su ejecución.

1.1 Tipo de proceso de enlace

Vinculación en tiempo de compilación: vinculación a bibliotecas estáticas y archivos de objetos reubicables durante el proceso de compilación de archivos ejecutables
Vinculación en tiempo de carga: vinculación a bibliotecas dinámicas en tiempo de ejecución, cuando se cargan en la memoria para su ejecución por el cargador.
Vinculación en tiempo de ejecución: para bibliotecas dinámicas, el programa de aplicación carga dinámicamente archivos de biblioteca, funciones relacionadas como dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym. La interfaz nativa de Java sirve para vincular y cargar dinámicamente la biblioteca de vínculos dinámicos generada por la compilación C / C ++ a través de la vinculación en tiempo de ejecución.

1.2 Formato de archivo de destino

Archivos de objeto reubicables: archivos de objeto .o compilados y ensamblados, reubicables;
archivos de objeto ejecutables: archivos de objeto ejecutables binarios, archivos bin después de la vinculación estática
Archivos de objetos compartidos: biblioteca de vínculos dinámicos

2 ejemplo de proceso de compilación de Gcc

2.1 Código de muestra

Tres archivos
add.h file content:
int add (int a, int b);
add.c file content:
int add (int a, int b)
{ return a + b; } main.c file content: #include " add.h " int a = 1; int b = 2;





int main ()
{ int res = agregar (a, b); }

2.2 Pretratamiento

2.2.1 main.i

gcc -E main.c -o main.i
genera el archivo main.i después de preprocesar main.c

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 1 "add.h" 1
int add(int a,int b);
# 2 "main.c" 2
int a = 1;
int b = 2;

int main()
{
    
    
 int res=add(a,b);
}

2.2.2 add.i

# 1 "add.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "add.c"
int add(int a,int b)
{
    
    
 return a+b;
}

2.3 Compilar

2.3.1 main.s

cc1 -m32 main.i -o main.s
genera un archivo de ensamblaje main.s
Observaciones:
1. Compile aquí con 32 bits
2. Si no se puede encontrar el comando de línea, la razón es que el directorio donde se encuentra cc1 no está en la variable de entorno $ PATH. Utilice rutas absolutas, como /usr/lib/gcc/x86_64-linux-gnu/4.8.4/cc1 -m32 main.i -o main.s
3. El tercer carácter de cc1 es el número 1, no la letra l

	.file	"main.i"
	.globl	a
	.data
	.align 4
	.type	a, @object
	.size	a, 4
a:
	.long	1
	.globl	b
	.align 4
	.type	b, @object
	.size	b, 4
b:
	.long	2
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	b(%rip), %edx
	movl	a(%rip), %eax
	movl	%edx, %esi
	movl	%eax, %edi
	call	add
	movl	%eax, -4(%rbp)
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"
	.section	.note.GNU-stack,"",@progbits
2.3.2	add.s
	.file	"add.i"
	.text
	.globl	add
	.type	add, @function
add:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	movl	12(%ebp), %eax
	movl	8(%ebp), %edx
	addl	%edx, %eax
	popl	%ebp
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE0:
	.size	add, .-add
	.ident	"GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"
	.section	.note.GNU-stack,"",@progbits

2.4 Montaje y desmontaje

como --32 -o main.o main.s
genera un archivo de objeto reubicable main.o

2.4.1 main.o

Este archivo no es fácil de ver directamente con cat, y se mostrarán un montón de caracteres confusos.
Inserte la descripción de la imagen aquí

Puede usar objdump para ver las opciones del comando de desmontaje:
objdump -dx main.o
-d: desensamblaje
-x: mostrar todos los
resultados del comando de encabezado se muestran de la siguiente manera:

main.o:     file format elf32-i386
main.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000026  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  00000000  00000000  0000005c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000064  2**0
                  ALLOC
  3 .comment      0000002c  00000000  00000000  00000064  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  00000000  00000000  00000090  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000038  00000000  00000000  00000090  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
00000000 l    df *ABS*	00000000 main.i
00000000 l    d  .text	00000000 .text
00000000 l    d  .data	00000000 .data
00000000 l    d  .bss	00000000 .bss
00000000 l    d  .note.GNU-stack	00000000 .note.GNU-stack
00000000 l    d  .eh_frame	00000000 .eh_frame
00000000 l    d  .comment	00000000 .comment
00000000 g     O .data	00000004 a
00000004 g     O .data	00000004 b
00000000 g     F .text	00000026 main
00000000         *UND*	00000000 add



Disassembly of section .text:

00000000 <main>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	83 e4 f0             	and    $0xfffffff0,%esp
   6:	83 ec 20             	sub    $0x20,%esp
   9:	8b 15 00 00 00 00    	mov    0x0,%edx
			b: R_386_32	b
   f:	a1 00 00 00 00       	mov    0x0,%eax
			10: R_386_32	a
  14:	89 54 24 04          	mov    %edx,0x4(%esp)
  18:	89 04 24             	mov    %eax,(%esp)
  1b:	e8 fc ff ff ff       	call   1c <main+0x1c>
			1c: R_386_PC32	add
  20:	89 44 24 1c          	mov    %eax,0x1c(%esp)
  24:	c9                   	leave  
  25:	c3                   	ret    

2.4.2 add.o

main.o:     file format elf32-i386
main.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000026  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  00000000  00000000  0000005c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000064  2**0
                  ALLOC
  3 .comment      0000002c  00000000  00000000  00000064  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  00000000  00000000  00000090  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000038  00000000  00000000  00000090  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
00000000 l    df *ABS*	00000000 main.i
00000000 l    d  .text	00000000 .text
00000000 l    d  .data	00000000 .data
00000000 l    d  .bss	00000000 .bss
00000000 l    d  .note.GNU-stack	00000000 .note.GNU-stack
00000000 l    d  .eh_frame	00000000 .eh_frame
00000000 l    d  .comment	00000000 .comment
00000000 g     O .data	00000004 a
00000004 g     O .data	00000004 b
00000000 g     F .text	00000026 main
00000000         *UND*	00000000 add



Disassembly of section .text:

00000000 <main>:
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	83 e4 f0             	and    $0xfffffff0,%esp
   6:	83 ec 20             	sub    $0x20,%esp
   9:	8b 15 00 00 00 00    	mov    0x0,%edx
			b: R_386_32	b
   f:	a1 00 00 00 00       	mov    0x0,%eax
			10: R_386_32	a
  14:	89 54 24 04          	mov    %edx,0x4(%esp)
  18:	89 04 24             	mov    %eax,(%esp)
  1b:	e8 fc ff ff ff       	call   1c <main+0x1c>
			1c: R_386_PC32	add
  20:	89 44 24 1c          	mov    %eax,0x1c(%esp)
  24:	c9                   	leave  
  25:	c3                   	ret    

2.5 Enlace

ld -m elf_i386 -o main main.o add.o

2.6 Resumen de comandos relacionados

cpp main.c main.i
cc1 main.i -o main.s
como --32 -o main.o main.s
objdump -dx main.o> main.o.txt

cpp add.c add.i /usr/lib/gcc/x86_64-linux-gnu/4.8.4/cc1
-m32 add.i -o add.s
as --32 -o add.o add.s
objdump -dx add.o> add.o.txt

链接 :
ld -m elf_i386 -o main main.o add.o

Observación: la ruta de la versión utilizada por el comando
cc1 /usr/lib/gcc/x86_64-linux-gnu/4.8.4/ cc1

3 Análisis de archivos ejecutables

3.1 Disposición del espacio de archivos ELF ejecutable

Inserte la descripción de la imagen aquí

3.2 Descompilación de archivos ejecutables

objdump -dx principal

3.2.1 Información básica del archivo

main: formato de archivo elf32-i386 arquitectura
principal
: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
dirección de inicio 0x08048094

3.2.2 Información de la tabla de encabezado del programa

Programa Header:
la PADDR LOAD OFF 0x08048000 0x08048000 0x00000000 vaddr align = left 2 12 es
filesz 0x00000120 0x00000120 las banderas RX MEMSZ
la carga de PADDR 0x08049120 0x08049120 0x00000120 vaddr align = left 2
12 es
filesz 0x00000008 0x00000008 MEMSZ las banderas rw-
STACK OFF vaddr 0x00000000 0x00000000 0x00000000 align = PADDR izquierda 2 ** 4.
Filesz 0x00000000 memsz 0x00000000 flags rw-
Descripción:
Off: Offset en el archivo de destino
Vadd / paddr: Dirección de memoria
Alinear: Requisitos de alineación
Filesz: Tamaño de segmento en el archivo de destino
Memsz: Tamaño de segmento en la memoria
Flags: Derechos de acceso en tiempo de ejecución

3.2.3 Información por segmentos

Secciones:
Idx Nombre Tamaño VMA LMA Archivo desactivado Algn
0 .text 00000033 08048094 08048094 00000094 2 0
CONTENIDO, ASIGNAR, CARGAR, SOLO LECTURA, CÓDIGO
1 .eh_frame 00000058 080480c8 080480c8 000000c8 2
2
CONTENIDO, ASIGNAR, CARGAR, SÓLO LECTURA 0000 DATOS
. 08049120 08049120 00000120 2 2
CONTENIDO, ASIGNACIÓN, CARGA, DATOS
3 .comentario 0000002b 00000000 00000000 00000128 2
0
CONTENIDO, SOLO LECTURA

3.2.4 Información de la tabla de símbolos

Símbolo de la tabla:
08048094 ld .text 00000000 .text
080480c8 ld .eh_frame 00000000 .eh_frame
08049120 ld .data 00000000 .data
00000000 ld .comment 00000000 .comment
00000000 l df ABS 00000000 main.i
00000000 l df ABS 00000000 Add.I
00000000 l df ABS 00000000
08049124 g O .data 00000004 b
080480ba g F .text 0000000d add
00000000 UND 00000000 _start
08049128 g .data 00000000 __bss_start
08048094 g F .text 00000026 principal
08049128 g .data 00000000 _edata
08049128 g .data 00000000 _edata
08049128 g .data 00000000 _edata . 00000004 a

3.2.5 Información de desmontaje

Desmontaje de la sección .text:

08048094:
8048094: 55 push% ebp
8048095: 89 e5 mov% esp,% ebp
8048097: 83 e4 f0 y $ 0xfffffff0,% esp
804809a: 83 ec 20 sub $ 0x20,% esp
804809d: 8b 15 24 91 04 08 mov 0x8049124 ,% edx
80480a3: a1 20 91 04 08 mov 0x8049120,% eax
80480a8: 89 54 24 04 mov% edx, 0x4 (% esp)
80480ac: 89 04 24 mov% eax, (% esp)
80480af: e8 06 00 00 00 llamar 80480ba
80480b4: 89 44 24 1c mov% eax, 0x1c (% esp)
80480b8: c9 dejar
80480b9: c3 ret

080480ba:
80480ba: 55 push% ebp
80480bb: 89 e5 mov% esp,% ebp
80480bd: 8b 45 0c mov 0xc (% ebp),% eax
80480c0: 8b 55 08 mov 0x8 (% ebp),% edx
80480c3: 01 d0 agregar% edx,% eax
80480c5: 5d pop% ebp
80480c6: c3 ret

4 Cargar archivo de objeto ejecutable

4.1 Mapeo de memoria en tiempo de ejecución

Inserte la descripción de la imagen aquí

5 Referencia

1. "Comprensión en profundidad de los sistemas informáticos", [Estados Unidos] Randal E. Bryant, David R. O'Hallaron
, tercera edición, marzo de 2019, China Machinery Industry Press,

Supongo que te gusta

Origin blog.csdn.net/skytering/article/details/105877054
Recomendado
Clasificación