免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1706 | 回复: 0
打印 上一主题 下一主题

elf文件格式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-09 20:36 |只看该作者 |倒序浏览

  elf文件格式--
   另一文本方式的elf文档
   
http://elfhack.whitecell.org/mydocs/ELF_chinese.txt
   
write by breadbox Email:breadbox@muppetlabs.com  
译:alert7  from m4in security team  
            
http://www.patching.net
   isearthling
       19:45 2001-5-16
译者注:
   由于翻译者水平有限(包括技术水平和翻译水平:(),所以
   有些地方或许比较难懂,可能还有理解错误的地方,如果有
   任何的问题,欢迎email:alert7@21cn.com
   我们会虚心接受的,会在以后的修订中更正过来。
   (总不能误导后来的读者,所以如果你英文比较好的话,还
   是看原版吧:),不要丢鸡蛋啊^_^)
   
这份文档和原始的那份ELF文件格式的文档有以下一个不同:
1. 忽略了分页记数 。
2. 因为上述原因,在这篇内容目录中去掉了页号,索引完全被忽略。
   (不象Postscript文档,txt文本可以用来搜索)
3. 页标题的内容和文章的页脚已经在开始的时候被换掉了。
4. 文章的排版也已经修正过了。
5. 如果必要,不同的字体已经被忽略了。大部分地方,这片文档能让你
   充分的理解。然而,很小的地方,原始的文档使用了斜体字来指出文
   章中的字符变量。在那种情况下,本文使用。在原始的文档
   中没有出现尖括号。
6. 原始的文档有三个错误,如果你是不经意读它的话,是不会明显
   就能找出的。但是在这里,明确的被鉴别出来了。
   我很冒昧的纠正了那些错误。在他们的位置用一个{*}做上了标记。
   可能还有其他我没有看出来的的错误。
如果有如何其他的区别都是我的责任。这样的错误请
mailto:breadbox@muppetlabs.com
.
Brian Raiter
[Last edited Fri Jul 23 1999]
   ________________________________________________________________
   EXECUTABLE AND LINKABLE FORMAT (ELF)
      Portable Formats Specification, Version 1.1
      Tool Interface Standards (TIS)
   ________________________________________________________________
   =========================== Contents 内容===========================
   序言
1. OBJECT文件
   导言
   ELF头(ELF Header)
   Sections
   String表(String Table)
   Symbol表(Symbol Table)
   重定位(Relocation)
2. 程序装载与动态连接
   导言
   Program头(Program Header)
   Program装载(Program Loading)
   Dynamic连接(Dynamic Linking)
3. C LIBRARY
   C Library
   ________________________________________________________________
             导言
   ________________________________________________________________
    ELF: 可执行连接格式
可执行连接格式是UNIX系统实验室(USL)作为应用程序二进制接口
(Application Binary Interface(ABI)而开发和发布的。工具接口标准委
员会(TIS)选择了正在发展中的ELF标准作为工作在32位INTEL体系上不同操
作系统之间可移植的二进制文件格式。
假定开发者定义了一个二进制接口集合,ELF标准用它来支持流线型的软件
发展。 应该减少不同执行接口的数量。因此可以减少重新编程重新编译的
代码。
    关于这片文档
这篇文档是为那些想创建目标文件或者在不同的操作系统上执行文件的开发
着准备的。它分以下三个部分:
* 第一部分, “目标文件Object Files”描述了ELF目标文件格式三种主要
  的类型。
* 第二部分, “程序转载和动态连接”描述了目标文件的信息和系统在创建
  运行时程序的行为。
* 第三部分, “C 语言库”列出了所有包含在libsys中的符号,标准的ANSI C
  和libc的运行程序,还有libc运行程序所需的全局的数据符号。
注意: 参考的X86体系已经被改成了Intel体系。
   ________________________________________________________________
      1. 目标文件(Object file)
   ________________________________________________________________
   ========================= 序言 =========================
第一部分描述了iABI的object文件的格式, 被称为ELF(Executable
and Linking Format). 在object文件中有三种主要的类型。
* 一个可重定位(relocatable)文件保存着代码和适当的数据,用来和其他的
  object文件一起来创建一个可执行文件或者是一个共享文件。
* 一个可执行(executable)文件保存着一个用来执行的程序;该文件指出了
  exec(BA_OS)如何来创建程序进程映象。
* 一个共享object文件保存着代码和合适的数据,用来被下面的两个链接器
  链接。第一个是连接编辑器[请参看ld(SD_CMD)],可以和其他的可重定位和
  共享object文件来创建其他的object。第二个是动态链接器,联合一个
  可执行文件和其他的共享object文件来创建一个进程映象。
一个object文件被汇编器和联接器创建, 想要在处理机上直接运行的object
文件都是以二进制来存放的。那些需要抽象机制的程序,比如象shell脚本,
是不被接受的。
在介绍性的材料过后,第一部分主要围绕着文件的格式和关于如何建立程序。
第二部分也描述了object文件的几个组成部分,集中在执行程序所必须的信息上。
        文件格式
Object文件参与程序的联接(创建一个程序)和程序的执行(运行一个程序)。
object 文件格式提供了一个方便有效的方法并行的视角看待文件的内容,
在他们的活动中,反映出不同的需要。例 1-1图显示了一个object文件的
组织图。
+ 图1-1: Object文件格式
  Linking 视角                      Execution 视角
  ============                      ==============
  ELF header                        ELF header
  Program header table (optional)   Program header table
  Section 1                         Segment 1
  ...                               Segment 2
  Section n                         ...
  Section header table              Section header table (optional)
一个ELF头在文件的开始,保存了路线图(road map),描述了该文件的组织情况。
sections保存着object 文件的信息,从连接角度看:包括指令,数据,
符号表,重定位信息等等。特别sections的描述会出项在以后的第一部分。
第二部分讨论了段和从程序的执行角度看文件。
假如一个程序头表(program header table)存在,那么它告诉系统如何来创建一
个进程的内存映象。被用来建立进程映象(执行一个程序)的文件必须要有一个程
序头表(program header table);可重定位文件不需要这个头表。一个
section头表(section header table)包含了描述文件sections的信息。每个
section在这个表中有一个入口;每个入口给出了该section的名字,大小,
等等信息。在联接过程中的文件必须有一个section头表;其他object文件可要
可不要这个section头表。
注意: 虽然图显示出程序头表立刻出现在一个ELF头后,section头表跟着其他
section部分出现,事实是的文件是可以不同的。此外,sections和段(segments)
没有特别的顺序。只有ELF头(elf header)是在文件的固定位置。
    数据表示
object文件格式支持8位、32位不同的处理器。不过,它试图努力的在更大
或更小的体系上运行。因此,object文件描绘一些控制数据需要用与机器
无关的格式,使它尽可能的用一般的方法甄别object文件和描述他们的内容。
在object文件中剩余的数据使用目标处理器的编码方式,不管文件是在哪台
机子上创建的。
+ 图 1-2: 32-Bit Data Types
  Name           Size Alignment   Purpose
  ====           ==== =========   =======
  Elf32_Addr      4       4       Unsigned program address
  Elf32_Half      2       2       Unsigned medium integer
  Elf32_Off       4       4       Unsigned file offset
  Elf32_Sword     4       4       Signed large integer
  Elf32_Word      4       4       Unsigned large integer
  unsigned char   1       1       Unsigned small integer
所有的object文件格式定义的数据结构是自然大小(natural size),为相关
的类型调整指针。如果需要,数据结构中明确的包含了确保4字节对齐的填
充字段。来使结构大小是4的倍数。数据从文件的开始也有适当的对齐。
例如,一个包含了Elf32_Addr成员的结构将会在文件内对齐到4字节的边界上。
因为移植性的原因,ELF不使用位字段。
   ========================== ELF Header ==========================
一些object文件的控制结构能够增长的,所以ELF头包含了他们目前的大小。
假如object文件格式改变,程序可能会碰到或大或小他们不希望的控制结构。
程序也有可能忽略额外(extra)的信息。
对待来历不明(missing)的信息依靠上下文来解释,假如扩展被定义,它们
将会被指定。
+ 图 1-3: ELF Header
  #define EI_NIDENT       16
  typedef struct {
      unsigned char       e_ident[EI_NIDENT];
      Elf32_Half          e_type;
      Elf32_Half          e_machine;
      Elf32_Word          e_version;
      Elf32_Addr          e_entry;
      Elf32_Off           e_phoff;
      Elf32_Off           e_shoff;
      Elf32_Word          e_flags;
      Elf32_Half          e_ehsize;
      Elf32_Half          e_phentsize;
      Elf32_Half          e_phnum;
      Elf32_Half          e_shentsize;
      Elf32_Half          e_shnum;
      Elf32_Half          e_shstrndx;
  } Elf32_Ehdr;
* e_ident
  这个最初的字段标示了该文件为一个object文件,提供了一个机器无关
  的数据,解释文件的内容。在下面的ELF的鉴别(ELF Identification)
  部分有更详细的信息。
* e_type
  该成员确定该object的类型。
               Name        Value  Meaning
               ====        =====  =======
               ET_NONE         0  No file type
               ET_REL          1  Relocatable file
               ET_EXEC         2  Executable file
               ET_DYN          3  Shared object file
        ET_CORE         4  Core file
        ET_LOPROC  0xff00  Processor-specific
        ET_HIPROC  0xffff  Processor-specific
  虽然CORE的文件内容未被指明,类型ET_CORE是保留的。
  值从 ET_LOPROC 到 ET_HIPROC(包括ET_HIPROC)是为特殊的处理器保留的。
  如有需要,其他保留的变量将用在新的object文件类型上。
* e_machine
  该成员变量指出了运行该程序需要的体系结构。
                    Name      Value  Meaning
             ====      =====  =======
                    EM_NONE       0  No machine
      EM_M32        1  AT&T WE 32100
                    EM_SPARC      2  SPARC
                    EM_386        3  Intel 80386
                    EM_68K        4  Motorola 68000
                    EM_88K        5  Motorola 88000
                    EM_860        7  Intel 80860
                    EM_MIPS       8  MIPS RS3000
  如有需要,其他保留的值将用到新的机器类型上。特殊处理器名使用机器名来
  区别他们。例如,下面将要被提到的成员flags使用前缀EF_;在一台EM_XYZ机器
  上,flag称为WIDGET,那么就称为EF_XYZ_WIDGET。
* e_version
  这个成员确定object文件的版本。
                 Name         Value  Meaning
                 ====         =====  =======
                 EV_NONE          0  Invalid version
   EV_CURRENT       1  Current version
  值1表示原来的文件格式;创建新版本就用>1的数。EV_CURRENT值(上面给
  出为1)如果需要将指向当前的版本号。
* e_entry
  该成员是系统第一个传输控制的虚拟地址,在那启动进程。假如文件没有
  如何关联的入口点,该成员就保持为0。
* e_phoff
  该成员保持着程序头表(program header table)在文件中的偏移量(以字节计数)。
  假如该文件没有程序头表的的话,该成员就保持为0。
* e_shoff
  该成员保持着section头表(section header table)在文件中的偏移量(以字节
  计数)。假如该文件没有section头表的的话,该成员就保持为0。
* e_flags
  该成员保存着相关文件的特定处理器标志。
  flag的名字来自于EF__。看下机器信息“Machine Information”
  部分的flag的定义。
* e_ehsize
  该成员保存着ELF头大小(以字节计数)。
* e_phentsize
  该成员保存着在文件的程序头表(program header table)中一个入口的大小
  (以字节计数)。所有的入口都是同样的大小。
* e_phnum
  该成员保存着在程序头表中入口的个数。因此,e_phentsize和e_phnum
  的乘机就是表的大小(以字节计数).假如没有程序头表(program header table),
  e_phnum变量为0。
* e_shentsize
  该成员保存着section头的大小(以字节计数)。一个section头是在section
  头表(section header table)的一个入口;所有的入口都是同样的大小。
* e_shnum
  该成员保存着在section header table中的入口数目。因此,e_shentsize和
  e_shnum的乘积就是section头表的大小(以字节计数)。
  假如文件没有section头表,e_shnum值为0。
* e_shstrndx
  该成员保存着跟section名字字符表相关入口的section头表(section header
  table)索引。假如文件中没有section名字字符表,该变量值为SHN_UNDEF。
  更详细的信息 看下面“Sections”和字符串表(“String Table”) 。
     ELF 鉴别(Identification)
在上面提到的,ELF提供了一个object文件的框架结构来支持多种处理机,多
样的数据编码方式,多种机器类型。为了支持这个object文件家族,最初的几
个字节指定用来说明如何解释该文件,独立于处理器,与文件剩下的内容无关。
ELF头(也就是object文件)最初的几个字节与成员e_ident相一致。
+ 图 1-4: e_ident[] Identification Indexes
  Name           Value  Purpose
  ====           =====  =======
  EI_MAG0      0  File identification
  EI_MAG1      1  File identification
  EI_MAG2      2  File identification
  EI_MAG3      3  File identification
  EI_CLASS      4  File class
  EI_DATA      5  Data encoding
  EI_VERSION      6  File version
  EI_PAD      7  Start of padding bytes
  EI_NIDENT     16  Size of e_ident[]
通过索引访问字节,以下的变量被定义。
* EI_MAG0 to EI_MAG3
  文件的前4个字符保存着一个魔术数(magic number),用来确定该文件是否
  为ELF的目标文件。
                  Name       Value  Position
                  ====       =====  ========
    ELFMAG0    0x7f   e_ident[EI_MAG0]
                  ELFMAG1    'E'    e_ident[EI_MAG1]
                  ELFMAG2    'L'    e_ident[EI_MAG2]
                  ELFMAG3    'F'    e_ident[EI_MAG3]
* EI_CLASS
  接下来的字节是e_ident[EI_CLASS],用来确定文件的类型或者说是能力。
                 Name           Value  Meaning
                 ====           =====  =======
                 ELFCLASSNONE       0  Invalid class
                 ELFCLASS32         1  32-bit objects
   ELFCLASS64         2  64-bit objects
  文件格式被设计成在不同大小机器中可移植的,在小型机上的不用大型机上
  的尺寸。类型ELFCLASS32支持虚拟地址空间最大可达4GB的机器;使用上面
  定义过的基本类型。
  类型ELFCLASS64为64位体系的机器保留。它的出现表明了object文件可能
  改变,但是64位的格式还没有被定义。如果需要,其他类型将被定义,会
  有不同的类型和不同大小的数据尺寸。
* EI_DATA
  字节e_ident[EI_DATA]指定了在object文件中特定处理器数据的编码
  方式。当前定义了以下编码方式。
             Name           Value  Meaning
             ====           =====  =======
      ELFDATANONE        0  Invalid data encoding
             ELFDATA2LSB        1  See below
             ELFDATA2MSB        2  See below
  更多的关于编码的信息出现在下面。其他值保留,将被分配一个新的编码
  方式,当然如果必要的话。
* EI_VERSION
  字节e_ident[EI_VERSION]表明了ELF头的版本号。
  现在这个变量的是一定要设为EV_CURRENT,作为上面e_version的解释。
* EI_PAD
  该变量标识了在e_ident中开始的未使用的字节。那些字节保留并被设置为
  0;程序把它们从object 文件中读出但应该忽略。假如当前未被使用的字节
  有了新的定义,EI_PAD变量将来会被改变。
一个文件的数据编码指出了如何来解释一个基本的object文件。在上述的
描述中,类型ELFCLAS32文件使用占用1,2和4字节的目标文件。下面定义的
编码方式,用下面的图来描绘。数据出现在左上角。
ELFDATA2LSB编码指定了2的补数值。
最小有意义的字节占有最低的地址。
+ 图1-5: Data Encoding ELFDATA2LSB
               0------+
      0x0102   |  01  |
               +------+
               0------1------+
    0x010204   |  02  |  01  |
               +------+------+
               0------1------2------3------+
  0x01020304   |  04  |  03  |  02  |  01  |
               +------+------+------+------+
ELFDATA2LSB编码指定了2的补数值。
最大有意义的字节占有最低的地址。
+ 图1-6: Data Encoding ELFDATA2MSB
               0------+
      0x0102   |  01  |
               +------+
               0------1------+
    0x010204   |  01  |  02  |
               +------+------+
               0------1------2------3------+
  0x01020304   |  01  |  02  |  03  |  04  |
               +------+------+------+------+
    机器信息
为了确定文件,32位Intel体系结构的需要以下的变量。
+ 图1-7: 32-bit Intel Architecture Identification, e_ident
  Position           Value
  ========           =====
  e_ident[EI_CLASS]  ELFCLASS32
  e_ident[EI_DATA]   ELFDATA2LSB
处理器确认ELF头里的e_machine成员,该成员必须为EM_386。
ELF报头里的e_flags成员保存了和文件相关的位标记。32位Intel体系上未
定义该标记;所以这个成员应该为0;
   =========================== Sections ===========================
一个object文件的section header table可以让我们定位所有的sections。
section header table是个Elf32_Shdr结构的数组(下面描述)。一个section
报头表(section header table)索引是这个数组的下标。ELF header table
的e_shoff成员给出了section报头表的偏移量(从文件开始的计数)。e_shnum
告诉我们section报头表中包含了多少个入口;e_shentsize 给出了每个
入口的大小。
一些section报头表索引是保留的;那些特别的索引在一个object文件中
将没有与之对应sections。
+ 图1-8: Special Section Indexes
  Name             Value
  ====             =====
  SHN_UNDEF            0
  SHN_LORESERVE   0xff00
  SHN_LOPROC      0xff00
  SHN_HIPROC      0xff1f
  SHN_ABS         0xfff1
  SHN_COMMON      0xfff2
  SHN_HIRESERVE   0xffff
* SHN_UNDEF
  该值表明没有定义,缺少,不相关的或者其他涉及到的无意义的section。
  例如,标号“defined”相对于section索引号SHN_UNDEF是一个没有被
  定义的标号。
注意: 虽然索引0保留作为未定义的值,section报头表包含了一个索引0的
入口。因此,假如ELF报头说一个文件的section报头表中有6个section入口
的话,e_shnum的值应该是从0到5。最初的入口的内容以后在这个section中
被指定。
* SHN_LORESERVE
  该值指定保留的索引范围的最小值。
* SHN_LOPROC through SHN_HIPROC
  该值包含了特定处理器语意的保留范围。
* SHN_ABS
  该变量是相对于相应参考的绝对地址。
  例如,section号的标号是绝对地址,不被重定位影响。
* SHN_COMMON
  该section的标号是一个公共(common)的标号,就象FORTRAN COMMON
  或者不允许的C扩展变量。
* SHN_HIRESERVE
  该值指定保留的索引范围的上限。系统保留的索引值是从SHN_LORESERVE
  到SHN_HIRESERVE;该变量不涉及到section报头表(section header table)。
  因此,section报头表不为保留的索引值包含入口。

sections包含了在一个object文件中的所有信息,除了ELF报头,程序报头
表(program header table),和section报头表(section header table)。
此外,object文件的sections满足几天条件:
* 每个在object文件中的section都有自己的一个section的报头来描述它。
  section头可能存在但section可以不存在。
* 每个section在文件中都占有一个连续顺序的空间(但可能是空的)。
* 文件中的Sections不可能重复。文件中没有一个字节既在这个section中
  又在另外的一个section中。
* object文件可以有"非活动的"空间。不同的报头和sections可以不覆盖到
  object文件中的每个字节。"非活动"数据内容是未指定的。
一个section头有如下的结构。
+ 图1-9: Section Header
  typedef struct {
      Elf32_Word sh_name;
      Elf32_Word sh_type;
      Elf32_Word sh_flags;
      Elf32_Addr sh_addr;
      Elf32_Off  sh_offset;
      Elf32_Word sh_size;
      Elf32_Word sh_link;
      Elf32_Word sh_info;
      Elf32_Word sh_addralign;
      Elf32_Word sh_entsize;
  } Elf32_Shdr;
* sh_name
  该成员指定了这个section的名字。它的值是section报头字符表section的
  索引。[看以下的“String Table”], 以NULL空字符结束。
* sh_type
  该成员把sections按内容和意义分类。section的类型和他们的描述在下面。
* sh_flags
  sections支持位的标记,用来描述多个属性。  
  Flag定义出现在下面。
* sh_addr
  假如该section将出现在进程的内存映象空间里,该成员给出了一个该section
  在内存中的位置。否则,该变量为0。
* sh_offset
  该成员变量给出了该section的字节偏移量(从文件开始计数)。SHT_NOBITS
  类型的section(下面讨论)在文件中不占空间,它的sh_offset成员定位在
  文件中的概念上的位置。
* sh_size
  该成员给你了section的字节大小。除非这个section的类型为SHT_NOBITS,
  否则该section将在文件中将占有sh_size个字节。SHT_NOBITS类型的section
  可能为非0的大小,但是不占文件空间。
* sh_link
  该成员保存了一个section报头表的索引连接,它的解释依靠该section的
  类型。以下一个表描述了这些值。
* sh_info
  该成员保存着额外的信息,它的解释依靠该section的类型。以下一个表描
  述了这些值。
* sh_addralign
  一些sections有地址对齐的约束。例如,假如一个section保存着双字,系统
  就必须确定整个section是否双字对齐。所以sh_addr的值以sh_addralign的值
  作为模,那么一定为0。当然的,仅仅0和正的2的次方是允许的。值0和1意味
  着该section没有对齐要求。
* sh_entsize
  一些sections保存着一张固定大小入口的表,就象符号表。对于这样一个
  section来说,该成员给出了每个入口的字节大小。如果该section没有
  保存着一张固定大小入口的表,该成员就为0。
section头成员sh_type指出了section的语意。
+ 图1-10: Section Types, sh_type
  Name               Value
  ====               =====
  SHT_NULL               0
  SHT_PROGBITS           1
  SHT_SYMTAB             2
  SHT_STRTAB          3
  SHT_RELA          4
  SHT_HASH          5
  SHT_DYNAMIC            6
  SHT_NOTE          7
  SHT_NOBITS          8
  SHT_REL          9
  SHT_SHLIB             10
  SHT_DYNSYM            11
  SHT_LOPROC    0x70000000
  SHT_HIPROC    0x7fffffff
  SHT_LOUSER    0x80000000
  SHT_HIUSER    0xffffffff
* SHT_NULL
  该值表明该section头是无效的;它没有相关的section。
  该section的其他成员的值都是未定义的。
* SHT_PROGBITS
  该section保存被程序定义了的一些信息,它的格式和意义取决于程序本身。
* SHT_SYMTAB and SHT_DYNSYM
  那些sections保存着一个符号表(symbol table)。一般情况下,一个
  object文件每个类型section仅有一个,但是,在将来,这个约束可能被放宽。
  典型的是,SHT_SYMTAB为连接器提供标号,当然它也有可能被动态连接时使用。
  作为一个完整的符号表,它可能包含了一些动态连接时不需要的标号。
  因此,一个object文件可能也包含了一个SHT_DYNSYM的section,它保存着
  一个动态连接时所需最小的标号集合来节省空间。
  看下面符号表“Symbol Table”的细节。
* SHT_STRTAB
  该section保存着一个字符串表。一个object文件可以包含多个字符串表的
  section。看下面字符串表“String Table”的细节。
* SHT_RELA
  该section保存着具有明确加数的重定位入口。就象object文件32位的
  Elf32_Rela类型。一个object文件可能有多个重定位的sections。具体细节
  看重定位``Relocation''部分。
* SHT_HASH
  该标号保存着一个标号的哈希(hash)表。所有的参与动态连接的object
  一定包含了一个标号哈希表(hash table)。当前的,一个object文件
  可能只有一个哈希表。详细细节看第二部分的哈希表"Hash Table"。
* SHT_DYNAMIC
  该section保存着动态连接的信息。当前的,一个object可能只有一个动态
  的section,但是,将来这个限制可能被取消。详细细节看第二部分的动态
  section(“Dynamic Section”)。
* SHT_NOTE
  该section保存着其他的一些标志文件的信息。详细细节看第二部分的“Note
  Section” 。
* SHT_NOBITS
  该类型的section在文件中不占空间,但是类似SHT_PROGBITS。尽管该section
  不包含字节,sh_offset成员包含了概念上的文件偏移量。
* SHT_REL
  该section保存着具有明确加数的重定位的入口。
  就象object文件32位类型Elf32_Rel类型。一个object文件可能有多个
  重定位的sections。具体细节看重定位``Relocation''部分。
* SHT_SHLIB
  该section类型保留但语意没有指明。包含这个类型的section的程序
  是不符合ABI的。
* SHT_LOPROC through SHT_HIPROC
  在这范围之间的值为特定处理器语意保留的。
* SHT_LOUSER
  该变量为应用程序保留的索引范围的最小边界。
* SHT_HIUSER
  该变量为应用程序保留的索引范围的最大边界。在SHT_LOUSER和HIUSER的
  section类型可能被应用程序使用,这和当前或者将来系统定义的section
  类型是不矛盾的。
其他section类型的变量是保留的。前面提到过,索引0(SHN_UNDEF)的section
头存在的,甚至索引标记的是未定义的section引用。这个入口保存着以下的
信息。
+ 图1-11: Section Header Table Entry: Index 0
  Name            Value    Note
  ====            =====    ====
  sh_name           0      No name
  sh_type        SHT_NULL  Inactive
  sh_flags          0      No flags
  sh_addr           0      No address
  sh_offset         0      No file offset
  sh_size           0      No size
  sh_link SHN_UNDEF  No link information
  sh_info     0      No auxiliary information
  sh_addralign     0      No alignment
  sh_entsize        0      No entries
一个section报头(section header table)的sh_flags成员保存着1位标记,
用来描述section的属性。以下是定义的值;其他的值保留。
+ 图1-12: Section Attribute Flags, sh_flags
  Name                Value
  ====                =====
  SHF_WRITE             0x1
  SHF_ALLOC             0x2
  SHF_EXECINSTR         0x4
  SHF_MASKPROC   0xf0000000
假如在sh_flags中的一个标记位被设置,该section相应的属性也被打开。
否则,该属性没有被应用。未明的属性就设为0。
* SHF_WRITE
  该section包含了在进程执行过程中可被写的数据。

* SHF_ALLOC
  该section在进程执行过程中占据着内存。一些控制section不存在一个
  object文件的内存映象中;对于这些sections,这个属性应该关掉。
* SHF_EXECINSTR
  该section包含了可执行的机器指令。
* SHF_MASKPROC
  所有的包括在这掩码中的位为特定处理语意保留的。
在section报头中,两个成员sh_link和sh_info的解释依靠该section的类型。
+ 图1-13: sh_link and sh_info Interpretation
  sh_type      sh_link                        sh_info
  =======      =======                        =======
  SHT_DYNAMIC  The section header index of    0
               the string table used by
               entries in the section.
  SHT_HASH     The section header index of    0
               the symbol table to which the
               hash table applies.
  SHT_REL,     The section header index of    The section header index of
  SHT_RELA     the associated symbol table.   the section to which the
                                              relocation applies.
  SHT_SYMTAB,  The section header index of    One greater than the symbol
  SHT_DYNSYM   the associated string table.   table index of the last local
                                              symbol (binding STB_LOCAL).
  other        SHN_UNDEF                      0
  Special Sections   特殊的Sections
不同的sections保存着程序和控制信息。下面列表中的section被系统使用,
指示了类型和属性。
+ 图1-14: Special Sections
  Name         Type           Attributes
  ====         ====           ==========
  .bss         SHT_NOBITS     SHF_ALLOC+SHF_WRITE
  .comment     SHT_PROGBITS   none
  .data        SHT_PROGBITS   SHF_ALLOC+SHF_WRITE
  .data1       SHT_PROGBITS   SHF_ALLOC+SHF_WRITE
  .debug       SHT_PROGBITS   none
  .dynamic     SHT_DYNAMIC    see below
  .dynstr      SHT_STRTAB     SHF_ALLOC
  .dynsym      SHT_DYNSYM     SHF_ALLOC
  .fini        SHT_PROGBITS   SHF_ALLOC+SHF_EXECINSTR
  .got         SHT_PROGBITS   see below
  .hash        SHT_HASH       SHF_ALLOC
  .init        SHT_PROGBITS   SHF_ALLOC+SHF_EXECINSTR
  .interp      SHT_PROGBITS   see below
  .line        SHT_PROGBITS   none
  .note        SHT_NOTE       none
  .plt         SHT_PROGBITS   see below
  .rel   SHT_REL        see below
  .rela  SHT_RELA       see below
  .rodata      SHT_PROGBITS   SHF_ALLOC
  .rodata1     SHT_PROGBITS   SHF_ALLOC
  .shstrtab    SHT_STRTAB     none
  .strtab      SHT_STRTAB     see below
  .symtab      SHT_SYMTAB     see below
  .text        SHT_PROGBITS   SHF_ALLOC+SHF_EXECINSTR
* .bss
  该sectiopn保存着未初始化的数据,这些数据存在于程序内存映象中。
  通过定义,当程序开始运行,系统初始化那些数据为0。该section不占
  文件空间,正如它的section类型SHT_NOBITS指示的一样。
  
* .comment
   该section保存着版本控制信息。
* .data and .data1
  这些sections保存着初始化了的数据,那些数据存在于程序内存映象中。
* .debug
  该section保存着为标号调试的信息。该内容是未指明的。
* .dynamic
  该section保存着动态连接的信息。该section的属性将包括SHF_ALLOC位。
  是否需要SHF_WRITE是跟处理器有关。第二部分有更详细的信息。
* .dynstr
  该section保存着动态连接时需要的字符串,一般情况下,名字字符串关联着
  符号表的入口。第二部分有更详细的信息。
* .dynsym
  该section保存着动态符号表,如“Symbol Table”的描述。第二部分有更
  详细的信息。
  
* .fini
  该section保存着可执行指令,它构成了进程的终止代码。
  因此,当一个程序正常退出时,系统安排执行这个section的中的代码。
* .got
  该section保存着全局的偏移量表。看第一部分的“Special Sections”和
  第二部分的“Global Offset Table”获得更多的信息。
* .hash
  该section保存着一个标号的哈希表。看第二部分的“Hash Table”获得更多
  的信息。
* .init
  该section保存着可执行指令,它构成了进程的初始化代码。
  因此,当一个程序开始运行时,在main函数被调用之前(c语言称为main),
  系统安排执行这个section的中的代码。
* .interp
  该section保存了程序的解释程序(interpreter)的路径。假如在这个section
  中有一个可装载的段,那么该section的属性的SHF_ALLOC位将被设置;否则,
  该位不会被设置。看第二部分获得更多的信息。
* .line
  该section包含编辑字符的行数信息,它描述源程序与机器代码之间的对于
  关系。该section内容不明确的。
* .note
  该section保存一些信息,使用“Note Section”(在第二部分)中提到的格式。
* .plt
  该section保存着过程连接表(Procedure Linkage Table)。看第一部分的
  ``Special Sections''和第二部分的“Procedure Linkage Table”。
* .rel and .rela
  这些section保存着重定位的信息,看下面的``Relocation''描述。
  假如文件包含了一个可装载的段,并且这个段是重定位的,那么该section的
  属性将设置SHF_ALLOC位;否则该位被关闭。按照惯例,由重定位适用
  的section来提供。因此,一个重定位的section适用的是.text,那么该名字
  就为.rel.text或者是.rela.text。
* .rodata and .rodata1
  这些section保存着只读数据,在进程映象中构造不可写的段。看第二部分的
  ``Program Header''获得更多的资料。
* .shstrtab
  该section保存着section名称。
* .strtab
  该section保存着字符串,一般地,描述名字的字符串和一个标号的入口相关
  联。假如文件有一个可装载的段,并且该段包括了符号字符串表,那么section
  的SHF_ALLOC属性将被设置;否则不设置。
* .symtab
  该section保存着一个符号表,正如在这个section里``Symbol Table''的
  描述。假如文件有一个可装载的段,并且该段包含了符号表,那么section
  的SHF_ALLOC属性将被设置;否则不设置。
* .text
  该section保存着程序的``text''或者说是可执行指令。
前缀是点(.)的section名是系统保留的,尽管应用程序可以用那些保留的
section名。应用程序可以使用不带前缀的名字以避免和系统的sections
冲突。object文件格式可以让一个定义的section部分不出现在上面的列
表中。一个object文件可以有多个同样名字的section。
为处理器体系保留的section名的形成是通过置换成一个体系名的缩写。
该名字应该取自体系名,e_machine使用的就是。例如,.Foo.psect就是
在FOO体系上定义的名字。
现存的扩展名是历史遗留下来的。
         Pre-existing Extensions
         =======================
    .sdata     .tdesc
    .sbss      .lit4
    .lit8      .reginfo
    .gptab     .liblist
    .conflict
   =================== String Table 字符串表=========================
String table sections 保存着以NULL终止的一系列字符,一般我们称为字
符串。object文件使用这些字符串来描绘符号和section名。一个字符串的
参考是一个string table section的索引。第一个字节,即索引0,被定义保
存着一个NULL字符。同样的,一个string table的最后一个字节保存着一个
NULL字符,所有的字符串都是以NULL终止。索引0的字符串是没有名字或者说
是NULL,它的解释依靠上下文。一个空的string table section是允许的;
它的section header的成员sh_size将为0。对空的string table来说,非0的
索引是没有用的。
一个 settion 头的 sh_name 成员保存了一个对应于该 setion 头字符表部分
的索引(就象ELF头的 e_shstrndx 成员所特指的那样。下表列出了一个有 25 字节
的字符串表(这些字符串和不同的索引相关联):
       Index   +0   +1   +2   +3   +4   +5   +6   +7   +8   +9
       =====   ==   ==   ==   ==   ==   ==   ==   ==   ==   ==
          0    \0   n    a    m    e    .    \0   V    a    r     
         10    i    a    b    l    e    \0   a    b    l    e
         20    \0   \0   x    x    \0
+ Figure 1-15: String Table Indexes
  Index   String
  =====   ======
      0   none
      1   "name."
      7   "Variable"
     11   "able"
     16   "able"
     24   null string
如上所示,一个字符串表可能涉及该 section 中的任意字节。一个字符串可能
引用不止一次;引用子串的情况是可能存在的;一个字符串也可能被引用若干次;而
不被引用的字符串也是允许存在的。
   ==================== Symbol Table 符号表=========================
一个object文件的符号表保存了一个程序在定位和重定位时需要的定义和引用的信息。
一个符号表索引是相应的下标。0表项特指了该表的第一个入口,就象未定义的符号
索引一样。初始入口的内容在该 section 的后续部分被指定。
                             Name       Value
                             ====       =====
        STN_UNDEF      0
一个符号表入口有如下的格式:
+ Figure 1-16: Symbol Table Entry
  typedef struct {
      Elf32_Word st_name;
      Elf32_Addr st_value;
      Elf32_Word st_size;
      unsigned char st_info;
      unsigned char st_other;
      Elf32_Half st_shndx;
  } Elf32_Sym;
* st_name
  该成员保存了进入该object文件的符号字符串表入口的索引(保留了符号名的表达字符)。  
  如果该值不为 0 ,则它代表了给出符号名的字符串表索引。否则,该符号无名。
注意:External C 符号和object文件的符号表有相同的名称。
* st_value
  该成员给出了相应的符号值。它可能是绝对值或地址等等(依赖于上下文);
  细节如下所述。
* st_size
  许多符号和大小相关。比如,一个数据对象的大小是该对象所包含的字节数目。
  如果该符号的大小未知或没有大小则这个成员为 0 。
* st_info
  成员指出了符号的类型和相应的属性。相应的列表如下所示。下面的代码说明了
  如何操作该值。
    #define ELF32_ST_BIND(i) ((i)>>4)
    #define ELF32_ST_TYPE(i) ((i)&0xf)
    #define ELF32_ST_INFO(b, t) (((b)>8)
    #define ELF32_R_TYPE(i) ((unsigned char)(i))
    #define ELF32_R_INFO(s, t) ((s)> 24;
          h &= ~g;
      }
      return h;
  }
        Initialization and Termination Functions
            初始化和终止函数
在动态连接妻建立进程映象和执行重定位以后,每一个共享object得到适当
的机会来执行一些初始话代码。初始化函数不按特别的顺序被调用,但是
所有的共享object初始化发生在执行程序获得控制之前。
类似地,共享的object可能包含终止函数,它们在进程本身开始它的终止之后
被执行(以atexit(BA_OS)的机制)。
共享object通过设置在动态结构中的DT_INIT和DT_FINI入口来指派它们的初始化
和终止函数,如上动态section(Dynamic Section)部分描述。典型的,那些函数
代码存在.init和.fini section中,第一部分的“section”已经提到过。
注意:尽管atexit(BA_OS)的终止处理一般可可正常完成,但是不保证在死进程上
被执行。特别的,假如_exit被调用(看exit(BA_OS))或者假如进程死掉,那么
进程是不执行终止处理的。因为它收到一个信号,该信号可捕获或忽略。
   ________________________________________________________________
        3. C LIBRARY
   ________________________________________________________________
   ========================== C Library ===========================
C库,libc,包含了所有的符号(包含在libsys),另外,包含在在下面两个
表中列出的运行函数。第一个表中的运行函数是ANSI C标准的。
+ Figure 3-1: libc Contents, Names without Synonyms
  abort        fputc        isprint      putc         strncmp
  abs        fputs        ispunct      putchar      strncpy
  asctime      fread        isspace      puts         strpbrk
  atof        freopen      isupper      qsort        strrchr
  atoi        frexp        isxdigit     raise        strspn
  atol        fscanf       labs         rand         strstr
  bsearch      fseek        ldexp        rewind       strtod
  clearerr     fsetpos      ldiv         scanf        strtok
  clock        ftell        localtime    setbuf       strtol
  ctime        fwrite       longjmp      setjmp       strtoul
  difftime     getc         mblen        setvbuf      tmpfile
  div        getchar      mbstowcs     sprintf      tmpnam
  fclose       getenv       mbtowc       srand        tolower
  feof        gets         memchr       sscanf       toupper
  ferror       gmtime       memcmp       strcat       ungetc
  fflush       isalnum      memcpy       strchr       vfprintf
  fgetc        isalpha      memmove      strcmp       vprintf
  fgetpos      iscntrl      memset       strcpy       vsprintf
  fgets        isdigit      mktime       strcspn      wcstombs
  fopen        isgraph      perror       strlen       wctomb
  fprintf      islower      printf       strncat   
再加上, libc 保存着以下的服务。
+ Figure 3-2: libc Contents, Names with Synonyms
  __assert     getdate      lockf **     sleep        tell **
  cfgetispeed  getopt       lsearch      strdup       tempnam
  cfgetospeed  getpass      memccpy      swab         tfind
  cfsetispeed  getsubopt    mkfifo       tcdrain      toascii
  cfsetospeed  getw         mktemp       tcflow       _tolower
  ctermid      hcreate      monitor      tcflush      tsearch
  cuserid      hdestroy     nftw         tcgetattr    _toupper
  dup2        hsearch      nl_langinfo  tcgetpgrp    twalk
  fdopen       isascii      pclose       tcgetsid     tzset
  __filbuf     isatty       popen        tcsendbreak  _xftw
  fileno       isnan        putenv       tcsetattr   
  __flsbuf     isnand **    putw         tcsetpgrp   
  fmtmsg **    lfind        setlabel     tdelete      
  ** = Function is at Level 2 in the SVID Issue 3 and therefore at
       Level 2 in the ABI.
包括上面同义(Synonyms)表列出的标号,对于 入口已经存在的_
形式(带一个下划线,上面没有列出来)优先权高于它们的名字。所以,例如,
libc同时包含了getopt和_getopt。
在常规的上列中,其他地方以下没有被定义。
int __filbuf(FILE *f);
This function returns the next input character for f, filling
its buffer as appropriate. It returns EOF if an error occurs.
int __flsbuf(int x, FILE *f);
This function flushes the output characters for f as if
putc(x, f) had been called and then appends the value of x to
the resulting output stream. It returns EOF if an error occurs
and x otherwise.
int _xftw(int, char *, int (*)(char *, struct stat *, int), int);
Calls to the ftw(BA_LIB) function are mapped to this function
when applications are compiled. This function is identical to
ftw(BA_LIB), except that _xftw() takes an interposed first
argument, which must have the value 2.
要了解更多的关于SVID,ANSI C,POSIX的知识,可看该章节其他的库section部分。
该节“System Data Interfaces”后有更多的描述。
    Global Data Symbols
                      全局数据符号
libc库需要一些外部的全局数据符号(为了它自己的常规工作而定义的)。
所有向libsys库请求的数据符号一定要让libc提供,就象下面表中的数据符号。
正式定义的数据object被他们的符号描述,看System V接口定义,第三版本
或者第6章节的数据定义(Data Definitions)section(在适当的处理器
补充到System V ABI)。
在下面表中的入口有-_的形式。一对符号都代表了一些数据。
下划线的synonyms假设满足ANSI C标准。
+ Figure 3-3: libc Contents, Global External Data Symbols
  getdate_err  optarg
  _getdate_err  opterr
  __iob   optind
   optopt



本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/54388/showart_1279901.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP