【问题标题】:RTTI across module boundaries in Itanium and MSVC ABIs在 Itanium 和 MSVC ABI 中跨模块边界的 RTTI
【发布时间】:2013-02-19 03:18:30
【问题描述】:

我正在阅读Itanium ABI 上面的内容

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

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

另外,我的印象是,MSVC 中的typeid 比较是(曾经?)使用运行时字符串比较对错位符号名称实现的,因为不能保证满足这一要求。这仍然是它的完成方式吗?是否存在阻止 MSVC 使用与 Itanium ABI 平台相同的技术的技术平台限制?

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

【问题讨论】:

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


    【解决方案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)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 2017-11-10
      • 2019-08-12
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多