111 lines
3.7 KiB
Org Mode
111 lines
3.7 KiB
Org Mode
#+title: Curso prático de introdução ao GDB
|
|
#+author: Blau Araujo
|
|
#+email: blau@debxp.org
|
|
|
|
* 3. Formato ELF
|
|
|
|
** Binários ELF, símbolos e códigos-fonte
|
|
|
|
Todo arquivo executável pelo sistema é construído em um binário segundo um
|
|
formato padrão. No GNU/Linux, esse formato é o *ELF* (/Executable and Linkable Format/),
|
|
que inclui no binário:
|
|
|
|
- O código de máquina do programa;
|
|
- Dados de variáveis globais e estáticas;
|
|
- Dados constantes;
|
|
- Tabelas de símbolos;
|
|
- Informações de depuração (se incluídas).
|
|
|
|
Os primeiros bytes de um arquivo ELF contém um cabeçalho com diversas
|
|
informações sobre o binário, o que nós podemos listar com o utilitário
|
|
=readelf=:
|
|
|
|
#+begin_example
|
|
:~$ readelf -h demo
|
|
Cabeçalho ELF:
|
|
Magia: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
|
|
Classe: ELF64
|
|
Dados: complemento 2, little endian
|
|
Versão: 1 (actual)
|
|
OS/ABI: UNIX - System V
|
|
Versão ABI: 0
|
|
Tipo: DYN (Position-Independent Executable file)
|
|
Máquina: Advanced Micro Devices X86-64
|
|
Versão: 0x1
|
|
Endereço do ponto de entrada: 0x1050
|
|
Início dos cabeçalhos do programa: 64 (bytes no ficheiro)
|
|
Start of section headers: 14944 (bytes no ficheiro)
|
|
Bandeiras: 0x0
|
|
Tamanho deste cabeçalho: 64 (bytes)
|
|
Tamanho dos cabeçalhos do programa:56 (bytes)
|
|
Nº de cabeçalhos do programa: 14
|
|
Tamanho dos cabeçalhos de secção: 64 (bytes)
|
|
Nº dos cabeçalhos de secção: 37
|
|
Índice de tabela de cadeias da secção: 36
|
|
#+end_example
|
|
|
|
*** Símbolos e o código-fonte
|
|
|
|
Símbolos são nomes associados a elementos do programa, como funções e
|
|
variáveis. Quando os símbolos de depuração são incluídos no binário
|
|
(compilando com =-g=, por exemplo), o GDB é capaz de:
|
|
|
|
- Exibir nomes legíveis, em vez de endereços de memória;
|
|
- Acompanhar o fluxo do programa com o código-fonte;
|
|
- Receber definições de /breakpoints/ por nomes de funções;
|
|
- Fazer a associação de códigos binários com as linhas do código-fonte;
|
|
- Acessar nomes de variáveis, tipos, estruturas, etc.
|
|
|
|
Nós podemos verificar se o programa foi compilado com os símbolos de
|
|
depuração com o utilitário =file=...
|
|
|
|
Sem a opção =-g=:
|
|
|
|
#+begin_example
|
|
:~$ gcc -o demo demo.c
|
|
:~$ file demo
|
|
demo: ELF 64-bit LSB pie executable [...] not stripped
|
|
#+end_example
|
|
|
|
Com a opção =-g=:
|
|
|
|
#+begin_example
|
|
:~$ gcc -g -o demo demo.c
|
|
:~$ file demo
|
|
demo: ELF 64-bit LSB pie executable [...] with debug_info, not stripped
|
|
#+end_example
|
|
|
|
Repare que, desta vez, nós temos a informação =with debug_info= no final
|
|
da linha.
|
|
|
|
Nós também podemos verificar se há símbolos de depuração a partir das
|
|
informações no formato ELF:
|
|
|
|
#+begin_example
|
|
:~$ readelf -S demo | grep debug
|
|
[28] .debug_aranges PROGBITS 0000000000000000 00003037
|
|
[29] .debug_info PROGBITS 0000000000000000 00003067
|
|
[30] .debug_abbrev PROGBITS 0000000000000000 00003180
|
|
[31] .debug_line PROGBITS 0000000000000000 0000324a
|
|
[32] .debug_str PROGBITS 0000000000000000 000032ba
|
|
[33] .debug_line_str PROGBITS 0000000000000000 00003367
|
|
#+end_example
|
|
|
|
Mas o próprio GDB informa se há símbolos de depuração ao iniciar...
|
|
|
|
Sem a opção =-g=:
|
|
|
|
#+begin_example
|
|
:~$ gcc -o demo demo.c
|
|
:~$ gdb demo
|
|
Reading symbols from demo...
|
|
(No debugging symbols found in demo)
|
|
#+end_example
|
|
|
|
Com a opção =-g=:
|
|
|
|
#+begin_example
|
|
:~$ gcc -g -o demo demo.c
|
|
:~$ gdb demo
|
|
Reading symbols from demo...
|
|
#+end_example
|