【问题标题】:Object files in an executable in LinuxLinux 中可执行文件中的目标文件
【发布时间】:2010-10-22 19:55:08
【问题描述】:

有没有办法找到在 Linux 中生成当前可执行文件的目标文件(具体是 RHEL)。我知道可以使用“nm”来查找导出的符号,“ldd”来查找依赖的共享对象。

但我找不到命令来找出可执行文件所包含的对象 (.o) 文件的名称。有可能吗?

【问题讨论】:

    标签: linux executable object-files


    【解决方案1】:

    类似于 Mikels 的回答,但使用不同的工具(可能)为您提供更清晰的输出。

    过去,我有幸使用名为 DIVA 的调试信息分析器工具。它是免费和开源的,您可以在这里找到它:

    https://github.com/SNSystems/DIVA

    虽然使用 DIVA 无法找到链接到哪些目标文件以生成可执行文件,但您可以使用它来找出编译单元。

    我赶紧整理了一个小例子如下

    a.cpp

    int a() {
      return 1;
    }
    

    啊。

    int a();
    

    b.cpp

    int b() {
      return 2;
    }
    

    b.h

    int b();
    

    c.cpp

    #include "a.h"
    #include "b.h"
    
    int main() {
      return a + b;
    }
    

    使用以下选项使用 clang 编译它们

    $ clang a.cpp b.cpp c.cpp -o test.elf -g -O0
    

    使用以下选项在 test.elf 上运行 DIVA:

    $ diva --show-none test.elf
    

    应该产生以下输出

    {InputFile} "test.elf"
       {CompileUnit} "a.cpp"
       {CompileUnit} "b.cpp"
       {CompileUnit} "c.cpp"
    

    【讨论】:

    • 我应该补充一点,您正在测试的可执行文件需要使用 DWARF 格式的调试信息进行编译,DIVA 才能成功显示编译单元。
    【解决方案2】:

    我没有足够的声誉来添加评论,但要扩展 Mikel Rychliski 使用 readelf 的建议,您可以使用 awk 提取源文件的路径:

    readelf --debug-dump=info --dwarf-depth=1 hw exe_to_examine | awk '/DW_AT_name/ {file=$8} /DW_AT_comp_dir/ {print $8 "/" file}'
    

    这会输出源文件(在我的例子中是 .cpp 文件)的完整路径,这些文件可能与目标文件非常匹配(取决于您的构建系统)。

    【讨论】:

      【解决方案3】:

      目标文件在链接后转换为可执行文件。如果链接是共享的,那么您可以通过共享库 (ldd) 获得它。但是,如果链接是静态的,那么只有一种方法,即通过调试信息。您可以在 RHEL(或 Fedora)中安装 debuginfo 包。以下是说明

      然后按照此处所述使用 gdb info sources

      这将为您提供源文件列表。但要真正获得目标文件,您需要深入了解构建工具 (rpmbuild)。要实际运行 rpmbuild,您需要 Source RPM 软件包,您可以使用此处列出的说明获取该软件包:

      现在您可以自己构建包,并剖析哪个.o 文件生成可执行文件。

      希望对你有帮助。

      【讨论】:

        【解决方案4】:

        对象文件的原始名称不存储在 DWARF 调试信息中。

        每个目标文件在.debug_info 部分都有一个DW_TAG_compile_unit 条目。此条目包含对“主要源文件”的引用 编译单元的来源”,但不是目标文件的名称。The DWARF standard 包含可以为每个编译单元存储的属性列表(第 3.1.1 节,第 44 页,pdf 第 58 页)。

        您可以使用以下命令查看存储的信息:

        $ readelf --debug-dump=info --dwarf-depth=1 hw
        

        输出:

        Contents of the .debug_info section:
        <some compilation units removed>       
          Compilation Unit @ offset 0x133:
           Length:        0x8b (32-bit)
           Version:       4
           Abbrev Offset: 0x64
           Pointer Size:  4
         <0><13e>: Abbrev Number: 1 (DW_TAG_compile_unit)
            <13f>   DW_AT_producer    : (indirect string, offset: 0x131): GNU C11 5.3.0 -mtune=generic -march=pentiumpro -g
            <143>   DW_AT_language    : 12      (ANSI C99)
            <144>   DW_AT_name        : (indirect string, offset: 0x163): hw.c
            <148>   DW_AT_comp_dir    : (indirect string, offset: 0x168): /home/mikel/src/hw
            <14c>   DW_AT_low_pc      : 0x80483db
            <150>   DW_AT_high_pc     : 0x2e
            <154>   DW_AT_stmt_list   : 0xea
         <1><158>: ...
        <some compilation units removed>
        

        【讨论】:

          【解决方案5】:

          你也可以使用objdump(只要编译的可执行文件和对象带有调试信息):

          # gcc -g -c -o /tmp/some_object.o /tmp/some_object.c
          # gcc -g -o /tmp/file /tmp/file.c /tmp/some_object.o
          # objdump -g /tmp/file | awk 'BEGIN{out=0} /Directory Table/{out=1} /Line Number Statements/{out=0} {if(out){print $0}}'
           The Directory Table (offset 0x1b):
            1     /tmp
          
           The File Name Table (offset 0x21):
            Entry Dir     Time    Size    Name
            1     1       0       0       file.c
          
           The Directory Table (offset 0x5a):
            1     /tmp
          
           The File Name Table (offset 0x60):
            Entry Dir     Time    Size    Name
            1     1       0       0       some_object.c
          

          awk 仅用于提取相关信息(如果不使用,您将在可执行文件和对象中获得完整的调试信息)。

          【讨论】:

            【解决方案6】:

            除了nullptr,“共享对象”是指其他共享库(链接),而不是原始对象(未链接)

            【讨论】:

              【解决方案7】:

              如果它已经用调试信息编译过,是的。使用 gdb (man gdb) 查找信息。

              如果它在没有调试信息的情况下没有被编译。你运气不好。

              【讨论】:

                猜你喜欢
                • 2011-01-08
                • 1970-01-01
                • 2020-10-12
                • 1970-01-01
                • 2015-05-02
                • 2010-09-21
                • 2010-10-23
                • 1970-01-01
                • 2023-03-07
                相关资源
                最近更新 更多