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

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

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

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

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

РЕДАКТИРОВАТЬ Еще один вопрос: действительно ли перехват исключений через границы модуля (в любом ABI) также зависит от информации RTTI, или есть другой механизм, помимо эквивалента времени выполнения dynamic_casts?

4

Решение

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).

1

Другие решения

Других решений пока нет …