【问题标题】:Can objdump un-mangle names of C++ template functions?objdump 可以取消 C++ 模板函数的名称吗?
【发布时间】:2023-04-01 15:31:01
【问题描述】:

我有一个 C++ 目标文件,其中包含一些 C++ 模板函数的实例化。有问题的目标文件为模板参数的几个不同组合实例化了相同的函数。我正在尝试调试一个问题,并希望查看模板函数的特定实例化的反汇编(即,我知道要检查的函数的模板参数)。我通常会使用objdump 来反汇编目标文件,但它(至少在默认情况下)无法对 C++ 函数名称进行分解。有没有办法做到这一点?目标文件是使用 gcc 4.6.1 创建的。

【问题讨论】:

    标签: c++ gcc name-mangling objdump


    【解决方案1】:

    通过c++filt 传递它?可能需要给它-n,具体取决于符号是带下划线还是不带前导下划线。

    【讨论】:

    • 看起来可以。我还刚刚找到了objdump-C 选项,这似乎至少适用于我的应用程序。
    • @JasonR 更好。从历史上看,有一些选项和变体名称,例如nm++,但它们时常碰壁,我养成了只管所有东西的习惯。
    • @JasonR,感谢您发布此内容...-C 在我的objdump 版本中没有记录(--help 未显示),但它仍然有效。
    【解决方案2】:

    objdump -C

    -C 标志启用去杂化:

    printf '
    template<typename T>
    T add(T x, T y) {
        return x + y;
    }
    
    void h() {
        add(1, 2);
        add(1.0, 2.0);
    }
    ' > a.cpp
    g++ -g -std=c++11 a.cpp
    objdump -CS a.out
    

    输出包含解构后的名称:

    int main() {
        add(1, 2);
     60c:   e8 28 00 00 00          callq  639 <int add<int>(int, int)>
        add(1.0, 2.0);
     62d:   e8 1b 00 00 00          callq  64d <double add<double>(double, double)>
    
    0000000000000639 <int add<int>(int, int)>:
    
    000000000000064d <double add<double>(double, double)>:
    

    如果没有-C,则它包含错位的名称:

    0000000000000639 <_Z3addIiET_S0_S0_>:
    000000000000064d <_Z3addIdET_S0_S0_>:
    

    man objdump 说:

    将低级符号名称解码(解码)为用户级名称。除了删除系统前面的任何初始下划线外,这使得 C++ 函数名称可读。不同的编译器有不同的修饰风格。可选的反修饰样式参数可用于为您的编译器选择合适的反修饰样式。

    nm 也有 -C 选项。

    在 Ubuntu 18.04、g++7.3.0、objdump2.30 中测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多