Skip to content

Commit

Permalink
fix 32 bit int simple return of riscv64 bridge
Browse files Browse the repository at this point in the history
Sometimes we need to return a 32 bit integer into a 64 bit integer.
For example, in pyuno.cxx:PyUNO_bool(), an int(32bit) is returned in
type Py_ssize_t(64bit). We assume that this 32bit int was put in low
32 bit of register a0. The bridge may return with high 32 bit
uncleaned and compiler might directly bind this register to 64 bit
variable in error.

This bug produces when build pyuno with gcc-12 with -O2.
https://bugs.documentfoundation.org/show_bug.cgi?id=155937
https://lists.debian.org/debian-riscv/2023/07/msg00011.html

So we need to clean the high 32 bit in bridge.

Change-Id: I37aafb03ba9523cfb90912871308921fbeaf5f0c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154837
Tested-by: René Engelhard <[email protected]>
Reviewed-by: René Engelhard <[email protected]>
Reviewed-by: Stephan Bergmann <[email protected]>
  • Loading branch information
Sakura286 authored and stbergmann committed Jul 31, 2023
1 parent 5526c52 commit 2c25807
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,6 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
case typelib_TypeClass_CHAR:
case typelib_TypeClass_SHORT:
Expand All @@ -367,6 +365,28 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
case typelib_TypeClass_BYTE:
std::memcpy(pReturn, pUnoReturn, 8);
break;
// Sometimes we need to return a 32 bit integer into a 64 bit integer.
// For example, in pyuno.cxx:PyUNO_bool(), an int(32bit) is returned
// in type Py_ssize_t(64bit)
// We assume that this 32bit int was put in low 32 bit of register a0.
// The bridge may return with high 32 bit uncleaned and compiler might
// directly bind this register to 64 bit variable.
//
// This bug occurs when build pyuno with gcc-12 with -O2.
// https://bugs.documentfoundation.org/show_bug.cgi?id=155937
//
// So we need to clean the high 32 bit in bridge.
case typelib_TypeClass_UNSIGNED_LONG:
std::memset(pReturn + 4, 0x0, 4);
std::memcpy(pReturn, pUnoReturn, 4);
break;
case typelib_TypeClass_LONG:
if (*reinterpret_cast<sal_uInt32*>(pUnoReturn) & 0x80000000)
std::memset(pReturn + 4, 0xFF, 4);
else
std::memset(pReturn + 4, 0x0, 4);
std::memcpy(pReturn, pUnoReturn, 4);
break;
case typelib_TypeClass_FLOAT:
std::memcpy(pReturn, pUnoReturn, 4);
std::memset(pReturn + 4, 0xFF, 4);
Expand Down Expand Up @@ -628,7 +648,7 @@ unsigned char* codeSnippet(unsigned char* code, sal_Int32 functionIndex, sal_Int

/* generate this code */
/*
It is complex to load a 64bit address because uou cannot load
It is complex to load a 64bit address because you cannot load
an unsigned number to register on RISC-V.
# load functionIndex to t4
00000eb7 lui t4,0x0
Expand Down

0 comments on commit 2c25807

Please sign in to comment.