SlideShare uma empresa Scribd logo
Entendendo a linkedição
Rodrigo Strauss
1bit.com.br
@rodrigostrauss
Grupo C & C++ Brasil
• Nasceu da vontade de conhecer outras áreas de
uso para C & C++
• Grupo de entusiastas/aficcionados
• Aberto à todos
• Organiza eventos para reunir profissionais,
estudantes e entusiastas
• Grupo mais multilinguagem que eu conheço
• groups.google.com/group/ccppbrasil/
• Temos um grupo no Telegram: t.me/ccppbrasil
• #ccppbrasil
Eu, eu e eu
• Escovador de bits
• Sócio programador da BitForge e da
Intelitrader
• Fundador do grupo C & C++ Brasil junto com o
Wanderley Caloni
• Fui MVP de Visual C++ por dois anos
• @rodrigostrauss
• www.1bit.com.br
Por que entender a linkedição
• Quanto mais você entende as mágicas melhor
programador você é
• Conhecimento dos ”internals” economiza tempo
e stress quando você mais precisa
• Abra as caixas pretas. Sempre
• A cada dia mais abstrações são criadas. Se você
sabe a raiz das coisas você entende tudo
rapidamente
• É um tópico extenso, eu foquei nos tópicos mais
úteis para diagnóstico dos problemas mais
comuns
Como seu código fonte vira um
programa?
• O compilador é só uma das partes
• O compilador converte código fonte para código
de máquina
• Para esse código de máquina ser útil ele precisa
ser
– Organizado
– ”Formatado” de uma forma que o sistema operacional
entenda
– Disponibilizado para ser usado por outros módulos
Compilação
• Resumidamente entra código fonte e sai
código de máquina
• Complicadamente isso requer diversos passos
– Parser
– Lexer
– Tratamento de AST
– Otimizador
Responsabilidades de cada um
Gerando um
executável
Compilador
Transforma fonte
em código de
máquina
Faz otimizações
Linker
Resolve chamadas
de função
Formata código
de uma forma que
o SO entenda
Relocação
O que um linker faz?
• Junta arquivos com código de máquina (principalemente)
em um arquivo executável que o SO consiga usar
• O compilador gera um arquivo .obj para cada arquivo .cpp
• O linker depois ”junta” esses arquivos .obj em outros tipos
de arquivo
– EXE
– DLL
– SYS
– DRV
– LIB
• Exceção à regra, esse arquivo não pode ser usado pelo sistema
operacional, ele é um simples agrupamentos de arquivos .obj
Considerações importantes
• Nem só de código de máquina vive um linker
– Código de máquina
• Erroneamente chamado de ”assembler”
– Dados
• Variáveis globais
• Variáveis estáticas
• TLS
• Resources (Windows)
• Informacão de debug
• Tabela de symbols
Por que existe o linker
• Motivos para precisarmos de um linker
– Dividir o código fonte em vários arquivos
– Permitir usar funções e dados disponibilizados de
forma binária
– O sistema operacional precisa de mais do um arquivo
com código de máquina sequencial
• Qualquer outra opção seria inviável
– Juntar todos os fontes
– Recompilar a partir dos fontes sempre
• Até o Gentoo usa um linker, certo Gianni?
Como um linker faz?
• Abre todos os arquivos .obj
• Verifica todas as funções não resolvidas
internamente
– Exemplo: uma função que está em main.obj chama
uma função que está em matematica.obj
• Procura essas funções em outros arquivos .obj ou
.lib
• Coloca essas funções dentro do executável e
aponta corretamente uma para outra
• Esse processo chama-se ”symbol resolution”
External resolving
• Consiste em verificar as promessas feitas ao
compilador
• Uma declaração de função em C e C++ nada
mais é que ”eu te prometo que essa função
existe em algum lugar”
• Onde procurar a função?
• Em que ordem?
Link estático
• Junta-se todos os arquivos .obj e .lib e gera-se um
executável
• Todo código de todas as funções resolvidas são
copiadas para dentro desse executável
• Isso faz com que o executável não tenha
dependência de DLLs (mais sobre isso daqui a
pouco)
• É o que acontece nos casos mais simples, quando
você cria um projeto novo no Visual C++
Link dinâmico
• A fase de symbol resolution é executada
quando o executável é carregado pelo sistema
operacional
– Cada DLL tem uma tabela de símbolos exportados
– Cada EXE tem uma tabela que contém os nomes
das DLLs e das funções importadas
• No Windows, isso vai dentro do arquivo PE,
em sessões específicas
DEMO DE COMPILAÇÃO E LINK
• Um arquivo cpp gerando um EXE
• Dois arquivos cpp gerando um EXE
• Movendo as funções para uma LIB
• Movendo as funções para uma DLL
ESCOVAÇÃO DE BITS
Formato COFF
• Common Object File Format
• É um velho formato do UNIX, criado pela AT&T em 1983
• O Windows usa uma extensão desse formato, que é
chamado PE (Portable Executable)
• Todo arquivo com código de máquina no Windows é um PE
– OBJ
– LIB
– DLL
– EXE
– DRV
– SYS
• O Linux usa o formato ELF
O que tem dentro de um COFF/PE?
• Um arquivo COFF/PE é composto por
– Header
– Section definition
– Section Content
Sections PE
• .text
• .drective
• .idata
• .edata
• .debug
• .data
• .bss
• .tls
Sections PE
• .text é a seção com código
• Podemos ver várias seções com nomes extras
depois de um $
– .text$M
– .text$XPTO
• Aí é que está a parte executável do programa
Sections PE
• As informações de debug estão,
surpreendentemente, nas seções .debug
– .debug$T
– .debug$S
– .debug$P
• Algumas informações são inline, outras são
referências para arquivos PDB
Sections PE
• .idata
– Import Data
• .edata
– Export Data
Sections PE
• .data
– Dados inicializados
• .bss
– Dados não inicializados
• .rsrc
• Resources
• .tls
– Thread Local Storage
Sections PE
• .drective
– Parâmetros para o linker
– Aqui vão todos o #pragma comment (lib)
DEMO
• Vamos olhar os arquivos gerados na demo
anterior
Algumas considerações
• Arquivos .obj e .lib declaram suas
dependências por nome
• Calling convention define o formato dos
nomes
– stdcall, cdecl, fastcall, etc
Problemas comuns e como
diagnosticá-los
• LNK2019: Unresolved external
• LNK1104: cannot open file ’xpto.lib’
• LNK2005: ”xpto” already defined in xyz.obj
• Dependências de diferentes runtimes
• Unresolved external: MessageBoxA ou
MessageBoxW
• Erro de DLL não encontrada em runtime
Maiores causadores de problemas no
link
• PREPROCESSADOR, o campeão dos campeões
• Declarações diferentes para cada .obj ou .lib
• Versão UNICODE ou ANSI das apis Win32
• _WINVER
• _HAS_ITERATOR_DEBUGGING
• Diferentes libs usam diferentes versões da
runtime do Visual C++
• #pragma comment(lib)
• Calling convention errado
Recursos do Visual C++
• Whole Program Optimization
• #pragma comment (lib)
• FAILIFMISMATCH
• /NODEFAULTLIB
• __declspec(dllexport)
• __declspec(selectany)
Whole Program Optimization
• O linker faz inline de funções
• Acaba sendo um módulo do otimizador do
compilador rodando na hora do link
• Melhora a performance do código fazendo uma
otimização que antes só era possível ”grudando”
todos os arquivos fontes em um só
– Sqlite tem o amalgamation
– SQL Server foi o primeiro usuário do WPO dentro da
Microsoft
CABÔ

Mais conteúdo relacionado

PDF
Aula 4 - Teste de mesa
PPT
PDF
Aula1-Conceitos de SGBD
PPTX
Informática Básica - Aula 03 - Hardware
PDF
Arquitetura de-computadores-apostila-avançada completa
PDF
Mini Curso de Microsoft Power BI
PDF
LDB atualizada 2024 - o que mais cai em concursos da educação
PPTX
Programação Orientada a Objetos
Aula 4 - Teste de mesa
Aula1-Conceitos de SGBD
Informática Básica - Aula 03 - Hardware
Arquitetura de-computadores-apostila-avançada completa
Mini Curso de Microsoft Power BI
LDB atualizada 2024 - o que mais cai em concursos da educação
Programação Orientada a Objetos

Mais procurados (20)

PDF
Aula 6 - Estruturas de seleção encadeada - parte 1
PDF
Java orientação a objetos (variaveis de instancia e metodos)
PPTX
Algoritmos - Pseudocódigo
DOCX
Atividade fundamentos-de-redes
PDF
Aula 1 - Introdução a POO
PPTX
Pensamento Computacional aula 01
PDF
Aula 5 - Estruturas de seleção simples e composta - parte 1
PDF
ICC - Aula 05 - Estrutura de controle, sequencial e condicional
PDF
95579522 control-net
PDF
exercicio-Organização e estrutura de Computadores
PPT
Inclusao de pessoas com deficiência
PPTX
Apresentação partes do computador
PPTX
Aula 1: Virtualização
PPTX
Hardware e software
PDF
Sistemas Operacionais - Aula 07 (Thread e Processos)
PDF
Exercicios java básico
PDF
Java orientação a objetos (associacao, composicao, agregacao)
PDF
Sistemas Computacionais - Aula 01 - Apresentação
PDF
Banco de Dados - Conceitos
Aula 6 - Estruturas de seleção encadeada - parte 1
Java orientação a objetos (variaveis de instancia e metodos)
Algoritmos - Pseudocódigo
Atividade fundamentos-de-redes
Aula 1 - Introdução a POO
Pensamento Computacional aula 01
Aula 5 - Estruturas de seleção simples e composta - parte 1
ICC - Aula 05 - Estrutura de controle, sequencial e condicional
95579522 control-net
exercicio-Organização e estrutura de Computadores
Inclusao de pessoas com deficiência
Apresentação partes do computador
Aula 1: Virtualização
Hardware e software
Sistemas Operacionais - Aula 07 (Thread e Processos)
Exercicios java básico
Java orientação a objetos (associacao, composicao, agregacao)
Sistemas Computacionais - Aula 01 - Apresentação
Banco de Dados - Conceitos
Anúncio

Semelhante a Entendendo a linkedição em C++ (10)

PDF
Criação, compilação e execução de um programa C (1).pdf
PDF
Análise de Código Malicioso no Linux
PPTX
Aula 01 - Introducao a C (3).pptx
PDF
PDF
Tutorial Programando C no Linux
PDF
Construindo um analisador de executáveis
PDF
Vale Security Conference - 2011 - 11 - Fernando Mercês [Octane Labs] [Coding ...
DOC
Aula de C para Linux
ODP
Aula c++ estruturas de dados
PDF
Criação, compilação e execução de um programa C (1).pdf
Análise de Código Malicioso no Linux
Aula 01 - Introducao a C (3).pptx
Tutorial Programando C no Linux
Construindo um analisador de executáveis
Vale Security Conference - 2011 - 11 - Fernando Mercês [Octane Labs] [Coding ...
Aula de C para Linux
Aula c++ estruturas de dados
Anúncio

Último (11)

PPTX
Tipos de servidor em redes de computador.pptx
PPTX
Eng. Software - pontos essenciais para o início
PPTX
Utilizando code blockes por andre backes
PPTX
Design - Introdução a Gestalt e teoria das formas
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
PDF
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
PDF
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf
PDF
Manejo integrado de pragas na cultura do algodão
PPTX
Viasol Energia Solar -Soluções para geração e economia de energia
PPTX
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
PPTX
Arquitetura de computadores - Memórias Secundárias
Tipos de servidor em redes de computador.pptx
Eng. Software - pontos essenciais para o início
Utilizando code blockes por andre backes
Design - Introdução a Gestalt e teoria das formas
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf
Manejo integrado de pragas na cultura do algodão
Viasol Energia Solar -Soluções para geração e economia de energia
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
Arquitetura de computadores - Memórias Secundárias

Entendendo a linkedição em C++

  • 1. Entendendo a linkedição Rodrigo Strauss 1bit.com.br @rodrigostrauss
  • 2. Grupo C & C++ Brasil • Nasceu da vontade de conhecer outras áreas de uso para C & C++ • Grupo de entusiastas/aficcionados • Aberto à todos • Organiza eventos para reunir profissionais, estudantes e entusiastas • Grupo mais multilinguagem que eu conheço • groups.google.com/group/ccppbrasil/ • Temos um grupo no Telegram: t.me/ccppbrasil • #ccppbrasil
  • 3. Eu, eu e eu • Escovador de bits • Sócio programador da BitForge e da Intelitrader • Fundador do grupo C & C++ Brasil junto com o Wanderley Caloni • Fui MVP de Visual C++ por dois anos • @rodrigostrauss • www.1bit.com.br
  • 4. Por que entender a linkedição • Quanto mais você entende as mágicas melhor programador você é • Conhecimento dos ”internals” economiza tempo e stress quando você mais precisa • Abra as caixas pretas. Sempre • A cada dia mais abstrações são criadas. Se você sabe a raiz das coisas você entende tudo rapidamente • É um tópico extenso, eu foquei nos tópicos mais úteis para diagnóstico dos problemas mais comuns
  • 5. Como seu código fonte vira um programa? • O compilador é só uma das partes • O compilador converte código fonte para código de máquina • Para esse código de máquina ser útil ele precisa ser – Organizado – ”Formatado” de uma forma que o sistema operacional entenda – Disponibilizado para ser usado por outros módulos
  • 6. Compilação • Resumidamente entra código fonte e sai código de máquina • Complicadamente isso requer diversos passos – Parser – Lexer – Tratamento de AST – Otimizador
  • 7. Responsabilidades de cada um Gerando um executável Compilador Transforma fonte em código de máquina Faz otimizações Linker Resolve chamadas de função Formata código de uma forma que o SO entenda Relocação
  • 8. O que um linker faz? • Junta arquivos com código de máquina (principalemente) em um arquivo executável que o SO consiga usar • O compilador gera um arquivo .obj para cada arquivo .cpp • O linker depois ”junta” esses arquivos .obj em outros tipos de arquivo – EXE – DLL – SYS – DRV – LIB • Exceção à regra, esse arquivo não pode ser usado pelo sistema operacional, ele é um simples agrupamentos de arquivos .obj
  • 9. Considerações importantes • Nem só de código de máquina vive um linker – Código de máquina • Erroneamente chamado de ”assembler” – Dados • Variáveis globais • Variáveis estáticas • TLS • Resources (Windows) • Informacão de debug • Tabela de symbols
  • 10. Por que existe o linker • Motivos para precisarmos de um linker – Dividir o código fonte em vários arquivos – Permitir usar funções e dados disponibilizados de forma binária – O sistema operacional precisa de mais do um arquivo com código de máquina sequencial • Qualquer outra opção seria inviável – Juntar todos os fontes – Recompilar a partir dos fontes sempre • Até o Gentoo usa um linker, certo Gianni?
  • 11. Como um linker faz? • Abre todos os arquivos .obj • Verifica todas as funções não resolvidas internamente – Exemplo: uma função que está em main.obj chama uma função que está em matematica.obj • Procura essas funções em outros arquivos .obj ou .lib • Coloca essas funções dentro do executável e aponta corretamente uma para outra • Esse processo chama-se ”symbol resolution”
  • 12. External resolving • Consiste em verificar as promessas feitas ao compilador • Uma declaração de função em C e C++ nada mais é que ”eu te prometo que essa função existe em algum lugar” • Onde procurar a função? • Em que ordem?
  • 13. Link estático • Junta-se todos os arquivos .obj e .lib e gera-se um executável • Todo código de todas as funções resolvidas são copiadas para dentro desse executável • Isso faz com que o executável não tenha dependência de DLLs (mais sobre isso daqui a pouco) • É o que acontece nos casos mais simples, quando você cria um projeto novo no Visual C++
  • 14. Link dinâmico • A fase de symbol resolution é executada quando o executável é carregado pelo sistema operacional – Cada DLL tem uma tabela de símbolos exportados – Cada EXE tem uma tabela que contém os nomes das DLLs e das funções importadas • No Windows, isso vai dentro do arquivo PE, em sessões específicas
  • 15. DEMO DE COMPILAÇÃO E LINK • Um arquivo cpp gerando um EXE • Dois arquivos cpp gerando um EXE • Movendo as funções para uma LIB • Movendo as funções para uma DLL
  • 17. Formato COFF • Common Object File Format • É um velho formato do UNIX, criado pela AT&T em 1983 • O Windows usa uma extensão desse formato, que é chamado PE (Portable Executable) • Todo arquivo com código de máquina no Windows é um PE – OBJ – LIB – DLL – EXE – DRV – SYS • O Linux usa o formato ELF
  • 18. O que tem dentro de um COFF/PE? • Um arquivo COFF/PE é composto por – Header – Section definition – Section Content
  • 19. Sections PE • .text • .drective • .idata • .edata • .debug • .data • .bss • .tls
  • 20. Sections PE • .text é a seção com código • Podemos ver várias seções com nomes extras depois de um $ – .text$M – .text$XPTO • Aí é que está a parte executável do programa
  • 21. Sections PE • As informações de debug estão, surpreendentemente, nas seções .debug – .debug$T – .debug$S – .debug$P • Algumas informações são inline, outras são referências para arquivos PDB
  • 22. Sections PE • .idata – Import Data • .edata – Export Data
  • 23. Sections PE • .data – Dados inicializados • .bss – Dados não inicializados • .rsrc • Resources • .tls – Thread Local Storage
  • 24. Sections PE • .drective – Parâmetros para o linker – Aqui vão todos o #pragma comment (lib)
  • 25. DEMO • Vamos olhar os arquivos gerados na demo anterior
  • 26. Algumas considerações • Arquivos .obj e .lib declaram suas dependências por nome • Calling convention define o formato dos nomes – stdcall, cdecl, fastcall, etc
  • 27. Problemas comuns e como diagnosticá-los • LNK2019: Unresolved external • LNK1104: cannot open file ’xpto.lib’ • LNK2005: ”xpto” already defined in xyz.obj • Dependências de diferentes runtimes • Unresolved external: MessageBoxA ou MessageBoxW • Erro de DLL não encontrada em runtime
  • 28. Maiores causadores de problemas no link • PREPROCESSADOR, o campeão dos campeões • Declarações diferentes para cada .obj ou .lib • Versão UNICODE ou ANSI das apis Win32 • _WINVER • _HAS_ITERATOR_DEBUGGING • Diferentes libs usam diferentes versões da runtime do Visual C++ • #pragma comment(lib) • Calling convention errado
  • 29. Recursos do Visual C++ • Whole Program Optimization • #pragma comment (lib) • FAILIFMISMATCH • /NODEFAULTLIB • __declspec(dllexport) • __declspec(selectany)
  • 30. Whole Program Optimization • O linker faz inline de funções • Acaba sendo um módulo do otimizador do compilador rodando na hora do link • Melhora a performance do código fazendo uma otimização que antes só era possível ”grudando” todos os arquivos fontes em um só – Sqlite tem o amalgamation – SQL Server foi o primeiro usuário do WPO dentro da Microsoft
  • 31. CABÔ

Notas do Editor

  • #4: Pedir sugestões para treinamento da Tempo Real