Eine sehr ähnliche Frage wurde zum Stapelüberlauf gestellt: Wie extrahiere ich einen Funktionsprototyp aus einer ELF-Datei?
Kurzum: Im Allgemeinen können Sie nicht. Wenn die ausführbare Datei (oder gemeinsam genutzte Bibliothek) keine Debug-Informationen enthält, werden die Informationen zu Anzahl und Art der Argumente nicht in der ausführbaren Datei gespeichert.
Wenn die gemeinsam genutzte Objektdatei Debug-Informationen enthält, sollten Sie in der Lage sein, die Informationen mit readelf -wi
oder mithilfe eines Debuggers zu extrahieren .
Zum Beispiel habe ich eine ausführbare ELF-Datei, die eine Funktion enthält int foo(char a, long b)
, die mit Debug-Informationen kompiliert wurde. GDB sagt mir:
(gdb) p foo
$1 = {int (char, long int)} 0x40051c <foo>
Und readelf -wi
(ein bisschen kryptisch, Sie müssen die Einträge selbst abgleichen) hat:
<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
Beachten Sie, dass für C ++ die Symbole, die mit nm
angezeigt werden, mehr Informationen enthalten (sofern sie nicht deklariert wurden extern "C"
- die Anzahl und der Typ der Parameter müssen dem Linker zur Verfügung stehen, um eine Überladung zu bewältigen. Die Informationen zum Rückgabetyp sind jedoch auch nicht vorhanden Die Symbole sind verstümmelt - c++filt
können zum Entwirren verwendet werden.)
Das Kompilieren derselben Quelldatei wie C ++ ergibt die folgende Ausgabe für nm a.out | c++filt
:
...
0000000000400554 T foo(char, long)
...