• ELF文件的格式和加载过程


    http://blog.csdn.net/lingfong_cool/article/details/7832896

    (一) ELF 文件的格式

          ELF 文件类型 (1) 可重定位文件( .o 目标文件) : 用于链接创建可执行文件或 so 文件

                                (2) 可执行文件                     : 用于执行

                                (3)so( 共享对象 ) 文件            : 用于链接

          

           注 :   一个 Program Header 对应一个 Segment

                一个 Section Header 对应一个 Section

                  Segment 由 Section 构成

    Segment 类型 :#define PT_NULL         0                   unused

    #define PT_LOAD         1                   可加载段 ( 代码节和数据节 )

    #define PT_DYNAMIC 2                   动态链接段 ( 动态链接信息 )

    #define PT_INTERP       3                   解释器段 ( 动态链接器路径 )

    #define PT_NOTE         4                   auxiliary information

    #define PT_SHLIB 5                          reserved - purpose undefined

    #define PT_PHDR         6                   program header

    #define PT_NUM          7                   Number of segment types

    #define PT_LOOS         0x60000000    reserved range for OS

    #define PT_HIOS          0x6fffffff              specific segment types

    #define PT_LOPROC    0x70000000    reserved range for processor

    #define PT_HIPROC     0x7fffffff              specific segment types

    Section 类型 :   #define ELF_BSS           ".bss"             uninitialized data

    #define ELF_DATA          ".data "           数据节 initialized data

    #define ELF_DEBUG        ".debug"         debug

    #define ELF_DYNAMIC     ".dynamic "  动态链接节 dynamic linking information

    #define ELF_DYNSTR ".dynstr"         dynamic string table

    #define ELF_DYNSYM        ".dynsym"      dynamic symbol table

    #define ELF_FINI             ".fini"             termination code

    #define ELF_GOT          ".got"             global offset table

    #define ELF_HASH         ".hash"           symbol hash table

    #define ELF_INIT          ".init"             initialization code

    #define ELF_REL_DATA     ".rel.data"       relocation data

    #define ELF_REL_FINI    ".rel.fini"         relocation termination code

    #define ELF_REL_INIT    ".rel.init"         relocation initialization code

    #define ELF_REL_DYN      ".rel.dyn"        relocaltion dynamic link info

    #define ELF_REL_RODATA  ".rel.rodata"    relocation read-only data

    #define ELF_REL_TEXT   ".rel.text"        relocation code

    #define ELF_RODATA     ".rodata"         read-only data

    #define ELF_SHSTRTAB   ".shstrtab"       section header string table

    #define ELF_STRTAB       ".strtab"          string table

    #define ELF_SYMTAB       ".symtab"              symbol table

    #define ELF_TEXT         ".text "            代码节 code

     

    (二) ELF 文件的加载过程

    源文件 Trunk/System/ElfLoader/dll/elfloader.c

    LoadElfExec() 函数

    加载的具体过程

    1. 打开文件 open_library(char* filename)

           系统调用 open(): 创建 File 结构体 , 放入进程打开文件表 , 返回 ( 打开文件表 ) 下标

    2. 读出文件头和程序头表 IsElfFormat(FILE)

           读出 ELF 文件头 ( 同时读出了程序头表 Program Header Table), 判断 ELF 格式根据文件头中的e_ident 来比较判断 .

    3. 加载文件 load_library(char * filename,int fd)

           (1) 计算所有 segment 占用内存大小 get_lib_extents()

    通过遍历程序头表 (Program Header Table), 算出所有 segment 将占用的内存大小extents_size

    (2) 分配内存 alloc_mem_region(extents_size)

           匿名映射一块非共享的私有内存 ( 不涉及文件 )

    (3) 分配 soinfo 结构体 alloc_info(char *filename)

           从全局静态 soinfo 结构体数组中分配 soinfo 结构体 ( 描述整个 ELF 文件 )

    (4) 加载 segment

    load_segment(int fd,void* header,soinfo*si)

    (1) 可加载段 (PT_LOAD): 映射到内存

    mmap(void * start,size_t len, int prot,int flags,int fd,off_t offsize)

    把 ELF 文件 offsize 处的 segment 映射到已分配内存的 start 处

                  (2) 动态链接段

                         由动态链接节设置 soinfo 中的动态链接信息

           (5) 设置 soinfo 结构体

    4. 加载依赖的动态链接库

    5.重定位(自身符号)

       重定位表项:   Elf32_Addr     r_offset   (重定位)内存地址(offset of relocation)

                                Elf32_Word    r_info      符号表下标和类型(symbol table index and type)

          

       符号表项:      Elf32_Word    st_name  符号名(name - index into string table)

                                Elf32_Addr     st_value   符号值(symbol value)

                                Elf32_Word    st_size                 symbol size

                                unsigned char st_info                  type and binding

                                unsigned char st_other               0 - no defined meaning

                                Elf32_Half      st_shndx;                     section header index

           根据重定位表(表项)查符号表,得到符号内存地址,修改(重定位)内存值

    最后得到soinfo结构体数组描述了所有加载的文件

    6.如果入口地址不为零,调用入口函数

  • 相关阅读:
    按顺序触发事件LazyMan deepcopy
    requirejs学习,demo下载学习
    滑动删除demo
    jquery1.7.2的源码分析(四)$.Deferred(2)
    jquery1.7.2的源码分析(三)$.Deferred
    jquery1.7.2的源码分析(二)
    jquery1.7.2的源码分析(一)
    解码H264文件的一些基础知识
    和 的区别
    Jmeter Cookie管理器 获取JSESSIONID
  • 原文地址:https://www.cnblogs.com/feng9exe/p/6901614.html
Copyright © 2020-2023  润新知