编译链接概念,VMA/LMA是什么
编译基础概念
为了描述链接器脚本语言,我们需要定义一些基本概念和词汇。
链接器干的主要事情就是把输入文件整合成一个输出文件。那么输入是什么?输出是什么?怎么整合?整合的是什么信息?
输入和输出文件都是object
文件格式。它们都称为目标文件。输出文件又称为可执行文件。它们的内容格式类似,都有很多的sections
。
一个节可能被标记为loadable
,这意味着应该将内容加载到内存中,输出文件才能运行起来。没有内容的部分可能是allocatable
,这意味着应该留出内存中的一个区域,但不应该在那里加载任何特定内容(在某些情况下,必须将该内存清零)。既不可加载也不可分配的部分通常包含某种调试信息。
每个loadable or allocatable
的输出部分都有两个地址。第一个是VMA或虚拟内存地址。这是运行输出文件时该节将具有的地址。第二个是LMA或加载存储器地址。这是加载节的地址。在大多数情况下,这两个地址将是相同的。
它们可能不同的一个例子是,将数据段加载到ROM中,然后在程序启动时复制到RAM中(这种技术通常用于在基于ROM的系统中初始化全局变量)。在这种情况下,ROM地址将是LMA,而RAM地址将是VMA。
每个对象文件都有一个符号列表,称为符号表
。符号可以定义也可以未定义。每个符号都有一个名称,每个定义的符号都有地址以及其他信息
。如果您将一个C或C++程序编译到一个对象文件中,您将为每个定义的函数和全局或静态变量获得一个定义的符号。输入文件中引用的每个未定义函数或全局变量都将成为未定义符号。
使用objdump -h
命令可以查看section的信息。
使用nm
或者objdump -t
可查看符号表的信息。
所以上面的问题可以简单回一下。
输入和输出文件都是object类型的文件。链接器把输入文件的相同section进行合并,不同的section继续保留。
https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html
Ref
GCC链接脚本帮助文档:https://sourceware.org/binutils/docs/ld/Scripts.html