From 34b33d447f958982af657b1d44dabbc7b6437e75 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 9 Jul 2019 15:27:59 +0800 Subject: [PATCH] cmake: check for unaligned access C and C++ allow us to cast a pointer with an alignment requirement to one with a different alignment requirement. but if the destination type's alignment is greater/stricter than the source type, the behavior is undefined. on amd64, it's allowed. and on aarch64, GCC offers an option named `-munaligned-access` to enable this behavior. so we cannot take this as guaranteed. in denc.h and messenger implementations, we just cast the pointers to the type we want to access without memcpy(), which is, strictly speaking, not quite standard compliant. so, to be on the safe side, we detect the support of unaligned access at compile time. please note, this would fail the cross-compile. as the target platform might not support unaligned access, and the produced executable does not run on the build platform. so this test is skipped if the building host's architecture is different than that of target host. Signed-off-by: Kefu Chai --- cmake/modules/CephChecks.cmake | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cmake/modules/CephChecks.cmake b/cmake/modules/CephChecks.cmake index 642d35eaa8935..f6dd41cf10555 100644 --- a/cmake/modules/CephChecks.cmake +++ b/cmake/modules/CephChecks.cmake @@ -89,3 +89,49 @@ CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h HAVE_STAT_ST_MTIM_TV_NSEC LANGUAGE C) CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec sys/stat.h HAVE_STAT_ST_MTIMESPEC_TV_NSEC LANGUAGE C) + +if(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR) + include(CheckCXXSourceRuns) + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++17") + check_cxx_source_runs(" +#include +#include +#include + +uint32_t load(char* p, size_t offset) +{ + return *reinterpret_cast(p + offset); +} + +bool good(uint32_t lhs, uint32_t small_endian) +{ + uint32_t rhs; + if (ntohl(0xdeadbeaf) == 0xdeadbeaf) { + return lhs == ntohl(small_endian); + } else { + return lhs == small_endian; + } +} + +int main(int argc, char **argv) +{ + char a1[] = \"ABCDEFG\"; + uint32_t a2[] = {0x44434241, + 0x45444342, + 0x46454443, + 0x47464544}; + for (size_t i = 0; i < std::size(a2); i++) { + if (!good(load(a1, i), a2[i])) { + return 1; + } + } +}" + HAVE_UNALIGNED_ACCESS) + cmake_pop_check_state() + if(NOT HAVE_UNALIGNED_ACCESS) + message(FATAL_ERROR "Unaligned access is required") + endif() +else(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR) + message(STATUS "Assuming unaligned access is supported") +endif(CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_HOST_SYSTEM_PROCESSOR) -- 2.39.5