【发布时间】:2012-06-12 19:20:08
【问题描述】:
编辑(更新问题)
我有一个简单的 C 程序:
// it is not important to know what the code does you may skip the code
main.c
#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;
}
(程序没有做任何有用的事情......我的目标是提取变量名,它们被声明的位置和它们的内存地址)
当我编译程序时,我得到文件a.out,这是一个包含调试信息的elf文件。
公司有人在 5 年前在 .net 中编写了一个程序,该程序将从 a.out 文件中获取所有这些信息。这是代码返回的内容:
// Name Display Name Type Size Address
对于这个小程序来说效果很好,也适用于其他大型项目。
该代码有 2000 行长,有几个错误,它不支持 .NET 版本 4。这就是我尝试重新创建它的原因。
所以我的问题是,我很迷茫,我不知道要采取什么方法来解决这个问题。这些是我一直在考虑的选项:
整理我在第一张图片上显示的程序的错误代码,并尝试查看它的作用以及它如何解析 a.out 文件以获取该信息。一旦我完全理解它,试着找出它为什么不支持版本 3 和 4。
我可以创建正则表达式,所以可以尝试通过执行以下操作在 a.out 文件中查找模式: 到目前为止,我能够找到只有一个文件的模式(main.c)。但是当有多个文件时,它会变得更加复杂。我还没试过。或许它不会那么复杂,并且可以找到模式。
-
安装Cygwin 这样我就可以在Windows 上使用Linux 命令,例如
objdump、nm或elfread。当我使用诸如readelf -w a.out之类的命令时,我对这些命令的使用还不够,我得到了我需要的更多信息。我没有花太多时间使用这种方法有一些缺点:缺点:在 Windows 上安装 cygwin 需要一些时间,并且在将此应用程序提供给我们的客户时,我们不希望他们必须安装它。也许有一种方法可以只安装命令 objdump 和 elfread 而不必安装整个东西
优点:如果我们找到正确的命令来使用,我们将不会重新发明轮子并节省一些时间。可能是解析
objdump -w a.out等命令结果的问题
如果您想下载 a.out 文件以解析它here it is。
总结
我将能够获取 a.out 文件中的全局变量。我想知道每个变量是什么类型(int、char、..),它们有什么内存地址,我还想知道在哪个文件上声明了变量(main.c 或 someOtherFile.c)。如果我不必使用 cygwin,我将不胜感激,因为这将使其更易于部署。 由于这个问题要求很多,我试图将其拆分为更多:
也许我应该删除其他问题。很抱歉是多余的。
【问题讨论】:
-
您的目标是获取全局变量列表吗?还是从 a.out 文件中获取全局变量?还是要修复您拥有的工具?显然,如果有多个编译单元,则查看 one a.out 文件不会为您提供所有全局变量的列表。
-
... 您的大部分麻烦似乎还在于对目标文件格式缺乏了解。如果你不愿意投入足够的时间去理解它,你怎么期望得到一个好的结果?
-
a.out 文件包含 dwarf 信息(调试信息)。我知道并非所有 a.out 文件都包含此信息。抱歉没有提到......
标签: gcc compiler-construction cygwin elf dwarf