如何找出用于构建二进制文件的* .c和* .h文件?

时间:2012-08-29 21:17:33

标签: c linux gcc build

我正在构建一个构建多个共享库和可执行文件的项目。用于构建这些二进制文件的所有源文件都位于单个/ src目录中。因此,弄清楚哪些源文件用于构建每个二进制文件(存在多对多关系)并不明显。

我的目标是编写一个脚本,为每个二进制文件解析一组C文件,并确保只从中调用正确的函数。

一个选项似乎是尝试从Makefile中提取此信息。但这对生成的文件和标题不起作用(由于依赖于包含)。

另一种选择可能是简单地浏览调用图,但这会变得复杂,因为使用函数指针调用了很多函数。

还有其他想法吗?

5 个答案:

答案 0 :(得分:9)

您可以先使用调试信息(gcc -g)编译项目,然后使用objdump获取包含的源文件。

objdump -W <some_compiled_binary>

矮人格式应包含您要查找的信息。

 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    < c>   DW_AT_producer    : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x28): test_3.c    
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x36): /home/auselen/trials    
    <19>   DW_AT_low_pc      : 0x82f0   
    <1d>   DW_AT_high_pc     : 0x8408   
    <21>   DW_AT_stmt_list   : 0x0  

在这个例子中,我从test_3编译了目标文件,它位于... / trials目录中。当然,你需要编写一些脚本来收集相关的源文件名。

答案 1 :(得分:2)

这是一个想法,需要根据您的特定构建进行优化。进行构建,使用脚本(例如script log.txt make clean all)进行记录。最后一个(或最后一个)步骤应该是目标文件的链接。 (提示:寻找cc -o <your_binary_name>)。该行应链接所有.o个文件,这些文件应在树中具有相应的.c个文件。然后grep那些.c文件,包含所有包含的头文件。

如果树中的.c文件中有重复的名称,那么我们需要查看链接器行中的完整路径,或者从Makefile开始工作。

Mahmood在下面建议的内容也应该有效。如果您有带符号的图像,strings <debug_image> | grep <full_path_of_src_directory>应该会为您提供C文件列表。

答案 2 :(得分:2)

首先,您需要将调试符号与刚刚编译的二进制文件分开。检查这个问题如何: How to generate gcc debug symbol outside the build target?

然后您可以尝试自己解析此文件。我知道如何为Visual Studio这样做,但是当你使用GCC我将无法进一步帮助你。

答案 3 :(得分:1)

您可以使用unix nm工具。它显示了对象中定义的所有符号。所以你需要:

  1. 在您的二进制文件上运行nm并获取所有未定义的符号
  2. 在您的二进制文件上运行ldd以获取其所有动态依赖项的列表(您的二进制文件链接到的.so文件)
  3. 在您在步骤2中找到的每个nm文件上运行.so
  4. 这将为您提供二进制使用的动态符号的完整列表。

    示例:

    nm -C --dynamic /bin/ls
    ....skipping.....
    00000000006186d0 A _edata
    0000000000618c70 A _end
                     U _exit
    0000000000410e34 T _fini
    0000000000401d88 T _init
                     U _obstack_begin
                     U _obstack_newchunk
                     U _setjmp
                     U abort
                     U acl_extended_file
                     U bindtextdomain
                     U calloc
                     U clock_gettime
                     U closedir
                     U dcgettext
                     U dirfd
    

    所有那些大写字母为“U”的符号都由ls命令使用。

答案 4 :(得分:1)

如果您的目标是分析C源文件,则可以通过自定义GCC编译器来实现。您可以将MELT用于此目的(MELT是一种扩展GCC的高级域特定语言) - 在GCC中添加您自己的MELT编码分析通道,但您应该首先了解GCC中端内部表示(Gimple,Tree,......)。

自定义GCC需要几天的工作(主要是因为GCC内部细节非常复杂)。

随时向我询问有关MELT的更多信息。