RTTI через границы модулей в Itanium и MSVC ABI

Я читаю Itanium ABI, в котором говорится, что

Предполагается, что два указателя type_info указывают на эквивалентные описания типов тогда и только тогда, когда указатели равны. Реализация должна удовлетворять этому ограничению, например. с использованием вытеснения символов, разделов COMDAT или других механизмов.

Кто-нибудь знает кровавые подробности о том, как это достигается на практике на популярных платформах, таких как, скажем, Linux с использованием GCC и GNU binutils, при использовании динамически загружаемых библиотек? Насколько это надежно?

Кроме того, у меня сложилось впечатление, что сравнения typeid в MSVC реализованы (были?) с использованием сравнений строк во время выполнения для искаженных имен символов именно потому, что это требование не может быть гарантировано выполнено. Это все еще так, как это делается? И существуют ли технические ограничения платформы, которые не позволяют MSVC использовать ту же технику, которая используется на платформах Itanium ABI?

EDIT Еще один вопрос: перехват исключений через границы модуля (в любом ABI) также зависит от информации RTTI, или есть другой механизм, помимо эквивалента среды выполнения dynamic_casts?


person Stephen Lin    schedule 04.03.2013    source источник


Ответы (1)


MSVC сначала использует сравнение указателей, а затем, если это не удается, сравнивает строки. Вы можете увидеть реализацию в исходниках CRT 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 всегда использует только сравнение указателей. Предполагается, что при работе с DLL динамический загрузчик должен гарантировать наличие единственного экземпляра объекта typeinfo для каждого исключения в адресном пространстве программы.

Если вас интересует фактическая реализация исключения RTTI и информация о перехвате, ознакомьтесь с моей статьей OpenRCE (MSVC) и презентация Recon 2012 (GCC, MSVC x64).

person Igor Skochinsky    schedule 25.02.2014