本课时主要介绍编译器具体如何安排工程生成的指令、数据在内存中的存储位置,并简要介绍
gcc链接脚本的写法。
原理介绍
课程中通过分析工程的生成的反汇编文件和elf解析文件,展示了GCC工具链是如何安排代码、数据在内存中的存储,如下图所示。
具体而言,我们知道GCC工具链默认按.text, .rodata, .data, .bss存储代码和数据,并分析得出以下结论:
● .text:存储机器指令和代码
● .rodata:存储常量以及字符串本身
● .data:存储初始化的数据,全局的或者static静态的
● .bss:存储未初始化的数据(即初始化为0),全局的或者静态的
● stack:存储局部变量和函数调用中返回地址等
● 相同类型的段会自动进行合并
当然,具体的细节会比上述的要复杂很多,在此我们只是得出一个初步地认识。在以后的课程中,还将会更深入其中的一些细节。我们也可以自己编写一个简单的链接脚本,来替代默认的存储配置。在链接脚本中,可以做更为复杂和灵活的设置。其语法结构为:
section {
. = 虚拟地址;
.text/.rodata/.data/.bss : {
目标文件(.text/.data/.bss/.data) /*可使用通配符**/
}
}
参考资料
● GCC LD官方文档:https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html
● linker脚本(较易阅读):https://wiki.osdev.org/Linker_Scripts
● ARM Linker链接脚本:http://www.bravegnu.org/gnu-eprog/linker.html
● ld脚本编写:https://sourceware.org/binutils/docs/ld/
登陆发表评论