链接 加载

实验程序:

$ cat SimpleSection.c
int printf(const char* format,...);
int globa_init_var = 84;
int global_uninit_val;
void func1(int i){
    printf("%d\n",i);
}
int main(){
    static int static_var = 85;
    static int static_var2;
    int a = 1;
    int b;
    func1(static_var+static_var2+a+b);
    return 0;
}
-----------------------------------------------------------------------------------------------------------

elf头数据结构

/usr/include/elf.h

  85 typedef struct
  86 {
  87   unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
  88   Elf64_Half    e_type;         /* Object file type */  //可重定位 可执行 共享
  89   Elf64_Half    e_machine;      /* Architecture */
  90   Elf64_Word    e_version;      /* Object file version */
  91   Elf64_Addr    e_entry;        /* Entry point virtual address */
  92   Elf64_Off e_phoff;        /* Program header table file offset */
  93   Elf64_Off e_shoff;        /* Section header table file offset */
  94   Elf64_Word    e_flags;        /* Processor-specific flags */
  95   Elf64_Half    e_ehsize;       /* ELF header size in bytes */
  96   Elf64_Half    e_phentsize;        /* Program header table entry size */
  97   Elf64_Half    e_phnum;        /* Program header table entry count */
  98   Elf64_Half    e_shentsize;        /* Section header table entry size */
  99   Elf64_Half    e_shnum;        /* Section header table entry count */
 100   Elf64_Half    e_shstrndx;     /* Section header string table index */
 101 } Elf64_Ehdr;

$ gcc -c -o SimpleSection.o SimpleSection.c

$ readelf -h SimpleSection.o
ELF 头:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (可重定位文件)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  入口点地址:               0x0
  程序头起点:          0 (bytes into file)
  Start of section headers:          400 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         64 (字节)
  节头数量:         13

  字符串表索引节头: 10

--------------------------------------------------------------------------------------

上面内容比较清晰,不过多介绍。注意其中的入口点地址目前为0,因为目前是可重定位文件,等最终链接完成就会得到最终地址,另外看一下最后一项:字符串表索引节头 指的是字符串表在section table中的索引

section table如下:

$ readelf -S SimpleSection.o


共有 13 个节头,从偏移量 0x190 开始

节头:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000056  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  000006b8
       0000000000000078  0000000000000018          11     1     8

  [ 3] .data             PROGBITS         0000000000000000  00000098
       0000000000000008  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  000000a0
       0000000000000004  0000000000000000  WA       0     0     4
  [ 5] .rodata           PROGBITS         0000000000000000  000000a0
       0000000000000004  0000000000000000   A       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  000000a4
       0000000000000025  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000c9
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  000000d0
       0000000000000058  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  00000730
       0000000000000030  0000000000000018          11     8     8
  [10] .shstrtab         STRTAB           0000000000000000  00000128 //保存段表中用到的字符串,最常见的就是段名
       0000000000000061  0000000000000000           0     0     1

  [11] .symtab           SYMTAB           0000000000000000  000004d0
       0000000000000180  0000000000000018          12    11     8
  [12] .strtab           STRTAB           0000000000000000  00000650  //保存普通字符串,如符号的名字
       0000000000000065  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

上面其实就是一个Section table的数组,继续看一下Section header对应的数据结构:

 270 /* Section header.  */
 286 typedef struct
 287 {
 288   Elf64_Word    sh_name;        /* Section name (string tbl index) */ //索引的是.shstrtab
 289   Elf64_Word    sh_type;        /* Section type */
 290   Elf64_Xword   sh_flags;       /* Section flags */
 291   Elf64_Addr    sh_addr;        /* Section virtual addr at execution */
 292   Elf64_Off sh_offset;      /* Section file offset */
 293   Elf64_Xword   sh_size;        /* Section size in bytes */
 294   Elf64_Word    sh_link;        /* Link to another section */ //该段使用的字符串在段表中的下标
 295   Elf64_Word    sh_info;        /* Additional section information */  //重定位表所作用的段在段表中的下标
 296   Elf64_Xword   sh_addralign;       /* Section alignment */
 297   Elf64_Xword   sh_entsize;     /* Entry size if section holds table */
 298 } Elf64_Shdr;

以.rela.text为例,它的sh_link为11,指向的是.symtab,说明它的字符串在.symtab中,它的sh_info为1,指向的是.text,说明它是对.text段进行重定位。

我们来查看一下.symtab的内容:

$ readelf -s SimpleSection.o

Symbol table '.symtab' contains 16 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FIL

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值