我正在构建一个构建多个共享库和可执行文件的项目。用于构建这些二进制文件的所有源文件都位于单个/ src目录中。因此,弄清楚哪些源文件用于构建每个二进制文件(存在多对多关系)并不明显。
我的目标是编写一个脚本,为每个二进制文件解析一组C文件,并确保只从中调用正确的函数。
一个选项似乎是尝试从Makefile中提取此信息。但这对生成的文件和标题不起作用(由于依赖于包含)。
另一种选择可能是简单地浏览调用图,但这会变得复杂,因为使用函数指针调用了很多函数。
还有其他想法吗?
答案 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
工具。它显示了对象中定义的所有符号。所以你需要:
nm
并获取所有未定义的符号ldd
以获取其所有动态依赖项的列表(您的二进制文件链接到的.so文件)nm
文件上运行.so
。这将为您提供二进制使用的动态符号的完整列表。
示例:
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的更多信息。