SlideShare a Scribd company logo
1 of 31
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Ô

More Related Content

What's hot

Designing the active directory logical structure
Designing the active directory logical structureDesigning the active directory logical structure
Designing the active directory logical structure
John Carlo Catacutan
 

What's hot (7)

Ha active active bang gfs2
Ha active  active bang gfs2Ha active  active bang gfs2
Ha active active bang gfs2
 
Beginners guide to_optimizer
Beginners guide to_optimizerBeginners guide to_optimizer
Beginners guide to_optimizer
 
Ugprade HCL Sametime V11.5 to V11.6 - Step by Step
Ugprade HCL Sametime V11.5 to V11.6 - Step by StepUgprade HCL Sametime V11.5 to V11.6 - Step by Step
Ugprade HCL Sametime V11.5 to V11.6 - Step by Step
 
Solving the DB2 LUW Administration Dilemma
Solving the DB2 LUW Administration DilemmaSolving the DB2 LUW Administration Dilemma
Solving the DB2 LUW Administration Dilemma
 
Designing the active directory logical structure
Designing the active directory logical structureDesigning the active directory logical structure
Designing the active directory logical structure
 
Creating Web Applications with IDMS, COBOL and ADSO
Creating Web Applications with IDMS, COBOL and ADSOCreating Web Applications with IDMS, COBOL and ADSO
Creating Web Applications with IDMS, COBOL and ADSO
 
Subnetting
SubnettingSubnetting
Subnetting
 

Similar to Entendendo a linkedição em C++

Sistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando ProgramasSistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando Programas
Luiz Arthur
 
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé LeiteComo ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
Tchelinux
 

Similar to Entendendo a linkedição em C++ (20)

DotNet Framework e Orientação a Objetos 1 - Introdução
DotNet Framework e Orientação a Objetos 1 - IntroduçãoDotNet Framework e Orientação a Objetos 1 - Introdução
DotNet Framework e Orientação a Objetos 1 - Introdução
 
Csharp
CsharpCsharp
Csharp
 
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataformaAndroid Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
 
Python - Programando em alto nível
Python - Programando em alto nívelPython - Programando em alto nível
Python - Programando em alto nível
 
Análise estática de código Python
Análise estática de código PythonAnálise estática de código Python
Análise estática de código Python
 
Docker: primeiros passos - Semana FCI - Mackenzie - Outubro-2019
Docker: primeiros passos - Semana FCI - Mackenzie - Outubro-2019Docker: primeiros passos - Semana FCI - Mackenzie - Outubro-2019
Docker: primeiros passos - Semana FCI - Mackenzie - Outubro-2019
 
Docker: Conceitos e Primeiros Passos na utilização de Containers - Programand...
Docker: Conceitos e Primeiros Passos na utilização de Containers - Programand...Docker: Conceitos e Primeiros Passos na utilização de Containers - Programand...
Docker: Conceitos e Primeiros Passos na utilização de Containers - Programand...
 
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Ab...
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Ab...Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Ab...
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Ab...
 
Tecnologias Microsoft em Linux: .NET Core, SQL Server e Visual Studio Code - ...
Tecnologias Microsoft em Linux: .NET Core, SQL Server e Visual Studio Code - ...Tecnologias Microsoft em Linux: .NET Core, SQL Server e Visual Studio Code - ...
Tecnologias Microsoft em Linux: .NET Core, SQL Server e Visual Studio Code - ...
 
Net beans 7.4 Funções e Atalhos
Net beans 7.4 Funções e AtalhosNet beans 7.4 Funções e Atalhos
Net beans 7.4 Funções e Atalhos
 
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Se...
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Se...Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Se...
Docker: Primeiros Passos, Dicas e Truques no Gerenciamento de Containers - Se...
 
Git e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedorGit e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedor
 
Docker + Django
Docker + DjangoDocker + Django
Docker + Django
 
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
Docker + Bancos de Dados: descomplicando a montagem de ambientes de Desenvolv...
 
Sistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando ProgramasSistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando Programas
 
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé LeiteComo ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
Como ajudar no desenvolvimento do kernel Linux? - Fábio Olivé Leite
 
Como automatizar Sistemas Legados utilizando ferramentas de DevOps
Como automatizar Sistemas Legados utilizando ferramentas de DevOpsComo automatizar Sistemas Legados utilizando ferramentas de DevOps
Como automatizar Sistemas Legados utilizando ferramentas de DevOps
 
Semana da computacao - Linux Day
Semana da computacao - Linux DaySemana da computacao - Linux Day
Semana da computacao - Linux Day
 
Como colaborar com projetos opensource com o GitHub
Como colaborar com projetos opensource com o GitHubComo colaborar com projetos opensource com o GitHub
Como colaborar com projetos opensource com o GitHub
 
Entity Framework 4, Novas funcionalidades
Entity Framework 4, Novas funcionalidadesEntity Framework 4, Novas funcionalidades
Entity Framework 4, Novas funcionalidades
 

Recently uploaded

Recently uploaded (8)

ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 
Luís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdf
 
Programação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfProgramação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdf
 
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docxATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 

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Ô

Editor's Notes

  1. Pedir sugestões para treinamento da Tempo Real