Como os tamanhos das funções são calculados por readelf

1

Estou tentando entender como o utilitário readelf calcula o tamanho da função. Eu escrevi um programa simples

#include <stdio.h>

int main() {
    printf("Test!\n");
}

Agora, para verificar o tamanho da função, usei isso (está tudo bem?):

readelf -sw a.out|sort -n -k 3,3|grep FUNC

que produziu:

 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
 2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
29: 0000000000400470     0 FUNC    LOCAL  DEFAULT   13 deregister_tm_clones
30: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   13 register_tm_clones
31: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
34: 0000000000400500     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
48: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.2.5
50: 00000000004005b4     0 FUNC    GLOBAL DEFAULT   14 _fini
51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
58: 0000000000400440     0 FUNC    GLOBAL DEFAULT   13 _start
64: 00000000004003e0     0 FUNC    GLOBAL DEFAULT   11 _init
45: 00000000004005b0     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
60: 000000000040052d    16 FUNC    GLOBAL DEFAULT   13 main
56: 0000000000400540   101 FUNC    GLOBAL DEFAULT   13 __libc_csu_init

Agora, se eu verificar o tamanho da função principal, ele mostra 16. Como ele chegou a isso? Esse é o tamanho da pilha?

Compilador usado gcc versão 4.8.5 (Ubuntu 4.8.5-2ubuntu1 ~ 14.04.1)

GNU readelf (GNU Binutils para Ubuntu) 2.24

    
por Zoso 10.04.2018 / 12:53

1 resposta

3

O tamanho dado por readelf é o tamanho do objeto binário; para main , essa é a sequência de instruções de máquina que implementam sua função. No meu sistema, vejo

57: 00000000004004d7    21 FUNC    GLOBAL DEFAULT   13 main

de readelf , que combina muito bem com o código compilado, conforme mostrado por gcc -S ou objdump -d :

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   

Os 21 bytes são os bytes 55 , 48 , 89 , e5 etc.

    
por 10.04.2018 / 13:09

Tags