天天看点

链接、装载与库——目标文件(2)第三章 目标文件里面有什么

*逐个分析各段。。。*

第三章 目标文件里面有什么

真正了不起的程序员对自己的程序的每一个字节都了如指掌。
//Test.c

int global_init_var = ;
int global_uninit_var;

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

int main()
{
    static int static_var = ;
    static int static_var2;
    int a = ;
    int b   

    func1(static_var + static_var2 + a + b);

    return ;
}
           

示例程序中包括代码段、数据段、BSS段、只读数据段(.rodata)、注释信息段(.comment)。

链接、装载与库——目标文件(2)第三章 目标文件里面有什么
  1. 代码段:
    • .text段中存放的是Test.c中函数func()和main()的指令。
  2. 数据段和只读数据段:
    • .data段保存初始化了的全局变量和局部静态变量(上述代码中的global_init_var和static_var)。
    • .rodata段存放只读数据,一般是程序的只读变量(const修饰的变量)和字符串常量(上述代码中”%d\n“是一种只读数据)。单独设立.rodata段从语义上支持C++的const关键字,也在加载时将属性映射成只读,保证安全性。有时编译器会把字符串常量放到.data段,而不会单独放在.rodata段。
  3. BSS段:
    • .bss段中存放的是未初始化的全局变量和局部静态变量(上述代码中的global_uninit_var和static_var2),准确的说是.bss段为他们预留了空间。
    • 有些编译器将未初始化的全局变量存放在目标文件.bss段,有些不存放只是预留一个未定义的全局变量符号”COMMON 符号“,到最终链接成可执行文件的时候再在.bss段·分配空间。
    • 但编译单元内部可见的静态变量(如·global_uninit_var加上static修饰),是存放在.bss段。
    • static int x1 = 0;

      x1被放在.bss段,因为可以认为是未初始化的,所以被优化放在.bss段。
    • static int x2 = 1;

      x2被放在.data段,因为初始化值为1,所以放在.data段。
  4. 其他段:
    链接、装载与库——目标文件(2)第三章 目标文件里面有什么
  5. 自定义段:
    • _attribute_((section("FOO"))) int global = 42;

    • _attribute_((section("BAR"))) void foo()

      在全局变量和函数之前加上

      _attribute_((section("name")))

      属性可以把相应的变量或函数放到以”name“作为的段中。

*以上为主要段,下一次总结ELF文件结构,包括文件头、段表。。。*