You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何区分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)、类型标识或直接结束。

函数实现思路

  1. 过滤非_ZN开头的符号(两者均遵循Itanium ABI,开头统一为_ZN,不符合的直接返回false)
  2. 检查符号长度是否足够容纳Rust的后缀结构(至少需要21位,不足直接返回false)
  3. 从末尾反向验证:
    • 确认最后一个字符是E
    • 找到倒数第17位的字符是否为h
    • 验证h之后到E之前的16个字符全为十六进制
  4. 满足所有条件则返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:26:27