表达式的语法和 C 语言的表达式语法一样,表达式的值都是整形,如果 ld 的运行主机
和生成文件的目标机都是 32 位,则表达式是 32 位数据,否则是 64 位数据。能够在表
达式内使用的值,设置符号的值。表达式格式如下:
一个简单例子
这个例子中, _edata 符号的值是 .data section 的末尾值(绝对值,在程序地址空间
内)
链接脚本相关的内建函数:
-
ABSOLUTE(EXP): 转换成绝对值
-
ADDR(SECTION): 返回某 section 的 VMA 值
-
ALIGN(EXP): 返回定位符 . 的修调值,对齐后的值,(. + EXP - 1) & ~(EXP - 1)
-
BLOCK(EXP): 如同 ALIGN(EXP),为了向前兼容
- DEFINED(SYMBOL): 如果符号 SYMBOL 在全局符号表内,且被定义了,那么返回 1,
否则返回 0
-
LOADADDR(SECTION): 返回某 SECTION 的 LMA
-
MAX(EXP1, EXP2): 返回大者
-
MIN(EXP1,EXP2): 返回小者
-
NEXT(EXP): 返回下一个能被使用的地址,该地址是 EXP 的倍数,类似于
ALIGN(EXP)。除非使用 MEMORY 命令定义了一些非连续的内存块,否则 NEXT(EXP)
与 ALIGN(一定相同)
-
SIZEOF(SECTION): 返回 SECTION 的大小。当 SECTION 没有被分配时,即此时
SECTION 大小不能确定,链接器会报错,
- SIZEOF_HEADERS: 返回输出文件的文件头大小,用以确定第一个 section 的开始
地址
e.g. 三个源文件 DemoA.c,DemoB.c 和 DemoC.c,其中 DemoA.c 引用 DemoA.c 和
DemoB.c 里面的函数,使用 GCC 生成独立的目标文件 DemoA.o,DemoB.o 和 DemoC.o。
ld 使用链接脚本 Demo.lds, 并且在 Demo.lds 里面通过使用多个赋值语句关键字:
DemoA.c
DemoB.c
DemoC.c
Demo.lds
使用如下命令进行编译和链接:
附录
BiscuitOS Home
BiscuitOS Driver
BiscuitOS Kernel Build
Linux Kernel
Bootlin: Elixir Cross Referencer
赞赏一下吧 🙂