diff --git a/CHANGELOG.md b/CHANGELOG.md index a0237927f9..83af927976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Native: clean up stale envelopes after crashes with `SENTRY_TRANSPORT=none`. ([#2049](https://github.com/getsentry/sentry-native/pull/2049)) - `sentry_set_trace` omits `parent_span_id` when the caller does not provide one, instead of serializing it as `null`. ([#2047](https://github.com/getsentry/sentry-native/pull/2047)) - Native/Linux i386: write valid thread stack descriptors to minidumps when stack addresses use the upper half of the 32-bit address space. ([#2054](https://github.com/getsentry/sentry-native/pull/2054)) +- Linux/ARM32: fix builds on 32-bit ARM systems, including 32-bit Raspberry Pi OS installations running a 64-bit kernel. ([#2063](https://github.com/getsentry/sentry-native/pull/2063)) - Guard size arithmetic when parsing envelopes and Linux OS release data, copying slices, and allocating memory during crash handling. ([#2059](https://github.com/getsentry/sentry-native/pull/2059)) **Thank you**: diff --git a/CMakeLists.txt b/CMakeLists.txt index 12615fd976..3d3c63e053 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -661,6 +661,11 @@ if(ANDROID) set(_SENTRY_PLATFORM_LIBS "dl" "log") elseif(LINUX) set(_SENTRY_PLATFORM_LIBS "dl" "rt") + sentry_find_atomic_library(_SENTRY_ATOMIC_LIBRARY) + if(_SENTRY_ATOMIC_LIBRARY) + list(APPEND _SENTRY_PLATFORM_LIBS "${_SENTRY_ATOMIC_LIBRARY}") + endif() + unset(_SENTRY_ATOMIC_LIBRARY) elseif(WIN32) if (XBOX) set(_SENTRY_PLATFORM_LIBS "version") diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 3b43ccf4d1..de8e4f3196 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -22,3 +22,28 @@ function(sentry_get_property NAME) endif() set("SENTRY_${NAME}" "${prop}" PARENT_SCOPE) endfunction() + +function(sentry_find_atomic_library OUT_VAR) + include(CheckCSourceCompiles) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + set(ATOMIC_U64_SOURCE " + #include + uint64_t value; + int main(void) { + return (int)__atomic_load_n(&value, __ATOMIC_SEQ_CST); + }") + check_c_source_compiles("${ATOMIC_U64_SOURCE}" SENTRY_HAVE_ATOMIC_U64) + if(SENTRY_HAVE_ATOMIC_U64) + set(ATOMIC_LIBRARY) + else() + set(CMAKE_REQUIRED_LIBRARIES atomic) + check_c_source_compiles("${ATOMIC_U64_SOURCE}" SENTRY_HAVE_ATOMIC_U64_WITH_LIB) + if(NOT SENTRY_HAVE_ATOMIC_U64_WITH_LIB) + message(FATAL_ERROR "64-bit atomic operations are not supported") + endif() + set(ATOMIC_LIBRARY atomic) + endif() + cmake_pop_check_state() + set(${OUT_VAR} "${ATOMIC_LIBRARY}" PARENT_SCOPE) +endfunction() diff --git a/src/modulefinder/sentry_modulefinder_linux.c b/src/modulefinder/sentry_modulefinder_linux.c index 595885b10c..37cf6ae80c 100644 --- a/src/modulefinder/sentry_modulefinder_linux.c +++ b/src/modulefinder/sentry_modulefinder_linux.c @@ -506,7 +506,7 @@ sentry__procmaps_module_to_value(const sentry_module_t *module) mmapped_module.is_mmapped = true; mmapped_module.num_mappings = 1; mmapped_module.mappings[0].addr - = (uint64_t)mm.ptr + module->offset_in_inode; + = (uint64_t)(uintptr_t)mm.ptr + module->offset_in_inode; mmapped_module.mappings[0].size = mm.len - module->offset_in_inode; sentry__procmaps_read_ids_from_elf(mod_val, &mmapped_module); diff --git a/src/sentry_cpu_relax.h b/src/sentry_cpu_relax.h index e19e6a22c8..de3312d4f4 100644 --- a/src/sentry_cpu_relax.h +++ b/src/sentry_cpu_relax.h @@ -13,8 +13,10 @@ #else # if defined(__i386__) || defined(__x86_64__) || defined(__amd64__) # define sentry__cpu_relax() __asm__ __volatile__("pause") -# elif defined(__aarch64__) || defined(__arm__) +# elif defined(__aarch64__) # define sentry__cpu_relax() __asm__ __volatile__("yield") +# elif defined(__arm__) +# define sentry__cpu_relax() __asm__ __volatile__("nop") # elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) # define sentry__cpu_relax() __asm__ __volatile__("or 27,27,27") # elif defined(__riscv) diff --git a/tests/unit/test_modulefinder.c b/tests/unit/test_modulefinder.c index 3173c3ba1d..27b36c6566 100644 --- a/tests/unit/test_modulefinder.c +++ b/tests/unit/test_modulefinder.c @@ -203,16 +203,17 @@ parse_elf_and_check_code_and_build_id(const char *rel_elf_path, sentry_module_t module = { 0 }; module.num_mappings = 1; - size_t *file_size = &module.mappings[0].size; - char **buf = (char **)&module.mappings[0].addr; sentry_value_t value = sentry_value_new_object(); sentry_path_t *elf_path = sentry__path_join_str(dir, rel_elf_path); - *buf = sentry__path_read_to_buffer(elf_path, file_size); + size_t file_size = 0; + char *buf = sentry__path_read_to_buffer(elf_path, &file_size); sentry__path_free(elf_path); + module.mappings[0].addr = (uint64_t)(uintptr_t)buf; + module.mappings[0].size = file_size; TEST_CHECK(sentry__procmaps_read_ids_from_elf(value, &module)); - sentry_free(*buf); + sentry_free(buf); sentry__path_free(dir); if (expected_code_id) { diff --git a/vendor/libunwind/CMakeLists.txt b/vendor/libunwind/CMakeLists.txt index 7de5085c97..6b46e7c9e1 100644 --- a/vendor/libunwind/CMakeLists.txt +++ b/vendor/libunwind/CMakeLists.txt @@ -16,22 +16,27 @@ set(LIBUNWIND_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src") set(LIBUNWIND_INC "${CMAKE_CURRENT_SOURCE_DIR}/include") # Detect architecture -if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64") - set(UNWIND_ARCH "x86_64") - set(UNWIND_ELF "elf64") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|arm64") - set(UNWIND_ARCH "aarch64") - set(UNWIND_ELF "elf64") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3-6]86|x86") - set(UNWIND_ARCH "x86") - set(UNWIND_ELF "elf32") -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|ARM)") - set(UNWIND_ARCH "arm") - set(UNWIND_ELF "elf32") +string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _UNWIND_PROCESSOR) +if(_UNWIND_PROCESSOR MATCHES "^(x86_64|amd64|x64|i[3-6]86|x86)$") + set(_UNWIND_ARCH_32 "x86") + set(_UNWIND_ARCH_64 "x86_64") +elseif(_UNWIND_PROCESSOR MATCHES "^(aarch64|arm64|arm)") + set(_UNWIND_ARCH_32 "arm") + set(_UNWIND_ARCH_64 "aarch64") else() message(FATAL_ERROR "Unsupported architecture for vendored libunwind: ${CMAKE_SYSTEM_PROCESSOR}") endif() +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(UNWIND_ARCH "${_UNWIND_ARCH_32}") + set(UNWIND_ELF "elf32") +elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(UNWIND_ARCH "${_UNWIND_ARCH_64}") + set(UNWIND_ELF "elf64") +else() + message(FATAL_ERROR "Unsupported pointer size for vendored libunwind: ${CMAKE_SIZEOF_VOID_P}") +endif() + # Common sources (libunwind_la_SOURCES_common + os sources for Linux) set(UNWIND_COMMON_SOURCES ${LIBUNWIND_SRC}/os-linux.c