Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RTTI across module boundaries in Itanium and MSVC ABIs

I am reading the Itanium ABI which says that

It is intended that two type_info pointers point to equivalent type descriptions if and only if the pointers are equal. An implementation must satisfy this constraint, e.g. by using symbol preemption, COMDAT sections, or other mechanisms.

Does anyone know the gory details about how this is accomplished in practice on popular platforms such as, say, Linux using GCC and GNU binutils, when using dynamically loaded libraries? How reliable is it?

Also, I'm under the impression from that typeid comparisons in MSVC are (were?) implemented using runtime string comparisons on mangled symbol names exactly because this requirement cannot be guaranteed to be satisfied. Is this still the way it's done? And are there technical platform constraints that prevent MSVC from utilizing the same technique as used on Itanium ABI platforms?

EDIT One more question: does exception catching across module boundaries (in either ABI) rely upon RTTI info as well, or is there another mechanism involved besides than the equivalent of runtime dynamic_casts?

like image 375
Stephen Lin Avatar asked Nov 03 '22 03:11

Stephen Lin


1 Answers

MSVC first uses pointer comparison, then, if that fails, compares the strings. You can see the implementation in the CRT sources of VS2012:

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 always uses only pointer comparison. The way it's supposed to work with DLLs is that the dynamic loader should ensure that there is a single instance of the typeinfo object for each exception in the address space of the program.

If you're interested in the actual implementation of the exception RTTI and catching info, check out my OpenRCE article (MSVC) and Recon 2012 presentation (GCC, MSVC x64).

like image 109
Igor Skochinsky Avatar answered Nov 13 '22 19:11

Igor Skochinsky