C++ Name Mangling
c++ 代码经过编译器编译之后,得到的 elf 文件中的函数符号和代码中定义的不一致,这个现象有一个专业名称:Name Mangling
背景
如下 C++ 代码所示:
/* name mangling test cpp file `lib.cpp` */
#include <iostream>
int test_func(int i, double j) {
return (int)(i*j);
}
int main() {
std::cout << "testing" << std::endl;
test_func(1, 2.0);
return 0;
}
g++ 编译之后,通过 readelf 读取编译出的二进制符号表,发现了一个很奇怪的现象——函数名称发生变化,如下所示:
root@ubuntu-jammy:~# g++ -o lib lib.cpp
root@ubuntu-jammy:~# readelf -a lib | grep test_func
21: 00000000000011a9 36 FUNC GLOBAL DEFAULT 16 _Z9test_funcid
Name Mangling
上述现象其实是 C++ 编译器的行为,它按照一定的规则对函数名进行了重新矫正,这个行为有一个专业叫法:Name Mangling,Name Mangling 需要解决的本质问题是:解决名字唯一性的问题。
GCC Name Mangling
对于 C++ 的 Name Mangling 规则,C++ 标准并没有做具体的规定,但各个编译器平台形成了一些事实性的标准。比如GCC的一个简单规则:
A global object with class or namespace qualifiers is coded as
<public name> ::= _Z <qualified name>
where
<qualified name> ::= N[<simple name> ]E
<simple name> ::= <name length> <name>
就是一个类的成员函数可能会被Name Mangling编码为:_Z+N+长度+名字+E
Name De-mangling
GNU Binutils 工具集中提供了 Name De-Mangling 相关的工具:
1. nm -C xxx
2. objdump -C xxx
3. readelf -C xxx
Public discussion