Uma pergunta muito semelhante foi feita no Stack Overflow: Como extrair protótipo de função de um arquivo ELF?
Resumindo: geralmente você não pode. Se o executável (ou biblioteca compartilhada) não tiver informações de depuração, as informações sobre o número e o tipo de argumentos não serão armazenadas no executável.
Se o arquivo de objeto compartilhado tiver informações de depuração, você poderá extrair as informações com readelf -wi
ou usando um depurador.
Por exemplo, eu tenho um executável ELF que contém uma função int foo(char a, long b)
, compilada com informações de depuração. GDB me diz:
(gdb) p foo
$1 = {int (char, long int)} 0x40051c <foo>
E readelf -wi
(um pouco enigmático, você terá que combinar as entradas):
<1><2d>: Abbrev Number: 2 (DW_TAG_subprogram) <= function
<2e> DW_AT_external : 1
<2f> DW_AT_name : foo <= func name
<33> DW_AT_decl_file : 1
<34> DW_AT_decl_line : 1
<35> DW_AT_prototyped : 1
<36> DW_AT_type : <0x6c> <= return type
<3a> DW_AT_low_pc : 0x40051c
<42> DW_AT_high_pc : 0x400532
<4a> DW_AT_frame_base : 0x0 (location list)
<4e> DW_AT_GNU_all_call_sites: 1
<4f> DW_AT_sibling : <0x6c>
<2><53>: Abbrev Number: 3 (DW_TAG_formal_parameter) <= parameter
<54> DW_AT_name : a
<56> DW_AT_decl_file : 1
<57> DW_AT_decl_line : 1
<58> DW_AT_type : <0x73>
<5c> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20)
<2><5f>: Abbrev Number: 3 (DW_TAG_formal_parameter) <= other param
<60> DW_AT_name : b
<62> DW_AT_decl_file : 1
<63> DW_AT_decl_line : 1
<64> DW_AT_type : <0x7a>
<68> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<1><6c>: Abbrev Number: 4 (DW_TAG_base_type)
<6d> DW_AT_byte_size : 4
<6e> DW_AT_encoding : 5 (signed)
<6f> DW_AT_name : int
<1><73>: Abbrev Number: 5 (DW_TAG_base_type)
<74> DW_AT_byte_size : 1
<75> DW_AT_encoding : 6 (signed char)
<76> DW_AT_name : (indirect string, offset: 0x2e): char
<1><7a>: Abbrev Number: 5 (DW_TAG_base_type)
<7b> DW_AT_byte_size : 8
<7c> DW_AT_encoding : 5 (signed)
<7d> DW_AT_name : (indirect string, offset: 0x0): long int
Observe que, para C ++, os símbolos que você vê com nm
contêm mais informações (a menos que tenham sido declarados extern "C"
- o número e o tipo de parâmetros devem estar disponíveis ao vinculador para lidar com sobrecarga. Mas o tipo de retorno as informações também não estão lá (mas os símbolos são desconfigurados - c++filt
pode ser usado para desmanchar).
Compilar o mesmo arquivo de origem que o C ++ fornece a seguinte saída para nm a.out | c++filt
:
...
0000000000400554 T foo(char, long)
...