GNU链接器(LD):什么是符号?符号定义及实例解析

0 参考资料

c 复制代码
GNU-LD-v2.30-中文手册.pdf
GNU linker.pdf

1 前言

一个完整的编译工具链应该包含以下4个部分:

(1)编译器

(2)汇编器

(3)链接器

(4)lib库

在GNU工具链中,对应的是:

(1)编译器:GCC(GNU Compiler Collection,GNU编译器套件)

(2)汇编器:GAS(GNU Assembler,GNU汇编器)

(3)链接器:LD(GNU Linker,GNU链接器)

(4)lib库:glibc(GNU C Library,GNU C 库)

本文介绍GNU链接器脚本中符号所谓何物,以及符号的定义及实例解析。

2 GNU linker(链接器,LD):什么是符号?符号定义及实例解析

2.1 什么是符号?

符号在链接器脚本(.ld文件)中类似于C语言中的变量,不同的是链接器脚本中的符号不需要定义类型,符号长度固定为CPU支持寻址的字长,支持负数,但不支持小数。同时,符号不占用内存空间,仅在编译阶段为编译器所用。

2.2 符号定义及实例解析

除非给符号名加上引号,否则符号名必须以字母、下划线或句点(.)作为开头,可以包括字母、数字、下划线、句点(.)、连字符(-)。没有添加引号的符号名不能和链接脚本的任何关键字一致。非要使用的话可以使用双引号包围符号名,如下:

c 复制代码
"SECTION" = 9;
"with a space" = "also with a space" + 10;

由于符号可以包括非字母的字符,为了避免混淆建议使用空格分隔符号。例如:

c 复制代码
A-B 是一个符号
A - B 是一个减法操作

符号定义实例

在链接脚本内定义了符号_TEST_symbol、._TEST-symbol2,值分别为-1、0xffffffff

c 复制代码
_TEST_symbol = -1;
._TEST-symbol2 = 0xffffffff;

编译生成的.map文件内容如下:

.map文件找不到这2个符号分配的内存空间地址,说明符号是不占用内存空间的,只是在编译时使用。
假如我们在链接器脚本给符号赋值超过CPU寻址字长,会发生什么呢?

c 复制代码
._TEST-symbol3 = 0x8888888811111111;

编译器不会报错,但打开.map文件可以看到符号只保留了CPU寻址字长能表示最大大小部分,超出部分直接被丢弃了:

假如我们在链接脚本内给符号赋值小数,会发生什么呢?

c 复制代码
._TEST-symbol3 = 0.1;

可以看到链接器返回了一个错误:

假如我们不给符号赋初值,会发生什么呢?

c 复制代码
._TEST-symbol3;

可以看到链接器返回了一个错误:

因此定义符号时需要严格遵守以下几点:

(1)必须要赋初值

(2)初值必须为整数(大小范围不能超过CPU寻址字长)

相关推荐
一丝晨光2 天前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
一丝晨光3 天前
GCC和clang的爱恨情仇
macos·objective-c·xcode·apple·clang·gcc·llvm
云中双月13 天前
如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)
linux·嵌入式·gdb·调试·gcc·崩溃·ida pro·ulimit·core dump·cross compile
witton19 天前
C语言实现Go的defer功能
c语言·clang·gcc·defer·attribute·cleanup·block type
码匠许师傅21 天前
【开源鸿蒙】OpenHarmony 5.0轻量系统最小开发环境搭建
python·pip·risc-v·openharmony·gcc·1024程序员节·hi3861
程序猿(攻城狮)23 天前
CentOS 7 安装gcc编译环境
linux·centos·gcc
CodingCos1 个月前
【ARM 嵌入式 编译系列 2.9 -- GCC 编译如何避免赋值判断 if ( x = 0)】
arm开发·gcc·arm gcc·gcc 编译
时光飞逝的日子1 个月前
GNU链接器(LD):输入分区的垃圾回收及保护处理(KEEP命令)介绍
垃圾回收·ld·保护·gnu链接器·keep
shylyly_1 个月前
编译链接的过程发生了什么?
linux·gcc·底层·编译链接
时差freebright1 个月前
【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法
linux·开发语言·gcc