RTTI 跨 Itanium 和 MSVC ABI 中的模块边界

Ste*_*Lin 5 c++ gcc rtti abi visual-c++

我正在阅读Itanium ABI,上面写着

当且仅当指针相等时,两个 type_info 指针才指向等效类型描述。实现必须满足此约束,例如通过使用符号抢占、COMDAT 部分或其他机制。

有谁知道在流行平台(例如使用 GCC 和 GNU binutils 的 Linux)上使用动态加载库时如何在实践中实现这一点的具体细节?它有多可靠?

另外,我的印象是,typeidMSVC 中的比较是(是?)使用对损坏的符号名称进行运行时字符串比较来实现的,因为不能保证满足此要求。现在还是这样吗?是否存在技术平台限制阻止 MSVC 使用与 Itanium ABI 平台上使用的相同技术?

编辑还有一个问题:跨模块边界(在任一 ABI 中)捕获异常是否也依赖于 RTTI 信息,或者除了运行时的等效机制之外是否还涉及另一种机制dynamic_cast

Igo*_*sky 2

MSVC 首先使用指针比较,然后,如果失败,则比较字符串。可以在VS2012的CRT源码中看到实现:

extern "C" _CRTIMP int __cdecl __TypeMatch(
    HandlerType *pCatch,                // Type of the 'catch' clause
    CatchableType *pCatchable,          // Type conversion under consideration
    ThrowInfo *pThrow                   // General information about the thrown
                                        //   type.
) {
    // First, check for match with ellipsis:
    if (HT_IS_TYPE_ELLIPSIS(*pCatch)) {
        return TRUE;
    }

    // Not ellipsis; the basic types match if it's the same record *or* the
    // names are identical.
    if (HT_PTD(*pCatch) != CT_PTD(*pCatchable)
      && strcmp(HT_NAME(*pCatch), CT_NAME(*pCatchable)) != 0) {
        return FALSE;
    }
    ...
Run Code Online (Sandbox Code Playgroud)

Itanium ABI 始终仅使用指针比较。与 DLL 一起工作的方式是,动态加载程序应确保程序的地址空间中的每个异常都有一个 typeinfo 对象的实例。

如果您对异常 RTTI 的实际实现和捕获信息感兴趣,请查看我的OpenRCE 文章(MSVC) 和Recon 2012 演示文稿(GCC、MSVC x64)。