Kaydet (Commit) 970ad502 authored tarafından Caolán McNamara's avatar Caolán McNamara

Related: rhbz#1125588 ppc64le has new struct passing rules

http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html

now we just fail instead of crash

Change-Id: I329c676337885bcf4fdfdcdb5912d75424862126
üst d931eb2a
......@@ -72,7 +72,7 @@ static typelib_TypeClass cpp2uno_call(
if (pReturnTypeDescr)
{
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
if (!ppc64::return_in_hidden_param(pReturnTypeRef))
{
pUnoReturn = pRegisterReturn; // direct way for simple types
}
......@@ -599,7 +599,7 @@ const int codeSnippetSize = 24;
#endif
unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
bool simpleRetType)
bool bHasHiddenParam)
{
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
......@@ -608,9 +608,8 @@ unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
if ( !simpleRetType )
if ( bHasHiddenParam )
nOffsetAndIndex |= 0x80000000;
#if _CALL_ELF == 2
unsigned int *raw = (unsigned int *)&code[0];
......@@ -629,7 +628,7 @@ unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
#endif
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
nFunctionIndex, nVtableOffset, bHasHiddenParam, raw[2]);
#endif
return (code + codeSnippetSize);
}
......@@ -696,7 +695,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
(s++)->fn = code + writetoexecdiff;
code = codeSnippet(
code, functionOffset++, vtableOffset,
bridges::cpp_uno::shared::isSimpleType(
ppc64::return_in_hidden_param(
reinterpret_cast<
typelib_InterfaceAttributeTypeDescription * >(
member)->pAttributeTypeRef));
......@@ -707,7 +706,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
member)->bReadOnly)
{
(s++)->fn = code + writetoexecdiff;
code = codeSnippet(code, functionOffset++, vtableOffset, true);
code = codeSnippet(code, functionOffset++, vtableOffset, false);
}
break;
......@@ -715,7 +714,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
(s++)->fn = code + writetoexecdiff;
code = codeSnippet(
code, functionOffset++, vtableOffset,
bridges::cpp_uno::shared::isSimpleType(
ppc64::return_in_hidden_param(
reinterpret_cast<
typelib_InterfaceMethodTypeDescription * >(
member)->pReturnTypeRef));
......
......@@ -85,6 +85,7 @@ void fillUnoException(
namespace ppc64
{
enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
}
#endif
......
......@@ -37,6 +37,56 @@
using namespace ::rtl;
using namespace ::com::sun::star::uno;
namespace ppc64
{
#if _CALL_ELF == 2
bool is_complex_struct(const typelib_TypeDescription * type)
{
const typelib_CompoundTypeDescription * p
= reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
for (sal_Int32 i = 0; i < p->nMembers; ++i)
{
if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
{
typelib_TypeDescription * t = 0;
TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
bool b = is_complex_struct(t);
TYPELIB_DANGER_RELEASE(t);
if (b) {
return true;
}
}
else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
return true;
}
if (p->pBaseTypeDescription != 0)
return is_complex_struct(&p->pBaseTypeDescription->aBase);
return false;
}
#endif
bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
{
if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
return false;
#if _CALL_ELF == 2
else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
{
typelib_TypeDescription * pTypeDescr = 0;
TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
//A Composite Type not larger than 16 bytes is returned in up to two GPRs
bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
TYPELIB_DANGER_RELEASE( pTypeDescr );
return bRet;
}
#endif
return true;
}
}
void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
{
switch (eTypeClass)
......
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