monero FTBFS on riscv64 due to toolchain issues:
[ 64%] Linking CXX executable signature_fuzz_tests
cd "/<<PKGBUILDDIR>>/obj-riscv64-linux-gnu/tests/fuzz" && /usr/bin/cmake -E cmake_link_script CMakeFiles/signature_fuzz_tests.dir/link.txt --verbose=1
/usr/bin/c++ -g -O2 -ffile-prefix-map=/<<PKGBUILDDIR>>=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -pthread -DNO_AES -fno-strict-aliasing -std=c++11 -D_GNU_SOURCE -Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized -Wlogical-op -Wno-error=maybe-uninitialized -Wno-error=cpp -Wno-reorder -Wno-missing-field-initializers -fPIC -Wformat -Wformat-security -fstack-protector -fstack-protector-strong -fstack-clash-protection -fno-strict-aliasing -ftemplate-depth=900 -Wl,-Bsymbolic-functions -Wl,-z,relro -pie -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -rdynamic CMakeFiles/signature_fuzz_tests.dir/signature.cpp.o CMakeFiles/signature_fuzz_tests.dir/fuzzer.cpp.o -o signature_fuzz_tests ../../lib/libwallet.a ../../src/cryptonote_core/libcryptonote_core.a ../../src/p2p/libp2p.a ../../contrib/epee/src/libepee.a ../../src/device/libdevice.a -Wl,-Bstatic -lrt -Wl,-Bdynamic -ldl ../../src/rpc/librpc_base.a ../../src/mnemonics/libmnemonics.a ../../src/device_trezor/libdevice_trezor.a ../../src/cryptonote_core/libcryptonote_core.a ../../src/multisig/libmultisig.a ../../src/blockchain_db/libblockchain_db.a ../../external/db_drivers/liblmdb/liblmdb.a ../../src/ringct/libringct.a ../../src/cryptonote_basic/libcryptonote_basic.a ../../src/device/libdevice.a -lhidapi-libusb ../../src/ringct/libringct_basic.a ../../src/blocks/libblocks.a ../../src/checkpoints/libcheckpoints.a ../../src/hardforks/libhardforks.a ../../src/net/libnet.a ../../src/common/libcommon.a ../../src/crypto/libcncrypto.a ../../contrib/epee/src/libepee.a ../../external/easylogging++/libeasylogging.a -lrandomx -lunbound -lboost_regex -lboost_date_time -lssl -lcrypto -lzmq -lpgm -lnorm -lgssapi_krb5 -lsodium ../../src/libversion.a -lminiupnpc -lboost_chrono -lboost_serialization -lboost_filesystem -lboost_system -lboost_thread -lboost_program_options -Wl,-Bstatic -lrt -Wl,-Bdynamic -ldl -latomic
../../external/db_drivers/liblmdb/liblmdb.a(mdb.c.o): in function `mdb_node_add':
./obj-riscv64-linux-gnu/external/db_drivers/liblmdb/./external/db_drivers/liblmdb/mdb.c:8245:(.text+0x44e6): relocation truncated to fit: R_RISCV_JAL against `mdb_assert_fail.constprop.0'
collect2: error: ld returned 1 exit status
make[3]: *** [tests/fuzz/CMakeFiles/signature_fuzz_tests.dir/build.make:166: tests/fuzz/signature_fuzz_tests] Error 1
make[3]: Leaving directory '/<<PKGBUILDDIR>>/obj-riscv64-linux-gnu'
make[2]: *** [CMakeFiles/Makefile2:4165: tests/fuzz/CMakeFiles/signature_fuzz_tests.dir/all] Error 2
make[2]: Leaving directory '/<<PKGBUILDDIR>>/obj-riscv64-linux-gnu'
make[1]: *** [Makefile:163: all] Error 2
make[1]: Leaving directory '/<<PKGBUILDDIR>>/obj-riscv64-linux-gnu'
dh_auto_build: error: cd obj-riscv64-linux-gnu && make -j1 "INSTALL=install --strip-program=true" VERBOSE=1 returned exit code 2
make: *** [debian/rules:47: binary-arch] Error 25
dpkg-buildpackage: error: debian/rules binary-arch subprocess returned exit status 2
If there are two callers in two .text sections (for example sections A, B), followed by two sections with R_RISCV_ALIGN type relocations (section C, D), then followed by the called functions in sections behind (section E), there is a chance to reproduce the issue.
I draw a picture to illustrate the problem:
high | |
^ -> | section E: cc, dd | <-
| | |______
| | | | |
| | | section D: align2 (R_RISCV_ALIGN) | |
| | |______
| | | | |
| | | section C: align1 (R_RISCV_ALIGN) | |
| | |______
| | | | |
| | | section B : ff (R_RISCV_CALL) |--
| | |______
| | | |
address low -- | section A : _start (R_RISCV_CALL) |
Consider this situation: Section A, B, C, D, E are linked in sequence. Section C and D have R_RISCV_ALIGN type relocations. Function _start() calls function cc(), function ff() calls dd(). The size of each section is 8, 8, 64, 0xfffbc, 10 bytes before relaxation.
In the first relaxation pass (info->relax_pass ==0), the R_RISCV_CALL relocations in section A and B couldn't be relaxed to R_RISCV_JAL, because the call from _start() to cc() and the call from ff() to dd() don't fit with 21-bit offset. The offset is 0x10001c indeed. In the first relaxation pass, nothing is done.
In the third relaxation pass (info->relax_pass ==2), the R_RISCV_ALIGN relocations in section C and D could be relaxed. The sizes of section C and D were changed to 34 and 0xfffba bytes. Now, the offset of the call from _start() to cc() is 0xffffe, the offset from ff() to dd() equals to this value too.
In the second round of relaxation, in the first pass (info->relax_pass ==0), the R_RISCV_CALL relocation in section A could be relaxed to R_RISCV_JAL. After the relaxation, section A's size is reduced by 4 bytes. So, section B's base address and every symbol go down 4 bytes forward. However section C, D and E will not go down 4 bytes, because of the .balign restriction placed in section C and D. relocation( )), the section B's symbol has been adjusted, then the bug is exposed.
But, when linker processes the relaxation of section B, it uses the original section B symbol addresses to calculate the offset of R_RISCV_CALL relocation (from ff() to dd()). The offset is within 1M bytes offset (0xffffe). So, the R_RISCV_CALL relocation is relaxed to R_RISCV_JAL. This is a mistake!
When linker finally performs the relocation (in perform_
I created a simple test case to trigger this issue:
riscv64- unknown- linux-gnu- gcc -nostdlib -o a.out a.s align_1.s align_2.s c.s ccgFgKhw. o: In function `ff':
/tmp/
(.text+0x0): relocation truncated to fit: R_RISCV_...