C++符号反混淆的不确定性

7
_ZNSaIwEC1Ev
_ZNSaIwEC2Ev

这两个C++符号不同,但是使用C++filt或类似工具解缠后,它们会变成相同的形式:

std::allocator<wchar_t>::allocator()
std::allocator<wchar_t>::allocator()

为什么会这样?可能是解缩器的缺陷还是其他什么原因?

反混淆函数的逆函数是否需要是单射的非常重要吗?我只看到了混淆函数是单射的重要性。 - SU3
1个回答

10

g++使用由Itanium ABI指定的名称重载方案(以及其他实现细节)。

构造函数和析构函数的重载部分中,我们可以看到:

<ctor-dtor-name> ::= C1 # complete object constructor
                 ::= C2 # base object constructor
                 ::= C3 # complete object allocating constructor
                 ::= D0 # deleting destructor
                 ::= D1 # complete object destructor
                 ::= D2 # base object destructor
  • “完整对象构造函数”包括C1,是直接用于初始化的普通构造函数。
  • “基础对象构造函数”包括C2,被派生类构造函数用来初始化其基类子对象。当涉及到虚继承时,这可以与“完整构造函数”不同,因为只有完整构造函数才会初始化虚基类,而基类构造函数则假定其虚基类已经被初始化。
  • “完整对象分配构造函数”包括C3,可能包括对operator new的调用。但据我所知,g++实际上从未使用过这个。
  • “删除析构函数”包括D0,以调用适当的标量operator delete结束。这是必要的,以便将其与虚析构函数绑定,因为正确的operator delete可能是一个静态类成员,而基类对此一无所知。
  • “完整对象析构函数”包括D1,类似于C1构造函数的反向操作,并包括虚基类的析构函数调用。
  • “基础对象析构函数”包括D2,类似于C2构造函数的反向操作,并省略对虚基类的析构函数调用。

因此,你所询问的C1C2名称中包含的信息对于C++系统来说非常重要,必须正确地链接每个信息。但是,这些信息在伪代码声明中很难简要解释,因此解密函数只是将两个符号描述为相同的。

尽管std::allocator<T>通常不具有任何虚基类,但很可能这两个符号实际上指向相同的代码地址,而g++提供了两个链接器符号以保持一致性。


2
在我的情况下,它们不指向相同的地址,但代码是相同的。 - def

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接