⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elf.txt

📁 序言 1. OBJECT文件 导言 ELF头(ELF Header) Sections String表(String Table) Symbol表(Symbol Table)
💻 TXT
📖 第 1 页 / 共 5 页
字号:
  R_386_JMP_SLOT    7    word32  S
  R_386_RELATIVE    8    word32  B + A
  R_386_GOTOFF	    9    word32  S + A - GOT
  R_386_GOTPC	   10    word32  GOT + A - P

有的重定位类型有不同于简单计算的语义。

* R_386_GOT32

  这种重定位类型计算全局偏移表基地址到符号的全局偏移表
  入口之间的间隔。这样另外通知了 link editor 建立一个全局偏移表 。


* R_386_PLT32

  这种重定位类型计算符号的过程链接表入口地址,并另外通知链接器建立一个
  过程链接表。


* R_386_COPY

  链接器创建该重定位类型用于动态链接。它的偏移成员涉及一个可写段中的一个
  位置。符号表索引指定一个可能存在于当前 object file 或在一个shared object
  中的符号。在执行过程中,动态链接器把和 shared object 符号相关的数据
  拷贝到该偏移所指定的位置。

* R_386_GLOB_DAT

  这种重定位类型用于设置一个全局偏移表入口为指定符号的地址。该特定的重定位
  类型允许你决定符号和全局偏移表入口之间的一致性。


* R_386_JMP_SLOT {*}

  链接器创建该重定位类型用于动态链接。其偏移成员给出了一个过程链接表入口的
  位置。动态链接器修改该过程链接表入口以便向特定的符号地址传递控制。
  [参阅第二部分中的 "Procedure Linkage Table(过程链接表)"]

* R_386_RELATIVE

  链接器创建该重定位类型用于动态链接。其偏移成员给出了包含表达相关地址值
  的一个 shared object 中的位置。动态链接器计算相应的虚拟地址(把该
  shared object 装载地址和相对地址相加)。该类型的重定位入口必须为
  符号表索引指定为 0 。


* R_386_GOTOFF

  这种重定位类型计算符号值和全局偏移表地址之间的不同。另外还通知链接器
  建立全局偏移表(GOT)。



* R_386_GOTPC

  这种重定位类型类似于 R_386_PC32 ,不同的是它在计算中使用全局偏移表。
  这种重定位中引用的符号通常是 _GLOBAL_OFFSET_TABLE_ ,该符号通知了
  链接器建立全局偏移表(GOT)。

   ________________________________________________________________


		2. PROGRAM LOADING AND DYNAMIC LINKING
                   程序装入和动态链接
   ________________________________________________________________


   ======================== Introduction(介绍) =========================


第二部分描述了 object file 信息和创建运行程序的系统行为。其中部分信息
适合所有的系统,其他信息是和特定处理器相关的。


可执行和共享的 object file 静态的描绘了程序。为了执行这样的程序,系统
用这些文件创建动态的程序表现,或进程映像。一个进程映像有用于保存其代码、
数据、堆栈等等的段。这个部分的主要章节讨论如下的内容。


* 程序头(Program header)。该章节补充第一部分,描述和程序运行相关的
  object file 结构。即文件中主要的数据结构、程序头表、定位段映像,也
  包含了为该程序创建内存映像所需要的信息。

* 载入程序(Program loading)。在给定一个 object file 时,系统为了
  让它运行必须将它载入内存。

* 动态链接(Dynamic linking)。在载入了程序之后,系统必须通过解决组
  成该进程的 object file之间的符号引用问题来完成进程映像的过程。

注意:指定了处理器范围的 ELF 常量是有命名约定的。比如,DT_ , PT_ ,
用于特定处理器扩展名,组合了处理器的名称(如 DT_M32_SPECIAL )。
没有使用这种约定但是预先存在的处理器扩展名是允许的。


		       Pre-existing Extensions
                       (预先存在的扩展名)
		       =======================
			      DT_JMP_REL


   ====================== Program Header(程序头)  ======================


一个可执行的或共享的 object file 的程序头表是一个结构数组,每一个
结构描述一个段或其他系统准备执行该程序所需要的信息。一个 object file
段包含一个或多个部分(就象下面的“段目录”所描述的那样)。程序头仅仅对于
可执行或共享的 object file 有意义。一个文件使用 ELF 头的 e_phentsize
和 e_phnum 成员来指定其拥有的程序头大小。[参阅 第一部分中的 "ELF 头"]


+ Figure 2-1: Program Header

  typedef struct {
      Elf32_Word	p_type;
      Elf32_Off		p_offset;
      Elf32_Addr	p_vaddr;
      Elf32_Addr	p_paddr;
      Elf32_Word	p_filesz;
      Elf32_Word	p_memsz;
      Elf32_Word	p_flags;
      Elf32_Word	p_align;
  } Elf32_Phdr;

* p_type

  该成员指出了这个数组的元素描述了什么类型的段,或怎样解释该数组元素的信息。
  类型值和含义如下所述。

* p_offset

  该成员给出了该段的驻留位置相对于文件开始处的偏移。

* p_vaddr

  该成员给出了该段在内存中的首字节地址。

* p_paddr

  在物理地址定位有关联的系统中,该成员是为该段的物理地址而保留的。由于
  System V 忽略了应用程序的物理地址定位,该成员对于可执行文件和共享的
  object 而言是未指定内容的。


* p_filesz

  该成员给出了文件映像中该段的字节数;它可能是 0 。
  
* p_memsz

  该成员给出了内存映像中该段的字节数;它可能是 0 。
 
* p_flags

  该成员给出了和该段相关的标志。定义的标志值如下所述。

* p_align

  就象在后面“载入程序”部分中所说的那样,可载入的进程段必须有合适的
  p_vaddr 、 p_offset 值,取页面大小的模。该成员给出了该段在内存和
  文件中排列值。 0 和 1 表示不需要排列。否则, p_align 必须为正的 2 的幂,
  并且 p_vaddr 应当等于 p_offset 模 p_align 。


某些入口描述了进程段;其他的则提供补充信息并且无益于进程映像。已经
定义的入口可以以任何顺序出现,除非是下面明确声明的。后面是段类型值;
其他的值保留以便将来用于其他用途。


+ Figure 2-2: Segment Types, p_type

  Name             Value
  ====             =====
  PT_NULL              0
  PT_LOAD              1
  PT_DYNAMIC           2
  PT_INTERP            3
  PT_NOTE              4
  PT_SHLIB             5
  PT_PHDR              6
  PT_LOPROC   0x70000000
  PT_HIPROC   0x7fffffff

* PT_NULL

  该数组元素未使用;其他的成员值是未定义的。这种类型让程序头表忽略入口。

* PT_LOAD

  该数组元素指定一个可载入的段,由 p_filesz 和 p_memsz 描述。文件中
  字节被映射到内存段中。如果该段的内存大小( p_memsz )比文件大小( p_filesz )
  要大,则多出的字节将象段初始化区域那样保持为 0 。文件的大小不会比内存大小值大。
  在程序头表中,可载入段入口是以 p_vaddr 的升序排列的。

* PT_DYNAMIC

  该数组元素指定动态链接信息。参阅 后面的“动态部分”以获得更多信息。

* PT_INTERP

  该数组元素指定一个 null-terminated 路径名的位置和大小(作为解释程序)。
  这种段类型仅仅对可执行文件有意义(尽管它可能发生在一个共享 object 上);
  它在一个文件中只能出现一次。如果它出现,它必须先于任何一个可载入段入口。
  参阅 后面的“程序解释器”(Program Interpreter)以获得更多的信息。


* PT_NOTE

  该数组元素指定辅助信息的位置和大小。参阅 后面的“注意部分”以获得细节。

* PT_SHLIB

  该段类型保留且具有未指定的语义。具有一个这种类型数组元素的程序并不
  遵守 ABI 。

* PT_PHDR

  该数组元素(如果出现),指定了程序头表本身的位置和大小(包括在文件中
  和在该程序的内存映像中)。更进一步来说,它仅仅在该程序头表是程序内存映像
  的一部分时才有效。如果它出现,它必须先于任何可载入段入口。参阅 后面的
  “程序解释器”(Program Interpreter)以获得更多的信息。


* PT_LOPROC through PT_HIPROC

  该范围中的值保留用于特定处理器的语义。

注意:除非在别处的特殊要求,所有的程序头的段类型是可选的。也就是说,
一个文件的程序头表也许仅仅包含和其内容相关的元素。



			  Base Address(基地址)

可执行和共享的 object file 有一个基地址,该基地址是与程序的 object file
在内存中映像相关的最低虚拟地址。基地址的用途之一是在动态链接过程中重定位
该程序的内存映像。


一个可执行的 object file 或 一个共享的 object file 的基地址是在
执行的时候从三个值计算而来的:内存载入地址、页面大小的最大值 和 程序可
载入段的最低虚拟地址。就象在“程序载入”中所描述的那样,程序头中的虚拟地址
也许和程序的内存映像中实际的虚拟地址并不相同。为了计算基地址,必须确定与
 PT_LOAD 段 p_vaddr 的最小值相关的内存地址。获得基地址的方法是将内存
地址截去最大页面大小的最接近的整数倍。由于依赖载入内存中的文件类型,
该内存地址和 p_vaddr 值可能匹配也可能不匹配。


就象在第一部分中 "Section" 中描述的那样, .bss section 具有 SHT_NOBITS
的类型。尽管在文件中不占用空间,它在段的内存映像中起作用。通常,没有初始化
的数据驻留在段尾,因此使得在相关的程序头元素中的 p_memsz 比 p_filesz 大。


			  Note Section(注解部分)

有的时候供应商或系统设计者需要用特定的信息标记一个
 object file 以便其他程序检查其兼容的一致性,等等此类。 SHT_NOTE 
类型的 section 和 PT_NOTE 类型的程序头元素能够被用于此目的。 section 
和程序头中的注解信息包含了任意数目的入口,每一个入口的格式都是对应于特定
处理器格式的 4-字节数组。下面的标签有助于解释注释信息的组织形式,但是这些
标签不是规格说明的一部分。


+ Figure 2-3: Note Information

  namesz
  descsz
  type
  name ...
  desc ...

* namesz and name

  名字中 namesz 的第一个字节包含了一个 null-terminated 字符
  表达了该入口的拥有者或始发者。没有正式的机制来避免名字冲突。从
  惯例来说,供应商使用他们自己的名称,比如 "XYZ Computer Company" ,
  作为标志。如果没有提供名字, namesz 值为 0 。 如果有必要,确定
  描述信息4-字节对齐。 这样的填充信息并不包含在namesz 中。


* descsz and desc

  desc 中 descsz 的首字节包含了注解描述符。ABI 不会在一个描述符内容中
  放入任何系统参数。如果没有描述符, descsz 将为 0 。  如果有必要,确定
  描述信息4-字节对齐。 这样的填充信息并不包含在descsz中。


* type

  该 word 给出了描述符的解释。每一个创造着(originator) 控制着自己的类型;
  对于单单一个类型值的多种解释是可能存在的。因此,一个程序必须辨认出该名字
  和其类型以便理解一个描述符。这个时候的类型必须是非负的。ABI 没有定义
  描述符的含义。

为了举例说明,下面的解释段包含两个入口。

+ Figure 2-4: Example Note Segment

           +0   +1   +2   +3
          -------------------
  namesz           7
  descsz           0           No descriptor
    type           1
    name   X    Y    Z    spc 
           C    o    \0   pad
  namesz           7
  descsz           8
    type           3
    name   X    Y    Z    spc
           C    o    \0   pad
    desc         word0
                 word1

注意:系统保留的注解信息没有名字 (namesz==0) ,有一个零长度的名字
 (name[0]=='\0') 现在还没有类型为其定义。所有其他的名字必须至少有
一个非空的字符。


注意:注解信息是可选的。注解信息的出现并不影响一个程序的 ABI 一致性,
前提是该信息不影响程序的执行行为。否则,该程序将不遵循 ABI 并将出现
未定义的行为。


   ===================== Program Loading(程序载入) =====================

当创建或增加一个进程映像的时候,系统在理论上将拷贝一个文件的段到一个虚拟
的内存段。系统什么时候实际地读文件依赖于程序的执行行为,系统载入等等。一个
进程仅仅在执行时需要引用逻辑页面的时候才需要一个物理页面,实际上进程通常会
留下许多未引用的页面。因此推迟物理上的读取常常可以避免这些情况,改良系统的
特性。为了在实践中达到这种效果,可执行的和共享的 object file 必须具有
合适于页面大小取模值的文件偏移和虚拟地址这样条件的段映像。

虚拟地址和文件偏移在 SYSTEM V 结构的段中是模 4KB(0x1000) 或大

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -