summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Horák <dan@danny.cz>2023-09-12 10:20:51 +0200
committerThorsten Behrens <thorsten.behrens@allotropia.de>2023-10-15 22:13:57 +0200
commitcbb05abcdc9f77ba7a51830377987900c2bee477 (patch)
tree0cfd56cb71072e3b42af452b8a9f4036ec9438d2
parent6fbb129a7cff016ea92bf294f74c06bfacff90e4 (diff)
bridge/powerpc64: fix integer ABI
The ABI document for PowerPC64 specifies that integer values shorter than a doubleword are sign or zero extended as necessary. Until now the smaller values were treated as unsigned values and only zero-extended. Handling of signed values was incorrect. Change-Id: Icbbe8fc8d4facfa6d1b3252c99ec2d8c2552d9f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156847 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com> (cherry picked from commit 0effeef3dc952959af50c045514bbcd135c37fb7) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156873
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx58
1 files changed, 52 insertions, 6 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
index 612495d83395..9b66f778dfd6 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -257,6 +257,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_Int64 *>( pSV ); \
+ else \
+ bOverflow = true; \
+ if (bOverflow) \
+ *pDS++ = *reinterpret_cast<sal_Int64 *>( pSV );
+
+#define INSERT_UINT64( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
else \
bOverflow = true; \
@@ -265,6 +273,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_Int32 *>( pSV ); \
+ else \
+ bOverflow = true; \
+ if (bOverflow) \
+ *pDS++ = *reinterpret_cast<sal_Int32 *>( pSV );
+
+#define INSERT_UINT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
else \
bOverflow = true; \
@@ -273,6 +289,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_Int16 *>( pSV ); \
+ else \
+ bOverflow = true; \
+ if (bOverflow) \
+ *pDS++ = *reinterpret_cast<sal_Int16 *>( pSV );
+
+#define INSERT_UINT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
else \
bOverflow = true; \
@@ -281,6 +305,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_Int8 *>( pSV ); \
+ else \
+ bOverflow = true; \
+ if (bOverflow) \
+ *pDS++ = *reinterpret_cast<sal_Int8 *>( pSV );
+
+#define INSERT_UINT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
else \
bOverflow = true; \
@@ -335,7 +367,7 @@ static void cpp_call(
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
#endif
- INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow );
+ INSERT_UINT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow );
}
}
// push "this" pointer
@@ -343,7 +375,7 @@ static void cpp_call(
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
#endif
- INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverflow );
+ INSERT_UINT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverflow );
// Args
void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
@@ -376,26 +408,40 @@ static void cpp_call(
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
#endif
INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#if OSL_DEBUG_LEVEL > 2
+ fprintf(stderr, "uhyper is 0x%lx\n", *(sal_Int64 *)pCppArgs[nPos]);
+#endif
+ INSERT_UINT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
+ break;
case typelib_TypeClass_LONG:
- case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
#endif
INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+#if OSL_DEBUG_LEVEL > 2
+ fprintf(stderr, "ulong is 0x%x\n", *(sal_Int32 *)pCppArgs[nPos]);
+#endif
+ INSERT_UINT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
+ break;
case typelib_TypeClass_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
+ break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
- INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
+ INSERT_UINT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_BOOLEAN:
+ INSERT_UINT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
+ break;
case typelib_TypeClass_BYTE:
INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
@@ -454,7 +500,7 @@ static void cpp_call(
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
- INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverflow );
+ INSERT_UINT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverflow );
}
}