gdb elf objdump function-prototypes readelf

gdb - ¿Cómo extraer prototipos de función de un archivo elf?



objdump function-prototypes (1)

GDB conoce la firma de una función a través de DWARF debuginfo. readelf -w ELF arrojaría eso. Probablemente quiera leer Introducción al formato de depuración DWARF por Michael J. Eager. Usando pyelftools puedes explorar y experimentar con DWARF desde una sesión interactiva de Python.

Para extraer prototipos de función, desea las entradas de información de depuración del subprogram . Un ejemplo en el tutorial de formato DWARF es:

strndup.c

1: #include "ansidecl.h" 2: #include <stddef.h> 3: 4: extern size_t strlen (const char*); 5: extern PTR malloc (size_t); 6: extern PTR memcpy (PTR, const PTR, size_t); 7: 8: char * 9: strndup (const char *s, size_t n) 10: { 11: char *result; 12: size_t len = strlen (s); 13: 14: if (n < len) 15: len = n; 16: 17: result = (char *) malloc (len + 1); 18: if (!result) 19: return 0; 20: 21: result[len] = ''/0''; 22: return (char *) memcpy (result, s, len); 23: }

Descripción DWARF para strndup.c

<1>: DW_TAG_base_type DW_AT_name = int DW_AT_byte_size = 4 DW_AT_encoding = signed <2>: DW_TAG_typedef DW_AT_name = size_t DW_AT_type = <3> <3>: DW_TAG_base_type DW_AT_name = unsigned int DW_AT_byte_size = 4 DW_AT_encoding = unsigned <4>: DW_TAG_base_type DW_AT_name = long int DW_AT_byte_size = 4 DW_AT_encoding = signed <5>: DW_TAG_subprogram DW_AT_sibling = <10> DW_AT_external = 1 DW_AT_name = strndup DW_AT_prototyped = 1 DW_AT_type = <10> DW_AT_low_pc = 0 DW_AT_high_pc = 0x7b <6>: DW_TAG_formal_parameter DW_AT_name = s DW_AT_type = <12> DW_AT_location = (DW_OP_fbreg: 0) <7>: DW_TAG_formal_parameter DW_AT_name = n DW_AT_type = <2> DW_AT_location = (DW_OP_fbreg: 4) <8>: DW_TAG_variable DW_AT_name = result DW_AT_type = <10> DW_AT_location = (DW_OP_fbreg: -28) <9>: DW_TAG_variable DW_AT_name = len DW_AT_type = <2> DW_AT_location = (DW_OP_fbreg: -24) <10>: DW_TAG_pointer_type DW_AT_byte_size = 4 DW_AT_type = <11> <11>: DW_TAG_base_type DW_AT_name = char DW_AT_byte_size = 1 DW_AT_encoding = signed char <12>: DW_TAG_pointer_type DW_AT_byte_size = 4 DW_AT_type = <13> <13>: DW_TAG_const_type DW_AT_type = <11>

Para una implementación más completa de la muestra, eche un vistazo a esta biblioteca de reflexión C de Petr Machata. Tiene el código para hacer lo que quieras con la siguiente advertencia:

  • La reflexión se ejecuta en proceso en lugar de fuera de proceso, como GDB
  • Depende de libdw y libdwfl de elfutils . No estoy seguro de cómo se sentiría acerca de hacer crecer esas dependencias externas de la biblioteca.

No he tenido éxito en encontrar una respuesta sobre esta pregunta.

Usando GDB, puedo usar el comando "llamar" para obtener el prototipo de una función. Ejemplo:

(gdb) call fn $1 = {void (int, int)} 0x8048414 <fn>

Entonces, GDB es capaz de descubrir, solo desde el archivo elf, que fn () devuelve vacío y toma dos enteros como argumentos.

Sin embargo, necesito usar alguna otra herramienta para extraer los prototipos de función de un archivo elf. Preferiblemente, quiero usar objdump / readelf.

¿Alguien sabe si esto es posible? Si no es posible, ¿cómo lo hace GDB? ¿En qué sección del archivo elf se almacenan los prototipos de función?