如何区分Rust旧版名字修饰与C++名字修饰?实现判断函数
区分Rust旧版名字修饰与C++符号的实现方案
要实现ELF_IsRustMangleSym函数,核心是抓住Rust旧版(legacy)名字修饰符号的独有特征,对比C++ Itanium ABI符号的差异:
关键特征区分
- Rust旧版符号的标志性结构:
符号结尾固定为h[16位十六进制哈希]E,比如示例中的h8df207f105c5d474E:- 最后一位是
E - 倒数第17位是
h(16位哈希 +h+E共18位) h与E之间的16个字符均为十六进制字符(0-9、a-f、A-F)
- 最后一位是
- C++符号的典型特征:
不会有这种固定的16位哈希后缀,结尾通常是函数标识(如构造函数C1、析构函数D1)、类型标识或直接结束。
函数实现思路
- 过滤非
_ZN开头的符号(两者均遵循Itanium ABI,开头统一为_ZN,不符合的直接返回false) - 检查符号长度是否足够容纳Rust的后缀结构(至少需要21位,不足直接返回false)
- 从末尾反向验证:
- 确认最后一个字符是
E - 找到倒数第17位的字符是否为
h - 验证
h之后到E之前的16个字符全为十六进制
- 确认最后一个字符是
- 满足所有条件则返回true,否则返回false
参考实现代码
#include <stdbool.h> #include <string.h> #include <ctype.h> bool ELF_IsRustMangleSym(const char* symName) { if (symName == NULL) return false; size_t len = strlen(symName); // 最小长度校验:_ZN + 基础模块名 + h[16]E,至少需21位 if (len < 21) return false; // 检查是否以_ZN开头 if (strncmp(symName, "_ZN", 3) != 0) return false; // 检查末尾是否为E if (symName[len - 1] != 'E') return false; // 定位h的位置:倒数第17位 size_t h_pos = len - 18; if (symName[h_pos] != 'h' && symName[h_pos] != 'H') return false; // 验证h后16个字符均为十六进制 for (size_t i = h_pos + 1; i < len - 1; ++i) { if (!isxdigit(symName[i])) { return false; } } return true; }
补充说明
- 该逻辑针对Rust旧版名字修饰有效,无需考虑新版Rust的
_R前缀符号 - C++符号恰好出现类似结构的概率极低,完全满足区分需求
内容的提问来源于stack exchange,提问作者super_jh
相关产品推荐
相关产品推荐

