代码之家  ›  专栏  ›  技术社区  ›  Vijay

对象文件包含什么?

  •  44
  • Vijay  · 技术社区  · 15 年前

    在C或C++编译的各个阶段中,我知道生成一个对象文件(即,YyNoNo.o文件)。这个.o文件包含什么?我不能打开它,因为它是一个二进制文件。

    有人能帮我吗?对象文件的内容主要依赖于我们在Unix上使用的编译器吗?

    8 回复  |  直到 10 年前
        1
  •  51
  •   Roddy    15 年前

    对象文件可以包含一堆内容:基本上是以下列表的部分或全部:

    • 符号名称
    • 编译的代码
    • 常量数据,如字符串
    • 导出-对象文件使其他对象文件可用的符号。

        2
  •  11
  •   kriss    15 年前

    有几种标准格式(Unix上的COFF、ELF),基本上它们是用于可执行文件的格式的变体,但缺少一些信息。这些缺失的信息将在链接时完成。

    对象文件格式基本上包含相同的信息:

    • 编译产生的二进制代码(对于目标处理器)
    • 程序的那一部分使用的静态数据(如常量字符串等)。您可以更好地区分BSS(导出的数据)和文本(程序不会修改的数据)。但这对于编译器和链接器来说最为重要。请注意,与二进制代码一样,数据也依赖于目标(大端、小端、32位、64位)。
    • 这部分程序导出的符号表(主要是函数入口点)
    • 此部分程序使用的外部符号表

    当对象链接在一起时,代码中引用外部符号的部分将被实际值替换(好吧,这仍然过于简单化,最后一部分将在运行程序时在加载时完成,但这就是想法)。

    对象文件还可能包含解析导入和导出所必需的更多符号信息(对于调试非常有用)。可以使用strip命令删除该信息。

        3
  •  7
  •   Anirudh Ramanathan    13 年前

    先读一下 wiki page . 你可以用 objdump 检查这样的文件:)

        4
  •  5
  •   Matthew Flaschen    15 年前

    ELF

    ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
    

    相反,动态链接的可执行文件可能看起来像:

    ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
    

    要查看标题(包括节名称),可以使用:

    objdump -x any_name.o
    

    拆卸:

    objdump -d any_name.o
    
        5
  •  5
  •   ShinTakezou    15 年前

    可以 打开!别害怕,你只需要合适的工具!作为二进制数据,文本编辑器当然不是正确的工具;一个合适的工具可以是十六进制编辑器,或者像emacs这样的高级编辑器,或者一个工具,它不是简单地“输出”字节的“十六进制”表示形式,让你独自解释数据,而是知道特定的格式,并在某种程度上正确地“解释”数据(例如,GIMP将PNG文件解释为图像并显示它,PNG分析器将“分解”PNG部分中的数据(显示以特定字节表示的标志,…等等)。

    在您的例子中,一般的答案是对象文件包含您编译的代码(和数据),加上链接器所需的所有额外信息,以及最终更多的信息。

    this , this this , this ...

    其中每一个都有分析内容的工具;例如 readelf 对于精灵来说, objdump 对于多种格式(请尝试 objdump -i )取决于它是如何编译的。

        6
  •  4
  •   ChrisF    15 年前

    对象文件是已编译的源文件。

    这意味着它是机器代码,这取决于目标平台(如果您真的愿意,可以在Windows上为Unix编译)和所使用的编译器。不同的编译器将从同一源文件生成不同的机器代码。

        7
  •  2
  •   soulmerge    15 年前

    linker 生成可执行文件。它本质上是一堆带有命名部分的机器代码指令(对应于您的函数)。来自维基百科的 Object File

    在计算机科学中,对象文件是 一个有组织的单独的, 机器命名序列 代码[需要引证]。每个序列, 或对象,通常包含 可能完成一些任务 元数据(例如重新定位 信息、评论、程序 符号、调试或分析 信息)。链接器通常是 通过组合对象的部分 文件夹。

        8
  •  1
  •   INS    15 年前

    在GNU编译环境中,可以在可执行文件和对象文件中使用objdump进行查看。

    如您所见,该对象仅包含编译文件中声明/引用的函数代码(该文件仅包含带有scanf调用和printf调用的main函数)。

    $ objdump -t scanf_sample.o
    
    scanf_sample.o:     file format pe-i386
    
    SYMBOL TABLE:
    [  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 scanf_sample.c
    File
    [  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
    [  3](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
    AUX scnlen 0x91 nreloc 9 nlnno 0
    [  5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
    AUX scnlen 0x0 nreloc 0 nlnno 0
    [  7](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
    AUX scnlen 0x0 nreloc 0 nlnno 0
    [  9](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
    AUX scnlen 0x54 nreloc 0 nlnno 0
    [ 11](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___main
    AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
    [ 13](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __alloca
    [ 14](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _memset
    [ 15](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _scanf
    [ 16](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _printf
    

    如果在可执行文件上使用objdump,您可以看到 更多 函数(除了对象内部的函数)。这证明了对象文件只包含源文件中定义的函数以及对其他函数的引用。这些参考将在链接阶段解决。

    linking , compilation objects .

    推荐文章