Kaydet (Commit) 9c9f0ea2 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Include RTTI in generated vtables for ubsan's vptr-based checks

...though only on gcc3_linux_x86-64 for now.

Change-Id: Id90554425e78b38a5a97149f2a7d3ac04cbe0c9b
üst 525063f2
......@@ -125,7 +125,7 @@ ifneq ($(filter DRAGONFLY FREEBSD LINUX NETBSD OPENBSD,$(OS)),)
bridges_SELECTED_BRIDGE := gcc3_linux_x86-64
bridge_asm_objects := call
bridge_noncallexception_noopt_objects := callvirtualmethod
bridge_exception_objects := abi cpp2uno except uno2cpp
bridge_exception_objects := abi cpp2uno except rtti uno2cpp
else ifeq ($(OS),MACOSX)
bridges_SELECTED_BRIDGE := gcc3_macosx_x86-64
bridge_exception_objects := abi call cpp2uno except uno2cpp
......
......@@ -128,9 +128,11 @@ private:
void freeBlock(Block const & block) const;
void createVtables(
sal_Int32 createVtables(
GuardedBlocks & blocks, BaseOffset const & baseOffset,
typelib_InterfaceTypeDescription * type, bool includePrimary) const;
typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber,
typelib_InterfaceTypeDescription * mostDerived, bool includePrimary)
const;
// This function is not defined in the generic part, but instead has to be
// defined individually for each CPP--UNO bridge:
......@@ -150,9 +152,15 @@ private:
@param block the start address of the raw vtable block
@param slotCount the number of slots
@param vtableNumber zero-based count across all the most derived type's
vtables (for vtable's "offset to top" slot)
@param type non-null most derived type (for vtable's "typeinfo pointer"
slot)
@return a pointer past the last vtable slot
*/
static Slot * initializeBlock(void * block, sal_Int32 slotCount);
static Slot * initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
typelib_InterfaceTypeDescription * type);
// This function is not defined in the generic part, but instead has to be
// defined individually for each CPP--UNO bridge:
......
......@@ -579,7 +579,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -507,7 +507,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -498,7 +498,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -469,7 +469,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -592,7 +592,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -497,7 +497,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -642,7 +642,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -598,7 +598,7 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
bridges::cpp_uno::shared::VtableFactory::Slot* bridges::cpp_uno::shared::VtableFactory::initializeBlock(void * block, sal_Int32 slotCount)
bridges::cpp_uno::shared::VtableFactory::Slot* bridges::cpp_uno::shared::VtableFactory::initializeBlock(void * block, sal_Int32 slotCount, sal_Int32, typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
Slot foo = {0,0};
......
......@@ -443,7 +443,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -454,7 +454,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -731,7 +731,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
......
......@@ -709,7 +709,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -639,7 +639,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -609,7 +609,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -572,7 +572,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -487,7 +487,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
......
......@@ -27,6 +27,7 @@
#include <com/sun/star/uno/genfunc.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"
#include <config_options.h>
#include <uno/data.h>
#include <typelib/typedescription.hxx>
......@@ -37,6 +38,7 @@
#include "abi.hxx"
#include "call.hxx"
#include "rtti.hxx"
#include "share.hxx"
using namespace ::osl;
......@@ -448,11 +450,16 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
typelib_InterfaceTypeDescription * type)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
#if ENABLE_RUNTIME_OPTIMIZATIONS
slots[-1].fn = 0;
#else
slots[-1].fn = x86_64::getRtti(type->aBase);
#endif
return slots + slotCount;
}
......
......@@ -20,15 +20,9 @@
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <boost/unordered_map.hpp>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/instance.hxx>
#include <osl/diagnose.h>
#include <osl/mutex.hxx>
#include <sal/log.hxx>
#include <com/sun/star/uno/genfunc.hxx>
......@@ -36,6 +30,7 @@
#include <typelib/typedescription.hxx>
#include <uno/any2.h>
#include "rtti.hxx"
#include "share.hxx"
......@@ -86,121 +81,6 @@ static OUString toUNOname( char const * p )
#endif
}
class RTTI
{
typedef boost::unordered_map< OUString, type_info *, OUStringHash > t_rtti_map;
Mutex m_mutex;
t_rtti_map m_rttis;
t_rtti_map m_generatedRttis;
void * m_hApp;
public:
RTTI();
~RTTI();
type_info * getRTTI( typelib_CompoundTypeDescription * );
};
RTTI::RTTI()
#if defined(FREEBSD) && __FreeBSD_version < 702104
: m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
#else
: m_hApp( dlopen( 0, RTLD_LAZY ) )
#endif
{
}
RTTI::~RTTI()
{
dlclose( m_hApp );
}
type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
{
type_info * rtti;
OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
MutexGuard guard( m_mutex );
t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
if (iFind == m_rttis.end())
{
// RTTI symbol
OStringBuffer buf( 64 );
buf.append( "_ZTIN" );
sal_Int32 index = 0;
do
{
OUString token( unoName.getToken( 0, '.', index ) );
buf.append( token.getLength() );
OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
buf.append( c_token );
}
while (index >= 0);
buf.append( 'E' );
OString symName( buf.makeStringAndClear() );
#if defined(FREEBSD) && __FreeBSD_version < 702104 /* #i22253# */
rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
#else
rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
#endif
if (rtti)
{
pair< t_rtti_map::iterator, bool > insertion (
m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
SAL_WARN_IF( !insertion.second, "bridges", "key " << unoName << " already in rtti map" );
}
else
{
// try to lookup the symbol in the generated rtti map
t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
if (iFind2 == m_generatedRttis.end())
{
// we must generate it !
// symbol and rtti-name is nearly identical,
// the symbol is prefixed with _ZTI
char const * rttiName = symName.getStr() +4;
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr,"generated rtti for %s\n", rttiName );
#endif
if (pTypeDescr->pBaseTypeDescription)
{
// ensure availability of base
type_info * base_rtti = getRTTI(
(typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
rtti = new __si_class_type_info(
strdup( rttiName ), (__class_type_info *)base_rtti );
}
else
{
// this class has no base class
rtti = new __class_type_info( strdup( rttiName ) );
}
pair< t_rtti_map::iterator, bool > insertion (
m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
SAL_WARN_IF( !insertion.second, "bridges", "key " << unoName << " already in generated rtti map" );
}
else // taking already generated rtti
{
rtti = iFind2->second;
}
}
}
else
{
rtti = iFind->second;
}
return rtti;
}
extern "C" {
static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
{
......@@ -217,11 +97,6 @@ static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
}
}
namespace
{
struct theRTTI : public rtl::Static<RTTI, theRTTI> {};
}
void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
{
#if OSL_DEBUG_LEVEL > 1
......@@ -252,8 +127,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
// destruct uno exception
::uno_any_destruct( pUnoExc, 0 );
// avoiding locked counts
static RTTI &rRTTI = theRTTI::get();
rtti = rRTTI.getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
rtti = x86_64::getRtti(*pTypeDescr);
TYPELIB_DANGER_RELEASE( pTypeDescr );
OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
if (! rtti)
......
......@@ -29,6 +29,7 @@
#endif
#include "config_gcc.h"
#include "uno/any2.h"
#include "uno/mapping.h"
#ifdef _LIBCPP_VERSION
......
......@@ -450,7 +450,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -665,7 +665,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -441,7 +441,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -438,7 +438,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -485,7 +485,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
......
......@@ -434,7 +434,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -441,7 +441,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
......
......@@ -432,7 +432,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount)
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
struct Rtti {
sal_Int32 n0, n1, n2;
......
......@@ -447,7 +447,8 @@ sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block,
sal_Int32 slotCount )
sal_Int32 slotCount,
sal_Int32, typelib_InterfaceTypeDescription * )
{
struct Rtti {
sal_Int32 n0, n1, n2;
......
......@@ -207,7 +207,7 @@ VtableFactory::Vtables VtableFactory::getVtables(
Map::iterator i(m_map.find(name));
if (i == m_map.end()) {
GuardedBlocks blocks(*this);
createVtables(blocks, BaseOffset(type), type, true);
createVtables(blocks, BaseOffset(type), type, 0, type, true);
Vtables vtables;
OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
vtables.count = static_cast< sal_Int32 >(blocks.size());
......@@ -323,9 +323,10 @@ void VtableFactory::freeBlock(Block const & block) const {
}
#endif
void VtableFactory::createVtables(
sal_Int32 VtableFactory::createVtables(
GuardedBlocks & blocks, BaseOffset const & baseOffset,
typelib_InterfaceTypeDescription * type, bool includePrimary) const
typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber,
typelib_InterfaceTypeDescription * mostDerived, bool includePrimary) const
{
if (includePrimary) {
sal_Int32 slotCount
......@@ -335,7 +336,8 @@ void VtableFactory::createVtables(
throw std::bad_alloc();
}
try {
Slot * slots = initializeBlock(block.start, slotCount);
Slot * slots = initializeBlock(
block.start, slotCount, vtableNumber, mostDerived);
unsigned char * codeBegin =
reinterpret_cast< unsigned char * >(slots);
unsigned char * code = codeBegin;
......@@ -366,8 +368,11 @@ void VtableFactory::createVtables(
}
}
for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
vtableNumber = createVtables(
blocks, baseOffset, type->ppBaseTypes[i],
vtableNumber + (i == 0 ? 0 : 1), mostDerived, i != 0);
}
return vtableNumber;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment