以下是 GNU nm 常见的完整符号类型。通常大写表示全局符号,小写表示局部符号,但 U、u 等有特殊含义。
类型 | 含义 |
A | Absolute,绝对地址符号,不会因重定位改变 |
B / b | BSS 段中的全局/局部符号,通常用于零初始化或未显式初始化的数据 |
C / c | Common symbol,未分配段的公共符号,链接时合并或分配 |
D / d | 已初始化数据段中的全局/局部符号 |
G / g | small data 段中的已初始化全局/局部符号 |
I | 对另一个符号的间接引用 |
i | 间接函数(GNU IFUNC);在 PE 文件中也可能表示 DLL 相关符号 |
N | 调试符号 |
n | 局部只读数据或目标格式定义的特殊只读符号 |
P / p | 栈展开、过程描述或目标架构特定段中的符号 |
R / r | 只读数据段中的全局/局部符号,例如常量和字符串 |
S / s | small BSS 段中的未初始化全局/局部符号 |
T / t | 代码段中的全局/局部符号,通常是函数 |
U | Undefined,当前目标文件引用了该符号,但没有提供定义 |
u | GNU unique global symbol,动态链接时整个进程中保持唯一 |
V / v | 弱对象符号;未定义时链接不会报错 |
W / w | 弱非对象符号,通常是弱函数;未定义时链接不会报错 |
- | a.out 文件中的 STABS 调试符号 |
? | 未知类型或目标文件格式特有的符号 |
常见示例:
T functionName # 全局函数
t localFunction # 当前 .cc 内的局部函数
D globalValue # 已初始化全局变量
B zeroInitialized # BSS 全局对象
b localStatic # BSS 局部静态对象
R constTable # 只读全局数据
U externalFunction # 引用其他 .o 提供的函数
W weakFunction # 弱函数
small BSS 和普通 BSS 在语义上相同,都存放零初始化或未显式初始化的静态存储期对象。区别主要在访问方式和目标平台优化:
对比项 | BSS | small BSS |
常见段名 | .bss | .sbss |
nm 类型 | B / b | S / s |
数据特点 | 零初始化、通常不占可执行文件的数据空间 | 同样为零初始化 |
对象大小 | 没有特殊限制 | 通常放较小对象 |
访问方式 | 普通地址加载 | 可通过全局指针等短偏移指令访问 |
目的 | 保存零初始化数据 | 减少指令数量和代码体积、提高访问效率 |
例如在支持 small data 的架构上:
C++
int largeBuffer[1024]; // 通常进入 .bss
int smallCounter; // 可能进入 .sbsssmall BSS 常见于 MIPS、PowerPC、RISC-V 等嵌入式工具链。编译器把尺寸低于某个阈值的对象放入 .sbss,代码可以通过全局指针寄存器加较短的偏移量访问:
C++
普通 BSS:构造完整地址 -> 访问数据
small BSS:gp 寄存器 + 短偏移 -> 访问数据对象是否进入 .sbss 由以下因素决定:
- 目标 CPU 和 ABI 是否支持 small data;
- 编译器的 small-data 阈值;
- 编译选项,例如部分工具链的 -G <size>;
- 链接脚本对 .sbss 的布局;
- 对象的大小和可见性。
因此,B 和 S 不代表 C++ 生命周期或初始化逻辑不同,只代表链接器把对象放到了不同的段中。两者在程序启动时都被清零,通常都属于 ELF 的 NOBITS 段,不需要在二进制文件中保存完整的零数据。
评论 (0)




