• Nenhum resultado encontrado

Compilação, Amarração e Relocação

N/A
N/A
Protected

Academic year: 2021

Share "Compilação, Amarração e Relocação"

Copied!
12
0
0

Texto

(1)

Compilação, Amarração e

Relocação

Desenvolvimento modular

• Programas grandes devem ser implementados de forma modular

– Limitam a complexidade de manutenção do código

– Mudança em um módulo não requer a re-compilação de todo o programa

– Módulos comuns podem ser disponibilizados em bibliotecas

• Cada módulo:

– define uma coleção símbolos que representam tipos, constantes, variáveis e procedimentos, e , p ,

– referencia outros símbolos de outros módulos

• O compilador gera código objeto para cada módulo, e o amarrador (linker) junta os objetos em um executável.

(2)

O processo completo

O driver de compilador (gcc) invoca cada uma das etapas: pré-processador (cpp), compilador(cc1),

assembler (as) e linker(ld), para gerar o executável (para ver as etapas use gcc –v ) executável (para ver as etapas, use gcc v ... )

Li k (ld) ccp, cc1, as m.c m.o ccp, cc1, as a.c

a.o Arquivos objeto relocáveis (endereços relativos ao

início do arquivo)

Linker (ld)

p Arquivo objeto executável (com todos dados e procedimentos definidos em

m.c and a.c)

Obs: arquivos objeto (.o) não podem ser executados, pois há referências não resolvidas e os endereços não são os definitivos.

Tarefas do processo de amarração

(linker)

1. Combina vários arquivos objeto relocáveis (.o) em um único arquivo executável, que pode ser carregado na memória e executado;

memória e executado;

2. Resolve todas as referências externas, isto é

referências a um símbolo definido em outro arquivo objeto

3. Faz a relocação de todos os símbolos

– Transforma endereços relativos em endereços absolutos no executável

– Atualiza todas as referências para estes símbolos para refletir i õ

suas novas posições

Obs:

• As referências podem ser para código ou dados

• Amarração poder ser feita em tempo de compilação (ld do Unix), tempo de carga ou de execução

(3)

Estrutura geral de um arquivo objeto

• Tabela de símbolos exportados • Tabela de referências externas • Código ( text)

• Código (.text)

• Dados incializados (.data)

– Exemplo: int x = 3;

• Dados não incializados

– Exemplo: int x;

• Dicionário de relocação (= tabela com as posições no código onde existe uma referência à memória)

código onde existe uma referência à memória) • Informação para o depurador (debugger)

Os formatos mais usados:

• ELF (Executable and Linkable Format) para sistemas Unix • PE (Portable Executable) para Windows

Formato ELF de arquivo objeto (1/2)

• Header ELF

– contém magic number, tipo (.o, exec, .so), arquitetura, big/little endian, etc.

ELF header Program header table (required for executables)

0

• Tabela de header de programas (para executáveis)

– Contém tamanho de página (para memória virtual), segmentos e seus tamanhos

• .text – código • .data

– Dados inicializados státicos (*)

( q ) .text section .data section .bss section .symtab .rel.txt .rel.data Dados inicializados státicos ( )

• .bss section

– Dados não incializados státicos – Não ocupa espaço (“Better Save

Space”)

.debug Section header table (required for relocatables)

(*) Lembre-se que variáveis dinâmicas, no corpo de procedimentos, são alocados na pilha de execução

(4)

Formato ELF de arquivo objeto (2/2)

• .symtab =Tabela de símbolos com:

– Nomes de procedimentos e variáveis estáticas

– Nomes de seções e posições

ELF header Program header table (required for executables)

0

Nomes de seções e posições • .rel.text

– Informação de relocação para seção .text

– Endereços das instruções que precisarão ser modificados no executável

• .rel.data

– Informação de relocação para seção data ( q ) .text section .data section .bss section .symtab .rel.text .rel.data seção.data

– Endereços dos enderços (ponteiros para dados) que precisarão ser modificados no executável

• .debug

– Seção que relaciona posições no arquivo objeto com linhas do código fonte; para depuração (gcc -g)

.debug Section header table (required for relocatables)

Amarração (Linker)

Principais tarefas (recapitulando)

1. combinar todos os objetos em um executável

2. Resolver as referências externas

3. Relocar as referências absolutas à memória

Vejamos usando um exempo:

int e=7; m.c a.c extern int e; int main() { int r = a(); exit(0); } int *ep=&e; int x=15; int y; int a() { return *ep+x+y; }

(5)

Combinação de todos os objetos

em um executável

headers 0

t d

Arquivos objeto relocáveis Arquivo executável

text main() m.o i 7 headers main() a() system code int e = 7 system data

more system code system data .text .text .data .text .data system code

int *ep = &e a() a.o

int e = 7 int *ep = &e int x = 15 int y int x = 15 .text .data .bss .symtab .debug .data uninitialized data .bss

A união requer a relocação dos endereços

em cada módulo de forma a acrescentar sua posição dentro da concatenação

Resolução de referências

– Cada símbolo (entidade léxica) possui um valor(=seu endereço de memória).

– Referências podem serReferências podem ser locaislocaisououexternas.externas.

int e=7; int main() { int r = a(); exit(0); } m.c a.c extern int e; int *ep=&e; int x=15; int y; i () { Def of local symbol e Ref to external symbol e Def of D f f int a() { return *ep+x+y; } Ref to external symbol exit (defined in libc.so) local symbol ep Defs of local symbols x and y Refs of local symbols ep,x,y Def of local symbol a Ref to external symbol a

(6)

Resolução de referências

• Objetivo: associar cada referência externa a

exatamente uma (1) definição do símbolo

• Usa a tabela de símbolo de cada módulo m que

Usa a tabela de símbolo de cada módulo m que

contém:

– Símbolos globais: definidos em m e que podem ser referenciados por outros módulos (funções e

variáveis não definidos com static)

– Símbolos referenciados por m, mas definidos em outro módulo

– Símbolos locais: definfidos e referenciadosSímbolos locais: definfidos e referenciados

exclusivamente por m (funções e variáveis definidos com static)

Obs: as tabelas de símbolos são criadas pelo

montador (as), usando os símbolos exportados

na etapa de compilação.

Resolução de referências

• Pode ser impossível:

– Se um símbolo referenciado não foi declarado

– Linker produz uma mensagem de erro (“undefined reference to ‘foo’)

• Pode ser ambígua:

– se existem várias definições para o mesmo símbolo em diferentes módulos

– Linker usa o conceito de símbolo forte e fraco (variáveis incializadas VS não inicializadas) e as seguintes regras:

• R1: não permite definição de >1 símbolos fortes • R2: se houver definição de 1 símbolo forte e vários

fracos, escolha a definição forte

• R3: se só houver definições de símbolos fracos, escolha qualquer uma (de a cordo com a ordem dos módulos)

(7)

Exemplos

Linker escolhe o x de foo3.c por ser forte, e resultado é “x= 15212”!

Linker escolhe qualquer um dos x (ambos fracos) e resultado pode ser igualmente inesperado!

Mais um erro de difícil detecção

Linker escolhe o x de foo5.c por ser forte, mas agora x de bar5.c ocupa 8 bytes, e f() sobre escreve y!

Resultado é “x= 0x80000000”

• Para identificar possíveis conflitos use flag

warn-common no gcc

(8)

Relocação

• É o processo (no ligador) de atribuir endereços

de carga às várias partes do programa:

Ajustando o código e dados ( text e data) para – Ajustando o código e dados (.text e .data) para

refletir os endereços designados e

– Levando em conta os endereços dos símbolos definidos em outros módulos

• Na resolução de referências, as posições são

calculadas com relação ao endereço 0 (zero),

que seria o início do código.

• Quando a relocação é feita as posições de

memória calculadas na etapa anterior

funcionarão como distâncias (offsets)

Informação de relocação de m.o

Disassembly of section .text:

00000000 <main>: 00000000 <main>: m.c 0: 55 pushl %ebp 1: 89 e5 movl %esp,%ebp 3: e8 fc ff ff ff call 4 <main+0x4> 4: R_386_PC32 a 8: 6a 00 pushl $0x0 a: e8 fc ff ff ff call b <main+0xb> b: R_386_PC32 exit f: 90 nop int e=7; int main() { int r = a(); exit(0); }

Disassembly of section .data: 00000000 <e>:

0: 07 00 00 00

(9)

Informação de Relocação de a.o

(.text)

a.c Disassembly of section .text:

extern int e; int *ep=&e; int x=15; int y; int a() { return *ep+x+y; } 00000000 <a>: 0: 55 pushl %ebp 1: 8b 15 00 00 00 movl 0x0,%edx 6: 00 3: R_386_32 ep 7: a1 00 00 00 00 movl 0x0,%eax 8: R_386_32 x c: 89 e5 movl %esp,%ebp e: 03 02 addl (%edx),%eax } 10: 89 ec movl %ebp,%esp 12: 03 05 00 00 00 addl 0x0,%eax 17: 00 14: R_386_32 y 18: 5d popl %ebp 19: c3 ret

Informação de Relocação de a.o

(.data)

a.c extern int e; int *ep=&e; int x=15; int y; int a() { return *ep+x+y;

Disassembly of section .data: 00000000 <ep>: 0: 00 00 00 00 0: R_386_32 e 00000004 <x>: 4: 0f 00 00 00 p y }

(10)

Executável depois de resolução de

referência e relocação (.text)

08048530 <main>: 8048530: 55 pushl %ebp 8048531 89 5 l % % b 8048531: 89 e5 movl %esp,%ebp 8048533: e8 08 00 00 00 call 8048540 <a> 8048538: 6a 00 pushl $0x0

804853a: e8 35 ff ff ff call 8048474 <_init+0x94> 804853f: 90 nop 08048540 <a>: 8048540: 55 pushl %ebp 8048541: 8b 15 1c a0 04 movl 0x804a01c,%edx 8048546: 08 Seção de Dados em 0x804a... 8048546: 08 8048547: a1 20 a0 04 08 movl 0x804a020,%eax 804854c: 89 e5 movl %esp,%ebp 804854e: 03 02 addl (%edx),%eax 8048550: 89 ec movl %ebp,%esp 8048552: 03 05 d0 a3 04 addl 0x804a3d0,%eax 8048557: 08 8048558: 5d popl %ebp 8048559: c3 ret

Bibliotecas

• Permitem agrupar módulos objeto relacionados em um arquivo

• No momento da ligação apenas os módulosNo momento da ligação, apenas os módulos “necessários” são copiados e combinados com o executável

• Para resolução de referências, processa-se as bibliotecas da esquerda para a direita!

gcc main.c mylib.a /usr/lib/libm.a • Driver gcc já amarra automaticamente com libc.ag j

• Para criar uma biblioteca, basta listar os arquivos objeto relocáveis, por exemplo:

(11)

Bibliotecas estáticas (archives)

p1.c p2.c

compilação

p1.o p2.o libc.a

Arquivo executável somente conterá código e dados de libc que são

Linker (ld) p compilação g q referenciadas em p1.c e p2.c

Carga (loading)

• O ato de copiar algumas seções para o espaço de endereçamento do processo, naturalmente,fazendo-se a relocação.

ELF header Program header table (required for executables)

.text section .data section .bss section symtab .text segment (r/o) Process image 0x08048494

init and shared lib segments 0x080483e0 Virtual addr .symtab .rel.text .rel.data .debug Section header table (required for relocatables)

.data segment (initialized r/w) .bss segment (uninitialized r/w) 0x0804a010 0x0804a3b0

(12)

Bibliotecas dinâmicas e

compartilhadas

• Principais desvantagens de bibliotecas estáticas:

– Replicação de código comum nos executáveis

• Desperdício de espaço em disco e na memória • Desperdício de espaço em disco e na memória

– Qualquer modificação (correção) nas bibliotecas requer uma re-amarração (re-linking) de todas as aplicações que as usam

• Bibliotecas dinâmicas

(ou dynamic link libraries,

DLLs) os módulos são dinâmicamente

DLLs) os módulos são dinâmicamente

carregados e ligados à aplicação em tempo de

carga ou em tempo de execução

• Vantagem adicional: estas bibliotecas podem ser compartilhadas por vários processos.

Bibliotecas Dinâmicas e compartilhadas

(cc1, as) m.c (cc1,as) a.c Biblioteca dinâmica m.o a.o libc.so Linker (ld) p Executável parcialmente ligado (em disco)

Funções de libc.so chamdas por m.c & a.c são carregadas, ligadas, e compartilhadas entre vários processos.

Loader/Dynamic Linker (ld-linux.so)

Executável totalmente ligado (em ´RAM)

Referências

Documentos relacionados

Vale ressaltar que a finalidade dos parafusos de ajustes utilizados é a de elevar ou abaixar o plano da antena, em relação ao plano de terra, para que durante as medidas possa ser

Com o advento do constitucionalismo e a consolidação da Constituição como centro do ordenamento jurídico, o controle de constitucionalidade mostra-se como mecanismo de

Os sujeitos supracitados recebem apoio e a garantia de integração social através da Lei nº 7.853/89 que criou a Coordenadoria Nacional para Integração da Pessoa

The objective of this study was to examine the relationship between growth patterns in early childhood and the onset of menarche before age 12, using data from The 1982

O estudo abarca o período de 2003 a 2012 e engloba uma análise de indicadores relativos à produção e comercialização de queijos e carnes certificados de

A tipologia de intervenção a apoiar respeita a investimentos nas explorações agrícolas para aquisição de tratores, utilizando custos simplificados com base em tabela normalizada

relacionados localizados ou Não Localizados, anote os Bens não relacionados e localizados que estão fisicamente na unidade, mas não constam no

Tabela 1: Resultados obtidos através da mineralização com bombas digestoras das amostras de agrião convencional procedente da cidade de Conceição de Jacuípe (CJ).. A