C++杂记——Name Mangling

Name Mangling

什么是Name Mangling

编程语言组织程序,都有一定的可见范围,比如Java的包、C/C++的文件。就像我们平时使用的文件夹一样,有了这些组织机制,变量、函数的命名在一定程度上就可以重复。

但在程序链接时,这些机制多少都要失效一些,就像每个小朋友在家都叫宝宝,到了幼儿园就没办法通过宝宝来区分彼此了。为了解决名字的唯一性,就需要Name Mangling技术。

其实说白了就是对名字进行重新编码的一种规则。比如使用VIM随便打开一个ELF文件,或是链接时,我们有时候可以看到一些类似与下面这样的古怪字符串:

_ZN9NS_QZSOCK10CTcpClient11SendAndRecvEPciRiRjd

这就是经过Name Mangling处理后的符号。

任何name-mangling做法都有两个重点:

  1. 一个算法,推导出独一无二的名称
  2. 万一编译系统(或环境工具)必须和使用者交互,那些独一无二的名称可以轻易被推导回原来的名称

GCC中的Name Mangling

C++的复杂度相对于C肯定是复杂很多的,其中表现之一就是C++的名字管理,比如C++支持重载、支持类、命名空间等。不同的函数可以使用相同的函数名、不同的类可以有相同名字的成员变量。这样C++的Name Mangling就会比C复杂很多。

当然,再复杂的,也都不过是各种Tool Chain的一碟小菜。对于C++的Name Mangling规则,C++标准并没有做具体的规定,但各个编译器平台形成了一些事实性的标准,比如GCC的一个简单规则:

A global object with class or namespace qualifiers is coded as

::= _Z

where

::= N[ ]E

::=

就是一个类的成员函数可能会被Name Mangling编码为:_Z+N+长度+名字+E

GNU Binutils中Name De-Mangling的相关工具

GNU Binutils工具集中提供了Name De-Mangling相关的工具,最典型的c++filt和nm,使用举例如下:

bash 复制代码
c++filt _ZN9NS_QZSOCK10CTcpClient11SendAndRecvEPciRiRjd
NS_QZSOCK::CTcpClient::SendAndRecv(char*, int, int&, unsigned int&, double)

nm -C bin/play_url.so | grep SendAndRecv
0000000000391090 T NS_QZSOCK::CTcpClient::SendAndRecv(char*, int, int&, unsigned int&, double)
0000000000390a10 T NS_QZSOCK::CUdpClient::SendAndRecv(char*, int, int&, unsigned int&, double)

有了这些工具,再也不怕链接报错和二进制分析时看到的一些奇怪符号了。

相关推荐
yuanmenghao2 小时前
车载Linux 系统问题定位方法论与实战系列 - 车载 Linux 平台问题定位规范
linux·运维·服务器·网络·c++
小羊羊Python2 小时前
SoundMaze v1.0.1正式发布!
开发语言·c++
码小猿的CPP工坊5 小时前
C++软件开发之内存泄漏闭坑方法
开发语言·c++
Benny_Tang5 小时前
题解:CF2164C Dungeon
c++·算法
青小莫6 小时前
C语言vsC++中的动态内存管理(内含底层实现讲解!)
java·c语言·c++
持梦远方6 小时前
算法剖析1:摩尔投票算法 ——寻找出现次数超过一半的数
c++·算法·摩尔投票算法
AI视觉网奇7 小时前
ue5 自定义 actor ac++ actor 用法实战
java·c++·ue5
明洞日记7 小时前
【软考每日一练002】进程调度机制详解
c++·ai·操作系统·进程
FMRbpm7 小时前
树的练习6--------938.二叉搜索树的范围和
数据结构·c++·算法·leetcode·职场和发展·新手入门