lifting-bits / remill

Library for lifting machine code to LLVM bitcode
Apache License 2.0
1.26k stars 142 forks source link

Build errors on ubuntu 20.04 with #526

Open pgoodman opened 3 years ago

pgoodman commented 3 years ago

image image image

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
thedataking commented 3 years ago

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.

pgoodman commented 3 years ago

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

pgoodman commented 3 years ago

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.