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

时间:2013-03-04 21:40:34

标签: c++ visual-c++ gcc rtti abi

我正在阅读说明

Itanium ABI
  

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

有没有人知道在使用动态加载的库时,在使用GCC和GNU binutils的Linux等流行平台上如何实现这一点的血腥细节?它有多可靠?

另外,我认为MSVC中的typeid比较是(使用?)在错位符号名称上使用运行时字符串比较,因为无法保证满足此要求。这仍然是它的方式吗?是否有技术平台限制阻止MSVC使用与Itanium ABI平台相同的技术?

编辑还有一个问题:跨越模块边界(在ABI中)捕获的异常是否也依赖于RTTI信息,或者除了相当于运行时dynamic_cast之外还有其他机制吗? S'

1 个答案:

答案 0 :(得分:1)

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;
    }
    ...

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

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