yyqng

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 编译和链接

    gcc hello.c执行的四个步骤:

#预处理(Prepressing)
gcc -E hello.c -o hello.i

#编译(Compilation)
gcc -S hello.i -o hello.s
gcc -S hello.c -o hello.s

#汇编(Assembly)
as hello.s -o hello.o
gcc -c hello.s -o hello.o
gcc -c hello.c -o hello.o

#链接(Linking)
ld -static -L/lib lxxx.o hello.o -o a.out

     链接包括地址和空间分配(Address and Storage Allocation)、符号决议(Symbol Resolution)和重定位(Relocation)等步骤。静态链接的最基本的过程和作用就是修正引用位置的目的地址,让它们为真正的函数的地址。地址修正的过程就被叫做重定位,每个要被修正的地方叫一个重定位入口(Relocation Entry)。

 2. 目标文件里面有什么

    Windows下的PE(Portable Executable)和Linux的ELF(Executable Linkable Format)都是COFF(Common file format)格式的变种。目标文件(Windows的.obj和Linux的.o)、静态链接库(Windows的.lib和Linux的.a)、动态链接库(Windows的.dll和Linux的.so)和核心转储文件(Linux下的Core dump),都可广义地看成可执行文件。静态链接库稍有不同,可以简单地把它理解为一个很多目标文件组成的文件包。

    文件头:存放文件属性(是否可执行、是静态链接还是动态链接及入口地址等)、段表(偏移位置及段的属性等)

    代码段(Code Section)常见的名字有”.code”或”.text”:存放机器指令

    数据段(Data Section)一般名字都叫”.data”:已初始化的存放全局变量和局部静态变量数据

    .bss”的段:未初始化的全局变量和局部静态变量(预留位置,不占据磁盘空间)

    相关工具:

 

    size hello.o(查看ELF文件的各段的长度(dec:十进制,hex:十六进制))

    readelf 查看ELF文件头信息(-s打印符号表信息 -a打印所有信息)

    objdump -h hello.o(-h打印各段的基本信息,-x打印更多复杂的信息,-s以十六机制的方式打印各段内容,-d将所有包含指令的段反汇编)

     输出汇编文件和重定位表

1 objdump -dCW test.o > test_o.asm
2 objdump -r   test.o > test_o_relo.txt

 

     这些段名都由”.”作为前缀,表示是系统保留的表名。GCC提供了一个扩展机制,使得程序员可以指定变量所处的段

// FOO和BAR是段名
__attribute__((section(“FOO”))) int global = 42;
__attribute__((section(“BAR”))) void foo() {}

 

 

 

 

 

 

参考资料:

(5条消息) 程序员的自我修养--链接、装载与库笔记:总结_网络资源是无限的-CSDN博客

 

posted on 2021-09-21 12:27  zziii  阅读(270)  评论(0编辑  收藏  举报