SlideShare uma empresa Scribd logo
1 de 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Ô

Mais conteúdo relacionado

Mais procurados

Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)
Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)
Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)Leinylson Fontinele
 
Estrutura de Dados - Aula 04 - Listas Estáticas
Estrutura de Dados - Aula 04 - Listas EstáticasEstrutura de Dados - Aula 04 - Listas Estáticas
Estrutura de Dados - Aula 04 - Listas EstáticasLeinylson Fontinele
 
Apostila Lógica de Programação
Apostila Lógica de ProgramaçãoApostila Lógica de Programação
Apostila Lógica de ProgramaçãoRicardo Terra
 
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Leinylson Fontinele
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL BásicoIgor Alves
 
Aula 04 PHP - Utilizando Funções e Manipulando Arquivos
Aula 04 PHP - Utilizando Funções e Manipulando ArquivosAula 04 PHP - Utilizando Funções e Manipulando Arquivos
Aula 04 PHP - Utilizando Funções e Manipulando ArquivosDaniel Brandão
 
Segurança da Informação - Aula 9 - Introdução a Auditoria de Sistemas
Segurança da Informação - Aula 9 - Introdução a Auditoria de SistemasSegurança da Informação - Aula 9 - Introdução a Auditoria de Sistemas
Segurança da Informação - Aula 9 - Introdução a Auditoria de SistemasCleber Fonseca
 
Aula05 - cabeamento estruturado - parte 02
Aula05 - cabeamento estruturado - parte 02Aula05 - cabeamento estruturado - parte 02
Aula05 - cabeamento estruturado - parte 02Carlos Veiga
 
Informática conceitos básicos
Informática   conceitos básicosInformática   conceitos básicos
Informática conceitos básicosThierryCC
 
Banco de Dados II Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)
Banco de Dados II  Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)Banco de Dados II  Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)
Banco de Dados II Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)Leinylson Fontinele
 
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...Fernanda Ledesma
 
Desvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptDesvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptRodrigo Branas
 

Mais procurados (20)

Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)
Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)
Sistemas Operacionais - Aula 02 (Visão geral de sistemas operacionais)
 
Estrutura de Dados - Aula 04 - Listas Estáticas
Estrutura de Dados - Aula 04 - Listas EstáticasEstrutura de Dados - Aula 04 - Listas Estáticas
Estrutura de Dados - Aula 04 - Listas Estáticas
 
Apostila Lógica de Programação
Apostila Lógica de ProgramaçãoApostila Lógica de Programação
Apostila Lógica de Programação
 
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL Básico
 
Aula 04 PHP - Utilizando Funções e Manipulando Arquivos
Aula 04 PHP - Utilizando Funções e Manipulando ArquivosAula 04 PHP - Utilizando Funções e Manipulando Arquivos
Aula 04 PHP - Utilizando Funções e Manipulando Arquivos
 
Segurança da Informação - Aula 9 - Introdução a Auditoria de Sistemas
Segurança da Informação - Aula 9 - Introdução a Auditoria de SistemasSegurança da Informação - Aula 9 - Introdução a Auditoria de Sistemas
Segurança da Informação - Aula 9 - Introdução a Auditoria de Sistemas
 
Protocolo SSH
Protocolo SSHProtocolo SSH
Protocolo SSH
 
Aula05 - cabeamento estruturado - parte 02
Aula05 - cabeamento estruturado - parte 02Aula05 - cabeamento estruturado - parte 02
Aula05 - cabeamento estruturado - parte 02
 
Aula1 Operador de Microcomputadores
Aula1 Operador de MicrocomputadoresAula1 Operador de Microcomputadores
Aula1 Operador de Microcomputadores
 
Placa mãe (motherboard)
Placa mãe (motherboard)Placa mãe (motherboard)
Placa mãe (motherboard)
 
Manutenção de computadores
Manutenção de computadoresManutenção de computadores
Manutenção de computadores
 
HTML Principios Básicos
HTML Principios BásicosHTML Principios Básicos
HTML Principios Básicos
 
Python
PythonPython
Python
 
Informática conceitos básicos
Informática   conceitos básicosInformática   conceitos básicos
Informática conceitos básicos
 
Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
 
Como trabalhar com arquivos e pastas
Como trabalhar com arquivos e pastasComo trabalhar com arquivos e pastas
Como trabalhar com arquivos e pastas
 
Banco de Dados II Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)
Banco de Dados II  Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)Banco de Dados II  Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)
Banco de Dados II Aula 02 - Modelagem de Dados (Definição, Modelo conceitual)
 
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...
Sobre as Aprendizagens Essenciais para Disciplina de TIC dos Cursos Profissio...
 
Desvendando a linguagem JavaScript
Desvendando a linguagem JavaScriptDesvendando a linguagem JavaScript
Desvendando a linguagem JavaScript
 

Semelhante a Entendendo a linkedição em C++

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çãoLorival Smolski Chapuis
 
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 plataformaFelipe Silveira
 
Python - Programando em alto nível
Python - Programando em alto nívelPython - Programando em alto nível
Python - Programando em alto nívelIgor Sobreira
 
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 PythonGuilherme Vierno
 
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-2019Renato Groff
 
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...Renato Groff
 
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...Renato Groff
 
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 - ...Renato Groff
 
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 Atalhosandreandrade17
 
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...Renato Groff
 
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 desenvolvedorFelipe Pedroso
 
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...Renato Groff
 
Sistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando ProgramasSistemas Operacionais - Gnu/Linux Instalando Programas
Sistemas Operacionais - Gnu/Linux Instalando ProgramasLuiz 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é LeiteTchelinux
 
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 DevOpsRafael Salerno de Oliveira
 
Semana da computacao - Linux Day
Semana da computacao - Linux DaySemana da computacao - Linux Day
Semana da computacao - Linux DayFábio Albuquerque
 
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 GitHubJulio Monteiro
 
Entity Framework 4, Novas funcionalidades
Entity Framework 4, Novas funcionalidadesEntity Framework 4, Novas funcionalidades
Entity Framework 4, Novas funcionalidadesC. Augusto Proiete
 

Semelhante a 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
 

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

  1. Pedir sugestões para treinamento da Tempo Real