ELF中Section的sh_type字段详解【含部分节的结构源码】

• Section Header

ELF文件中的Section Header定义如下(32位):

/* Section header.  */

typedef struct
{
  Elf32_Word    sh_name;        /* Section name (string tbl index) */
  Elf32_Word    sh_type;        /* Section type */
  Elf32_Word    sh_flags;       /* Section flags */
  Elf32_Addr    sh_addr;        /* Section virtual addr at execution */
  Elf32_Off     sh_offset;      /* Section file offset */
  Elf32_Word    sh_size;        /* Section size in bytes */
  Elf32_Word    sh_link;        /* Link to another section */
  Elf32_Word    sh_info;        /* Additional section information */
  Elf32_Word    sh_addralign;   /* Section alignment */
  Elf32_Word    sh_entsize;     /* Entry size if section holds table */
} Elf32_Shdr;

• sh_type

其中的sh_type字段表示节的类型,在elf.h文件中sh_type的合法值有以下定义:

/* Legal values for sh_type (section type).  */

#define SHT_NULL            0        /* Section header table entry unused */
#define SHT_PROGBITS        1        /* Program data */
#define SHT_SYMTAB          2        /* Symbol table */
#define SHT_STRTAB          3        /* String table */
#define SHT_RELA            4        /* Relocation entries with addends */
#define SHT_HASH            5        /* Symbol hash table */
#define SHT_DYNAMIC         6        /* Dynamic linking information */
#define SHT_NOTE            7        /* Notes */
#define SHT_NOBITS          8        /* Program space with no data (bss) */
#define SHT_REL             9        /* Relocation entries, no addends */
#define SHT_SHLIB          10        /* Reserved */
#define SHT_DYNSYM         11        /* Dynamic linker symbol table */
#define SHT_INIT_ARRAY     14        /* Array of constructors */
#define SHT_FINI_ARRAY     15        /* Array of destructors */
#define SHT_PREINIT_ARRAY  16        /* Array of pre-constructors */
#define SHT_GROUP          17        /* Section group */
#define SHT_SYMTAB_SHNDX   18        /* Extended section indeces */
#define    SHT_NUM         19        /* Number of defined types.  */
#define SHT_LOOS           0x60000000    /* Start OS-specific.  */
#define SHT_GNU_ATTRIBUTES 0x6ffffff5    /* Object attributes.  */
#define SHT_GNU_HASH       0x6ffffff6    /* GNU-style hash table.  */
#define SHT_GNU_LIBLIST    0x6ffffff7    /* Prelink library list */
#define SHT_CHECKSUM       0x6ffffff8    /* Checksum for DSO content.  */
#define SHT_LOSUNW         0x6ffffffa    /* Sun-specific low bound.  */
#define SHT_SUNW_move      0x6ffffffa
#define SHT_SUNW_COMDAT    0x6ffffffb
#define SHT_SUNW_syminfo   0x6ffffffc
#define SHT_GNU_verdef     0x6ffffffd    /* Version definition section.  */
#define SHT_GNU_verneed    0x6ffffffe    /* Version needs section.  */
#define SHT_GNU_versym     0x6fffffff    /* Version symbol table.  */
#define SHT_HISUNW         0x6fffffff    /* Sun-specific high bound.  */
#define SHT_HIOS           0x6fffffff    /* End OS-specific type */
#define SHT_LOPROC         0x70000000    /* Start of processor-specific */
#define SHT_HIPROC         0x7fffffff    /* End of processor-specific */
#define SHT_LOUSER         0x80000000    /* Start of application-specific */
#define SHT_HIUSER         0x8fffffff    /* End of application-specific */

下列表格罗列了几种比较常见的sh_type:

sh_type 描述
SHT_NULL 无对应节区,该节其他字段取值无意义
SHT_PROGBITS 程序数据
SHT_SYMTAB 符号表
SHT_STRTAB 字符串表
SHT_RELA 带附加的重定位项
SHT_HASH 符号哈希表
SHT_DYNAMIC 动态链接信息
SHT_NOTE 提示性信息
SHT_NOBITS 无数据程序空间(bss)
SHT_REL 无附加的重定位项
SHT_SHLIB 保留
SHT_DYNSYM 动态链接符号表
SHT_INIT_ARRAY 构造函数数组
SHT_FINI_ARRAY 析构函数数组

• SHT_SYMTAB、SHT_DYNSYM → Symbol table entry

如果节的类型是SHT_SYMTAB或者SHT_DYNSYM,那么该节的内容使用Elf32_Sym和Elf64_Sym描述。

/* Symbol table entry.  */

typedef struct
{
  Elf32_Word    st_name;   /* Symbol name (string tbl index) */
  Elf32_Addr    st_value;  /* Symbol value */
  Elf32_Word    st_size;   /* Symbol size */
  unsigned char  st_info;   /* Symbol type and binding */
  unsigned char  st_other;  /* Symbol visibility */
  Elf32_Section  st_shndx;  /* Section index */
} Elf32_Sym;

typedef struct
{
  Elf64_Word     st_name;   /* Symbol name (string tbl index) */
  unsigned char  st_info;   /* Symbol type and binding */
  unsigned char  st_other;  /* Symbol visibility */
  Elf64_Section  st_shndx;  /* Section index */
  Elf64_Addr     st_value;  /* Symbol value */
  Elf64_Xword    st_size;   /* Symbol size */
} Elf64_Sym;

st_value   此成员提供关联符号的值。根据上下文的不同,可以是绝对值、地址等。

• SHT_RELA → Relocation table entry with addend

如果节的类型是SHT_RELA,那么该节的内容使用Elf32_Rela和Elf64_Rela描述。

/* Relocation table entry with addend (in section of type SHT_RELA).  */

typedef struct
{
  Elf32_Addr    r_offset;        /* Address */
  Elf32_Word    r_info;          /* Relocation type and symbol index */
  Elf32_Sword   r_addend;        /* Addend */
} Elf32_Rela;

typedef struct
{
  Elf64_Addr    r_offset;        /* Address */
  Elf64_Xword   r_info;          /* Relocation type and symbol index */
  Elf64_Sxword  r_addend;        /* Addend */
} Elf64_Rela;

• SHT_DYNAMIC → Dynamic section entry

如果节的类型是SHT_DYNAMIC,那么该节的内容使用Elf32_Dyn和Elf64_Dyn描述。

/* Dynamic section entry.  */

typedef struct
{
  Elf32_Sword    d_tag;            /* Dynamic entry type */
  union{
      Elf32_Word d_val;            /* Integer value */
      Elf32_Addr d_ptr;            /* Address value */
  } d_un;
} Elf32_Dyn;

typedef struct
{
  Elf64_Sxword    d_tag;           /* Dynamic entry type */
  union{
      Elf64_Xword d_val;           /* Integer value */
      Elf64_Addr d_ptr;            /* Address value */
  } d_un;
} Elf64_Dyn;

elf.h中对d_tag取值的定义如下:

/* Legal values for d_tag (dynamic entry type).  */

#define DT_NULL   0   /* Marks end of dynamic section */
#define DT_NEEDED 1   /* Name of needed library */
#define DT_PLTRELSZ 2   /* Size in bytes of PLT relocs */
#define DT_PLTGOT 3   /* Processor defined value */
#define DT_HASH   4   /* Address of symbol hash table */
#define DT_STRTAB 5   /* Address of string table */
#define DT_SYMTAB 6   /* Address of symbol table */
#define DT_RELA   7   /* Address of Rela relocs */
#define DT_RELASZ 8   /* Total size of Rela relocs */
#define DT_RELAENT  9   /* Size of one Rela reloc */
#define DT_STRSZ  10    /* Size of string table */
#define DT_SYMENT 11    /* Size of one symbol table entry */
#define DT_INIT   12    /* Address of init function */
#define DT_FINI   13    /* Address of termination function */
#define DT_SONAME 14    /* Name of shared object */
#define DT_RPATH  15    /* Library search path (deprecated) */
#define DT_SYMBOLIC 16    /* Start symbol search here */
#define DT_REL    17    /* Address of Rel relocs */
#define DT_RELSZ  18    /* Total size of Rel relocs */
#define DT_RELENT 19    /* Size of one Rel reloc */
#define DT_PLTREL 20    /* Type of reloc in PLT */
#define DT_DEBUG  21    /* For debugging; unspecified */
#define DT_TEXTREL  22    /* Reloc might modify .text */
#define DT_JMPREL 23    /* Address of PLT relocs */
#define DT_BIND_NOW 24    /* Process relocations of object */
#define DT_INIT_ARRAY 25    /* Array with addresses of init fct */
#define DT_FINI_ARRAY 26    /* Array with addresses of fini fct */
#define DT_INIT_ARRAYSZ 27    /* Size in bytes of DT_INIT_ARRAY */
#define DT_FINI_ARRAYSZ 28    /* Size in bytes of DT_FINI_ARRAY */
#define DT_RUNPATH  29    /* Library search path */
#define DT_FLAGS  30    /* Flags for the object being loaded */
#define DT_ENCODING 32    /* Start of encoded range */
#define DT_PREINIT_ARRAY 32   /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33   /* size in bytes of DT_PREINIT_ARRAY */
#define DT_NUM    34    /* Number used */
#define DT_LOOS   0x6000000d  /* Start of OS-specific */
#define DT_HIOS   0x6ffff000  /* End of OS-specific */
#define DT_LOPROC 0x70000000  /* Start of processor-specific */
#define DT_HIPROC 0x7fffffff  /* End of processor-specific */
#define DT_PROCNUM  DT_MIPS_NUM /* Most used by any processor */

d_tag总体上可以说包含两种类型,一种是Address,一种是Size;如果表示地址,则d_un取d_ptr的值;如果表示大小,则d_un取d_val的值。

• SHT_REL → Relocation table entry without addend

如果节的类型是SHT_REL,那么该节的内容使用Elf32_Rel和Elf64_Rel描述。

/* Relocation table entry without addend (in section of type SHT_REL).  */

typedef struct
{
  Elf32_Addr  r_offset;   /* Address */
  Elf32_Word  r_info;     /* Relocation type and symbol index */
} Elf32_Rel;

/* I have seen two different definitions of the Elf64_Rel and
   Elf64_Rela structures, so we'll leave them out until Novell (or
   whoever) gets their act together.  */
/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */

typedef struct
{
  Elf64_Addr  r_offset;   /* Address */
  Elf64_Xword r_info;     /* Relocation type and symbol index */
} Elf64_Rel;

• SHT_PROGBITS

如果该节的sh_type==SHT_PROGBITS && (sh_name==“.got” || sh_name==“.got.plt”),那么该节为全局偏移表。GOT全局偏移表,存放在数据段。GOT被拆分为两个表,分别是“.got”和“.got.plt”,前者保存全局变量引用的地址,后者保存函数引用的地址【也包括外部函数的引用】。

 

参考链接:

1. https://refspecs.linuxfoundation.org/elf/elf.pdf

2. https://www.cnblogs.com/sayhellowen/p/802b5b0ad648e1a343dcd0f85513065f.html

3. https://blog.csdn.net/denny_chen_/article/details/85395389

4. https://www.cnblogs.com/lanrenxinxin/p/5573018.html

posted @ 2020-04-15 14:30  From_Zero  阅读(1554)  评论(0编辑  收藏  举报