《程序员的自我修养》读书笔记 PAGE77 图3-6理解

《程序员的自我修养》PAGE77 图3-6理解

    /*

    *SimpleSection.c

     *

     *

    */

int printf(const char * format, ...);

int global_init_var = 84;
int static global_uninit_var;
__attribute__((section("yl"))) int gobal = 42;

void func1 (int i)
{
    printf( "%d\n", i );
}

int main(void)
{
    static int static_var = 85;
    static int static_var2;
    int a = 1;
    int b;
    func1( static_var + static_var2 + a + b);
    return a;
}

命令:

root@ubuntu:/usr# gcc -c SimpleSection.c

root@ubuntu:/usr# readelf -h SimpleSection.o

ubuntu系统得出表1:
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          272 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 9

根据Start of section headers:          272 (bytes into file)

由Size of this header:               52 (bytes)可知ELF Header长度为0x34。


注:typedef struct
{
  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
  Elf32_Half    e_type;                 /* Object file type */
  Elf32_Half    e_machine;              /* Architecture */
  Elf32_Word    e_version;              /* Object file version */
  Elf32_Addr    e_entry;                /* Entry point virtual address */
  Elf32_Off     e_phoff;                /* Program header table file offset */
  Elf32_Off     e_shoff;                /* Section header table file offset */
  Elf32_Word    e_flags;                /* Processor-specific flags */
  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
  Elf32_Half    e_phentsize;            /* Program header table entry size */
  Elf32_Half    e_phnum;                /* Program header table entry count */
  Elf32_Half    e_shentsize;            /* Section header table entry size */
  Elf32_Half    e_shnum;                /* Section header table entry count */
  Elf32_Half    e_shstrndx;             /* Section header string table index */
} Elf32_Ehdr;

该结构体定义了ELF文件头格式。

其中Elf32_Half    e_shstrndx;    Section header string table index: 9

e_shstrndx表示".shstrtab"在段表中的下标为9。如表2所示。

.shstrtab用来保存段表中用到的字符串。

所以我们知道,通过分析ELF文件头,就可以得到段表和段表字符串表的位置,从而解析出整个ELF文件。

命令:

root@ubuntu:/usr# readelf -S SimpleSection.o
There are 12 section headers, starting at offset 0x110:

ubuntu系统得出表2:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000050 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 00046c 000028 08     10   1  4
  [ 3] .data             PROGBITS        00000000 000084 000008 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 00008c 000008 00  WA  0   0  4
  [ 5] yl                PROGBITS        00000000 00008c 000004 00  WA  0   0  4
  [ 6] .rodata           PROGBITS        00000000 000090 000004 00   A  0   0  1
  [ 7] .comment          PROGBITS        00000000 000094 000026 01  MS  0   0  1
  [ 8] .note.GNU-stack   PROGBITS        00000000 0000ba 000000 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 0000ba 000054 00      0   0  1
  [10] .symtab           SYMTAB          00000000 0002f0 000110 10     11  12  4
  [11] .strtab           STRTAB          00000000 000400 00006c 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

注:.yl段由"__attribute__((section("yl"))) int gobal = 42;"自定义出。

[ 2] .rel.text         REL             00000000 00046c 000028 08     10   1  4

.rel.text段是一个重定位表,是SHT_REL类型的,他的”sh_link"表示符号表的下标,它的"sh_info”表示它作用于哪个段。这里.rel.text作用于.text段,.text段的下标为1。

由表2可知.text段由ox04开始长度为0x50以0x84结束;.data段由0x84开始长度为0x08以0x8c结束;.yl段由0x8c开始长度为0x04以0x90结束(.bss段也是有0x8c开始的,但长度为0);.rodata段由0x90开始长度为0x04以0x94结束;.comment段由0x94开始长度为0x26以0ba结束;.shstrtab段由0xba开始长度为0x54以0x10e结束;由表1可知SectionTable的偏移量为0x110,一共12个段,每段大小为40byte,这个长度正好等于sizeof(Elf32_Shdr)。Elf32_Shdr是/usr/include/elf.h 中定义的段表中描述段内容的结构体:

/* 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;

所以SectionTable由0x110开始,长度为480byte即0x1e0以0x2f0结束;.symtab由0x2f0开始长度为0x110以0x400结束;.strtab由0x400开始长度为0x6c以0x46c结束;.reltext段由0x46c开始长度为0x28以0x494结束。0x494为1172字节的。正好就是SimpleSection.o的大小。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值