如何知道所有编译在一起以生成可执行文件的文件?

时间:2017-12-07 06:17:36

标签: gdb decompiler

我们正在寻找一个程序,通过该程序,我们可以轻松列出所有编译在一起的文件以生成可执行文件。

用例:假设,我们有大型存储库,我们想知道存储库中存在的文件是什么,这些文件被编译为可执行文件(即a.out)

例如:

class ORDER
{
// order properties
private $_db = null;
private $_settings = null;
private $_user = null;

private $_userLevel = 1;

...

/**
 * Order Constructor
 * @param $db
 * @param $settings
 * @param $user
 * @param $need_db_record
 * @return ORDER
 */
public function __construct(&$db, &$settings, &$user, $need_db_record=false, $check_user_change = true)
{
    $this->_db = $db;
    $this->_settings = $settings;
    $this->_user = $user;
...
}


/**
 * Returns class instance
 * @return USER
 */
public function user()
{
    return $this->_user;
}

但它没有列出所有头文件。 请建议。

1 个答案:

答案 0 :(得分:3)

  

如何使用可用的调试符号从可执行文件中提取源代码?

你不能那样做。我猜你是在Linux / x86-64上(你的问题是operating systemABI具体,具体是调试格式)。当然,您应该pass -g(或even -g3)执行可执行文件的所有gcc编译命令。如果没有使用-g-g3选项来编译每个 translation unit(包括共享库的那些!),您可能没有足够的信息。

即使debug information格式为DWARFELF可执行文件也不包含源代码,但只有引用源代码(例如源文件路径,位置为行号和列号)。因此,调试信息包含文件src/foo.c,第34行第5列等内容(但不要提供有关该位置附近src/foo.c内容的内容)。当然,一旦gdb知道文件路径src/foo.c,它就能够读取该源文件(如果可用并且最新的w.r.t.可执行文件),以便它可以列出它。

提取调试元数据是一个不同的问题。理解DWARF后,您可以使用objdumpreadelfaddr2linedwarfdump or libdwarf等工具;你也可以编写脚本gdb(GDB的最新版本可能是extendable在Python或Guile中)并在你的ELF可执行文件中使用它。

也许你应该考虑伊恩·泰勒的libbacktrace。它使用DWARF信息在运行时提供漂亮的回溯。

BTW,cgdb(仅ddd)只有前端gdb,它完成了处理DWARF信息的所有实际工作。它是free software,你可以研究它的源代码。

  

我只有a.out然后我想列出完成的文件名

您可以尝试使用dwarfdump -i | grep DW_AT_decl_file,但可以使用GNU awk命令代替grep。您需要深入了解details of DWARF specifications,并且需要了解有关elf(5)格式的更多信息。

  

它没有列出所有头文件

这是预期的。大多数标头文件不包含任何代码,只有声明(例如printf未在<{1}中实现 但是在C standard library的某个C源文件中,例如在tree/src/stdio/printf.c中,如果您使用musl-libc;它只是在<stdio.h>声明。 DWARF(和其他调试信息格式)正在描述binary code。并且包含一些头文件只是为了访问一些预处理器宏(在预处理时间会扩展或跳过)。

也许你梦见homoiconic编程语言,然后尝试使用Common Lisp(例如SBCL)。

如果您的问题是如何使用/usr/include/stdio.h,请阅读Debugging with GDB手册。

如果您的问题是关于decompilers,请注意这是一项不可能的任务(例如,因为Rice's theorem)。顺便说一下,大多数Linux发行版中的程序通常都是free software,所以很容易获得源代码(你甚至可以避免在Linux上使用专有软件)。

顺便说一句,您也可以通过将more flags传递给gdb,在编译时间做更多事情。您可以pass gcc-H(等等)到-M(除gcc之外)。您甚至可以考虑编写自己的GCC plugin来收集某些数据库中所需的信息(但这可能不值得付出努力)。您还可以考虑改进build automation(例如,在Makefile中添加更多内容)以收集此类信息。顺便说一下,许多大型C程序使用一些metaprogramming技术,通过工具(例如#line directives)或脚本生成一些-g个文件,这些文件可能包含bison 生成的 ,那么你想保留什么样的文件路径??

  

我们正在寻找一个程序,通过该程序,我们可以轻松列出所有编译在一起的文件以生成可执行文件。

如果您正在编写该可执行文件并从其源代码编译它,我建议您在构建时收集该信息。将某些.c和/或-M标记传递给-H可能同样重要,可能会传递到某些生成的 gcc文件中(请参阅{{ 3}}获取灵感;但您的timestamp.c可能包含timestamp.c等提供的信息。您的时间戳文件可能包含this版本控制元数据(如git中生成的)。另请阅读this Makefilereproducible builds