gcc compiler-construction cygwin elf dwarf

gcc - Extrae variables globales del archivo a.out



compiler-construction cygwin (1)

Esto es lo que haré. ¡Por qué reinventar la rueda!

  1. Descarga los comandos de Linux que necesitarán en Windows desde aquí.

    en el directorio bin debería haber: readelf.exe

    Tenga en cuenta que no necesitaremos Cygwin ni ningún programa, por lo que implementarlo será simple.

  2. Una vez que tengamos ese archivo ejecutemos en cmd:

    // cd "path where readelf.exe is" readelf.exe -s a.out

    y esta es la lista que saldrá a la luz:

    así que si echas un vistazo, estamos interesados ​​en obtener todas las variables que son de tipo OBJECT con un tamaño mayor que 0.

  3. Una vez que tenemos las variables, podemos usar el readelf.exe -w a.out para echar un vistazo al árbol y se ve así: comencemos a buscar una de las variables que encontramos en el paso 2 (SOME_GREAT_COUNTER). Tenga en cuenta que en la parte superior sabemos la ubicación donde se declara la variable, obtenemos más información, como la línea donde fue declarada y la dirección de la memoria

  4. Lo último que nos falta hacer es obtener el tipo. si echas un vistazo, vemos que el tipo es = <0x522>. Lo que eso significa es que tenemos que ir a 522 del árbol para obtener más información acerca de ese momento. Si vamos a esa parte, esto es lo que obtenemos: Al mirar el árbol, sabemos que SOME_LARGE_VARIABLE es de tipo unsigned long

Editar (pregunta actualizada)

Tengo un programa simple de C:

// it is not important to know what the code does you may skip the code

C Principal

#include <bsp.h> unsigned int AppCtr; unsigned char AppFlag; int SOME_LARGE_VARIABLE; static void AppTest (void); void main (void) { AppCtr = 0; AppFlag = 0; AppTest(); } static void Foo(void){ SOME_LARGE_VARIABLE=15; } static void AppTest (void) { unsigned int i; i = 0; while (i < 200000) { i++; } BSP_Test(); SOME_LARGE_VARIABLE=3; Foo(); }

bsp.c

extern int SOME_LARGE_VARIABLE; extern unsigned char AppFlag; unsigned int long My_GREAT_COUNTER; void BSP_Test (void) { SOME_LARGE_VARIABLE = 5; My_GREAT_COUNTER = 4; }

(el programa no hace nada útil ... Mi objetivo es extraer los nombres de las variables su ubicación donde se declaran y su dirección de memoria )

Cuando compilo el programa, obtengo el archivo a.out que es un archivo elf que contiene información de depuración.

Alguien de la compañía escribió un programa en .net hace 5 años que obtendrá toda esta información del archivo a.out. Esto es lo que devuelve el código:

// Name Display Name Type Size Address

Para este pequeño programa funciona muy bien y también para otros grandes proyectos.

Ese código tiene 2000 líneas de longitud con varios errores y no es compatible con .NET versión 4. Es por eso que estoy tratando de recrearlo.

Entonces mi pregunta es : estoy perdido en el sentido de que no sé qué enfoque tomar para resolver este problema. Estas son las opciones que he estado considerando:

  1. Organice el código erróneo del programa que mostré en la primera imagen y trate de ver qué hace y cómo analiza el archivo a.out para obtener esa información. Una vez que lo entiendo completamente, intento descubrir por qué no es compatible con la versión 3 y 4.

  2. Estoy bien para crear expresiones regex, así que tal vez intente buscar el patrón en el archivo a.out haciendo algo como: Hasta ahora pude encontrar el patrón donde solo hay un archivo (main.c). Pero cuando hay varios archivos, se vuelve más complicado. No lo he intentado todavía Tal vez no será tan complicado y será posible encontrar el patrón.

  3. Instala Cygwin para que pueda usar comandos de Linux en ventanas como objdump , nm o elfread . No he jugado lo suficiente con los comandos cuando uso esos comandos, como readelf -w a.out , obtengo readelf -w a.out más información que la que necesito. Hay algunos contras por los que no he gastado tanto tiempo con este enfoque:

    • Contras: lleva un tiempo instalar cygwin en Windows y al momento de entregar esta aplicación a nuestros clientes no queremos que tengan que instalarla. Tal vez hay una forma de instalar los comandos objdump y elfread sin tener que instalar todo

    • Pros: Si encontramos el comando correcto para usar, no reinventaremos la rueda y ahorraremos tiempo. Tal vez se trata de analizar los resultados de un comando como objdump -w a.out

En caso de que quiera descargar el archivo a.out para analizarlo aquí, lo está .

Resumen

Voy a poder obtener las variables globales en un archivo a.out. Me gustaría saber de qué tipo es cada variable (int, char, ...), qué dirección de memoria tienen y también me gustaría saber en qué archivo se declara la variable (main.c u anotherOtherFile.c). Apreciaré si no tengo que usar cygwin ya que eso hará que sea más fácil de implementar. Como esta pregunta requiere mucho, intenté dividirla en más:

quizás debería eliminar las otras preguntas. lo siento ser redundante.