【问题标题】:Flags in objdump output of object file目标文件的 objdump 输出中的标志
【发布时间】:2012-06-27 02:30:53
【问题描述】:

在某个目标文件上有 objdump 的输出:

$ objdump -h main.o

main.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000000b  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000040  2**2
                  ALLOC
  3 .note.GNU-stack 00000000  00000000  00000000  00000040  2**0
                  CONTENTS, READONLY, CODE

这些标志CONTENTS、ALLOC、LOAD等是什么意思?

【问题讨论】:

    标签: linux elf objdump


    【解决方案1】:

    您看到的是对目标文件中每个节的 ELF 段标志、节类型和节标志的组合的解释。

    • LOAD 表示该部分位于可加载段中,即在创建进程时可以将其内容从文件读取到内存中

    部分标志在 System V 应用程序二进制接口的 Chapter 4 中有详细记录,尽管名称与 objdump 显示的名称略有不同。

    • CODE 表示该段包含可执行代码;它由部分标题中的SHF_EXECINSTR 标志指示
    • DATA 表示该部分不可执行但可写,由 SHF_WRITE 标志的存在表示
    • READONLY 表示该段既不可执行也不可写,应放在只读内存页中
    • ALLOC 表示该段占用内存,例如在创建进程时,实际上分配内存页来保存节内容,由SHF_ALLOC 标志指示。某些部分,例如那些包含调试信息的,在正常程序执行期间不会读入内存,也不会标记为ALLOC以节省内存。

    SHT_PROGBITS 类型的部分在文件中有相应的内容,显示为CONTENTS。某些部分在文件中没有对应的内容,例如.bss 部分,其类型为 SHT_NOBITS

    .text 部分包含程序可执行代码。它显示为CONTENTS,因为它是SHT_PROGBITS 类型。应该为这个部分保留内存,因为它是ALLOC,并且它的内容应该从文件中加载,因为它被放置在一个LOAD-able 段中。程序代码通常是不可修改的,因此该部分被放置在只读存储器中。它包含要执行的指令以及 CODE 标志。

    初始化 带有静态存储类的变量进入.data 部分。它们的初始值存储在文件中,并在创建过程时从那里读取。在 C/C++ 中,这些是适当初始化的全局变量、静态局部变量和 C++ 静态成员变量,例如static int a = 10;。 Fortran 将初始化的 SAVE-d 变量和 COMMON 块放在其中,并在其中使用块 DATA 语句为其赋予初始值。

    .bss 部分(历史名称,Block Started by Symbol 的缩写)是最简单的部分。它保存具有静态存储类的 未初始化 变量。它是SHT_NOBITS 类型的部分,在文件中不占用空间。内存为ALLOC-ated,但没有从文件中读取任何内容来预填充内存 - 它只是保持内核内存分配器提供的全零。

    常量通常进入.rodata 部分(在您的示例中不存在),它看起来像.data,但未标记为可写,因此显示为READONLY

    【讨论】:

    • 链接 #2 现在已断开。 :(
    • 我尝试在可重定位文件(原始 .o 文件,即没有程序头的文件)上运行 objdump -h,但它仍然列出了具有 LOAD 属性的部分(例如 .text)。所以我不清楚 LOAD 和 ALLOC 之间的区别是什么。也许只是 LOAD = ALLOC && CONTENTS
    • @TroelsFolke,是的,objdump 所基于的 BFD 库有一个硬编码逻辑,即占用二进制 (CONTENTS) 和内存 (ALLOC) 空间的部分应该去进入可加载段 (LOAD)。 LOAD 是一个段属性,由于.o 文件没有程序头,它在objdump 的输出中的存在是“假的”(或者更确切地说是假设的)。
    • @TroelsFolke,还值得一提的是,objdump 显示的是抽象 BFD 部分,具有通过组合底层对象文件类型元素的属性构建的抽象属性。因此,readelf 更适合分析 ELF 文件。
    【解决方案2】:

    Ubuntu elf man page 上找到了一些信息,这只是我的理解。
    我认为它们是来自program headersection header 的信息。

    LOAD: may correspond to PT_LOAD in the Program header table. Brief description:
    It specifies the type of that particular element in the program header table.
    The array element specifies a loadable segment
    
    ALLOC: may correspond to SHF_ALLOC in the section table. Brief description:
    Its specifies the flag of that particular element in the section header.
    This  section  occupies  memory during process execution.
    
    CODE/ DATA: indicates the belonging segment
    
    READONLY: specifies a read-only segment
    
    CONTENTS: I didn't find anything to conclude.
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多