summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2014-08-22 13:31:03 +0100
committerCaolán McNamara <caolanm@redhat.com>2014-08-22 13:34:50 +0100
commit970ad502e3ea2cc992c6cc1c7583231aec5bf5da (patch)
treef3e6d83febe42476fd0d0076202f9039efa47a0b /bridges
parentd931eb2a93d6ae8a2549077c446d2b856ebe9e41 (diff)
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
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx15
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx1
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx50
3 files changed, 58 insertions, 8 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
index c0ca97f400f7..dbdef1bce881 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -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));
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
index 87303b60c407..b5f609adc39a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
@@ -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
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
index 33131ea78799..55a53081cc95 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -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)