Build errors on ubuntu 20.04 with

Example GCC command line:
[ 6%] Building CXX object lib/Arch/AArch32/CMakeFiles/remill_arch_aarch32.dir/Decode.cpp.o
cd /root/build/remill/lib/Arch/AArch32 && /usr/bin/c++ -DGFLAGS_DLL_DECLARE_FLAG="" -DGFLAGS_DLL_DEFINE_FLAG="" -DGFLAGS_IS_A_DLL=0 -DGOOGLE_GLOG_DLL_DECL="" -DNDEBUG -DREMILL_BUILD_SEMANTICS_DIR_AARCH32=\"/root/build/remill/lib/Arch/AArch32/Runtime\" -DREMILL_BUILD_SEMANTICS_DIR_AARCH64=\"/root/build/remill/lib/Arch/AArch64/Runtime\" -DREMILL_BUILD_SEMANTICS_DIR_SPARC32=\"/root/build/remill/lib/Arch/SPARC32/Runtime\" -DREMILL_BUILD_SEMANTICS_DIR_SPARC64=\"/root/build/remill/lib/Arch/SPARC64/Runtime\" -DREMILL_BUILD_SEMANTICS_DIR_X86=\"/root/build/remill/lib/Arch/X86/Runtime\" -DREMILL_INSTALL_SEMANTICS_DIR=\"/usr/local/share/remill/12/semantics\" -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/root/src/remill/include -isystem /root/vcpkg_ubuntu-20.04_llvm-12_amd64/installed/x64-linux-rel/include -O2 -g -DNDEBUG -fPIC -Wall -Wextra -Wno-unused-parameter -Wno-c++98-compat -Wno-unreachable-code-return -Wno-nested-anon-types -Wno-extended-offsetof -Wno-variadic-macros -Wno-return-type-c-linkage -Wno-c99-extensions -Wno-ignored-attributes -Wno-unused-local-typedef -Wno-unknown-pragmas -Wno-unknown-warning-option -fPIC -fno-omit-frame-pointer -fvisibility-inlines-hidden -fno-asynchronous-unwind-tables -gdwarf-2 -g3 -O2 -std=c++17 -MD -MT lib/Arch/AArch32/CMakeFiles/remill_arch_aarch32.dir/Decode.cpp.o -MF CMakeFiles/remill_arch_aarch32.dir/Decode.cpp.o.d -o CMakeFiles/remill_arch_aarch32.dir/Decode.cpp.o -c /root/src/remill/lib/Arch/AArch32/Decode.cpp
/root/src/remill/lib/Arch/AArch32/Decode.cpp: In function ‘void remill::{anonymous}::ExpandTo32AddImmAddCarry(remill::Instruction&, uint32_t, bool)’:
/root/src/remill/lib/Arch/AArch32/Decode.cpp:689:20: error: ‘__builtin_rotateright32’ was not declared in this scope; did you mean ‘__builtin_copysignf32’?
689 | AddImmOp(inst, __builtin_rotateright32(unrotated_value, rotation_amount));
| ^~~~~~~~~~~~~~~~~~~~~~~
| __builtin_copysignf32
GCC version:
root@sloth:~/build/remill# /usr/bin/c++ --version
c++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
I think the problem is that GCC doesn't support __builtin_rotateright{8,16,32,64}. It isn't mentioned in the GCC docs AFAICT. Check out the godbolt links below
I hacked build.sh by putting CC=clang-11 CXX=clang++-11 in front of the cmake command and that did the trick.
From another project we worked around this issue with the following functions:
/// Rotate `val` to the right `rot` positions.
inline static uint64_t RotateRight64(uint64_t val, unsigned rot) {
// NOTE: if we ever move to C++20, there are builtin rotation functions in the
// standard library, which we should use instead.
#ifdef __has_builtin
# if !__has_builtin(__builtin_rotateright64)
# define HYDE_NEEDS_ROR64 1
# else
# define HYDE_NEEDS_ROR64 0
# endif
#elif !defined(__clang__)
# define HYDE_NEEDS_ROR64 1
#endif
#if HYDE_NEEDS_ROR64
if (!rot)
return val;
return (val >> rot) | (val << (64u - (rot % 64u)));
#else
return __builtin_rotateright64(val, rot);
#endif
#undef HYDE_NEEDS_ROR64
}
/// Rotate `val` to the right `rot` positions.
inline static uint32_t RotateRight32(uint32_t val, unsigned rot) {
// NOTE: if we ever move to C++20, there are builtin rotation functions in the
// standard library, which we should use instead.
#ifdef __has_builtin
# if !__has_builtin(__builtin_rotateright32)
# define HYDE_NEEDS_ROR32 1
# else
# define HYDE_NEEDS_ROR32 0
# endif
#elif !defined(__clang__)
# define HYDE_NEEDS_ROR32 1
#endif
#if HYDE_NEEDS_ROR32
if (!rot)
return val;
return (val >> rot) | (val << (32u - (rot % 32u)));
#else
return __builtin_rotateright32(val, rot);
#endif
#undef HYDE_NEEDS_ROR32
}
We should just work these into the Arch/Runtime/Operators.h
We would presumable want to make sure that __builtin_rotateright* behaves the same way across architectures when given a zero rotation amount. If I remember correctly, John Regehr found some issues in our semantics related to this issue in the past.