compilation gcc et fichiers objets

1 Concepts de base

Compilation Gcc 4 étapes: prétraitement, compilation, assemblage, liaison

Prétraitement (cpp): traitement des fichiers d'en-tête, définitions de macros, compilation conditionnelle, etc .;
compilation (ccl): inspection de code, génération de fichiers d'assemblage .s;
assemblage (as): génération de repositionnables (symboles globaux, fonctions externes, etc.). o Fichier objet;
processus de liaison (ld): combinez tout le code et les données dans un seul fichier, qui peut être chargé en mémoire pour exécution.

1.1 Type de processus de liaison

Liaison à la compilation: liaison vers des bibliothèques statiques et des fichiers objets relocalisables lors du processus de compilation des fichiers exécutables
Liaison au moment du chargement: liaison vers des bibliothèques dynamiques à l'exécution, lorsqu'elles sont chargées en mémoire pour exécution par le chargeur.
Liaison d'exécution: pour les bibliothèques dynamiques, le programme d'application charge dynamiquement les fichiers de bibliothèque, les fonctions associées telles que: dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym. L'interface native Java consiste à lier et à charger dynamiquement la bibliothèque de liens dynamiques générée par la compilation C / C ++ via la liaison d'exécution.

1.2 Format de fichier cible

Fichiers objets déplaçables: fichiers objets .o compilés et assemblés, déplaçables;
fichiers objets exécutables: fichiers objets exécutables binaires, fichiers bin après liaison statique
Fichiers objets partagés: bibliothèque de liens dynamiques

2 Exemple de processus de compilation Gcc

2.1 Exemple de code

Trois fichiers
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 = add (a, b); }

2.2 Prétraitement

2.2.1 main.i

gcc -E main.c -o main.i
génère le fichier main.i après le prétraitement 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 Compiler

2.3.1 main.s

cc1 -m32 main.i -o main.s
génère le fichier d'assemblage main.s
Remarques:
1. Compilez ici avec 32 bits
2. Si la commande prompt est introuvable, la raison est que le répertoire où se trouve cc1 n'est pas dans la variable d'environnement $ PATH. Utilisez des chemins absolus, tels que /usr/lib/gcc/x86_64-linux-gnu/4.8.4/cc1 -m32 main.i -o main.s
3. Le troisième caractère de cc1 est le chiffre 1, pas la lettre 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 Montage et démontage

as --32 -o main.o main.s
génère un fichier objet relocalisable main.o

2.4.1 main.o

Ce fichier n'est pas facile à visualiser directement avec chat, et un tas de caractères déformés sera affiché.
Insérez la description de l'image ici

Vous pouvez utiliser objdump pour afficher les options de la commande de désassemblage:
objdump -dx main.o
-d: disassembly
-x: afficher tous les
résultats de la commande d'en- tête sont affichés comme suit:

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 Lien

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

2.6 Résumé des commandes associées

cpp main.c main.i
cc1 main.i -o main.s
comme --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

Remarque: Le chemin de version utilisé par la commande
cc1 /usr/lib/gcc/x86_64-linux-gnu/4.8.4/ cc1

3 Analyse des fichiers exécutables

3.1 Disposition de l'espace fichier ELF exécutable

Insérez la description de l'image ici

3.2 Décompilation des fichiers exécutables

objdump -dx main

3.2.1 Informations de base sur les fichiers

main: format de fichier elf32-i386 architecture
principale
: i386, indicateurs 0x00000112:
EXEC_P, HAS_SYMS,
adresse de départ D_PAGED 0x08048094

3.2.2 Informations du tableau des en-têtes de programme

Programme en- tête:
OFF CHARGE PADDR 0x08048000 0x08048000 0x00000000 vaddr align = left 2 12 est
filesz 0x00000120 0x00000120 les drapeaux RX MEMSZ
la charge OFF PADDR 0x08049120 0x08049120 0x00000120 vaddr align = left 2
12 est
filesz 0x00000008 0x00000008 MEMSZ les drapeaux
STACK OFF de vaddr 0x00000000 0x00000000 0x00000000 align = PADDR gauche 2 ** 4.
Filesz 0x00000000 memsz 0x00000000 flags rw-
Description:
Off: Décalage dans le fichier cible
Vadd / paddr: Adresse mémoire
Alignement: Exigences d'alignement
Filesz: Taille du segment dans le fichier cible
Memsz: Taille du segment dans la mémoire Indicateurs:
Droits d'accès à l' exécution

3.2.3 Informations sectorielles

Sections:
Idx Nom Taille VMA LMA File off Algn
0 .text 00000033 08048094 08048094 00000094 2 0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .eh_frame 00000058 080480c8 080480c8 000000c8 2
2
CONTENTS, ALLOC, LOAD DATA, READONLY,
00000008 2. 08049120 08049120 00000120 2 2
CONTENU, ALLOC, LOAD, DATA
3 .comment 0000002b 00000000 00000000 00000128 2
0
CONTENU, LECTURE UNIQUEMENT

3.2.4 Informations sur le tableau des symboles

TABLEAU
DES SYMBOLES : 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.i df ABS 00000000 main.i
00000000 l.i df 00000000 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 main
08049128 g .data 00000000 _edend
0804900001 g .data 00000000 _edend 080490000120 g .data 00000000
_edend 080490000120 g .data 00000004 a

3.2.5 Informations de démontage

Démontage de la section .text:

08048094:
8048094: 55 push% ebp
8048095: 89 e5 mov% esp,% ebp
8048097: 83 e4 f0 et $ 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 appeler 80480ba
80480b4: 89 44 24 1c mov% eax, 0x1c (% esp)
80480b8: c9 quitter
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 ajouter% edx,% eax
80480c5: 5d pop% ebp
80480c6: c3 ret

4 Charger le fichier objet exécutable

4.1 Mappage de la mémoire d'exécution

Insérez la description de l'image ici

5 Référence

1. "Compréhension approfondie des systèmes informatiques", [États-Unis] Randal E. Bryant, David R. O'Hallaron
, 3e édition, mars 2019, China Machinery Industry Press,

Je suppose que tu aimes

Origine blog.csdn.net/skytering/article/details/105877054
conseillé
Classement