From 6d24e32d0278e1e71cbd1bfdc16899659e47b2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= Date: Tue, 12 Sep 2023 10:20:51 +0200 Subject: [PATCH] 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 --- .../cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx index 4bb4270806b8..37d75659fdb6 100644 --- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx @@ -256,6 +256,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, *pDS++ = *reinterpret_cast( pSV ); // verbatim! #define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \ + if ( nr < ppc64::MAX_GPR_REGS ) \ + pGPR[nr++] = *reinterpret_cast( pSV ); \ + else \ + bOverflow = true; \ + if (bOverflow) \ + *pDS++ = *reinterpret_cast( pSV ); + +#define INSERT_UINT64( pSV, nr, pGPR, pDS, bOverflow ) \ if ( nr < ppc64::MAX_GPR_REGS ) \ pGPR[nr++] = *reinterpret_cast( pSV ); \ else \ @@ -264,6 +272,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, *pDS++ = *reinterpret_cast( pSV ); #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \ + if ( nr < ppc64::MAX_GPR_REGS ) \ + pGPR[nr++] = *reinterpret_cast( pSV ); \ + else \ + bOverflow = true; \ + if (bOverflow) \ + *pDS++ = *reinterpret_cast( pSV ); + +#define INSERT_UINT32( pSV, nr, pGPR, pDS, bOverflow ) \ if ( nr < ppc64::MAX_GPR_REGS ) \ pGPR[nr++] = *reinterpret_cast( pSV ); \ else \ @@ -272,6 +288,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, *pDS++ = *reinterpret_cast( pSV ); #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \ + if ( nr < ppc64::MAX_GPR_REGS ) \ + pGPR[nr++] = *reinterpret_cast( pSV ); \ + else \ + bOverflow = true; \ + if (bOverflow) \ + *pDS++ = *reinterpret_cast( pSV ); + +#define INSERT_UINT16( pSV, nr, pGPR, pDS, bOverflow ) \ if ( nr < ppc64::MAX_GPR_REGS ) \ pGPR[nr++] = *reinterpret_cast( pSV ); \ else \ @@ -280,6 +304,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, *pDS++ = *reinterpret_cast( pSV ); #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \ + if ( nr < ppc64::MAX_GPR_REGS ) \ + pGPR[nr++] = *reinterpret_cast( pSV ); \ + else \ + bOverflow = true; \ + if (bOverflow) \ + *pDS++ = *reinterpret_cast( pSV ); + +#define INSERT_UINT8( pSV, nr, pGPR, pDS, bOverflow ) \ if ( nr < ppc64::MAX_GPR_REGS ) \ pGPR[nr++] = *reinterpret_cast( pSV ); \ else \ @@ -339,7 +371,7 @@ static void cpp_call( #if OSL_DEBUG_LEVEL > 2 fprintf(stderr, "pCppReturn/pUnoReturn is %p/%p\n", pCppReturn, pUnoReturn); #endif - INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow ); + INSERT_UINT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow ); } } // push "this" pointer @@ -347,7 +379,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 ); @@ -380,26 +412,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 0x%lx\n", *(sal_Int64 *)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 0x%x\n", *(sal_Int32 *)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: - case typelib_TypeClass_CHAR: - case typelib_TypeClass_UNSIGNED_SHORT: INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow ); break; + case typelib_TypeClass_CHAR: + case typelib_TypeClass_UNSIGNED_SHORT: + 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; @@ -458,7 +504,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 ); } }