https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96973
--- Comment #4 from Francois-Xavier Coudert <fxcoudert at gcc dot gnu.org> --- I've identified the issue and found a fix. The problem is in the calculation of the offset when !is_64. The current code is take the uint32_t offset value, casting it into a uint64_t, then calling bswap64, which is wrong. The correct way is to call bswap32 and then cast to uint64_t. diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c index bd737226ca6..5974d8d8a5b 100644 --- a/libbacktrace/macho.c +++ b/libbacktrace/macho.c @@ -797,9 +797,13 @@ macho_add_fat (struct backtrace_state *state, const char *filename, uint32_t fcputype; if (is_64) - memcpy (&fat_arch, - (const char *) arch_view.data + i * arch_size, - arch_size); + { + memcpy (&fat_arch, + (const char *) arch_view.data + i * arch_size, + arch_size); + if (swapped) + fat_arch.offset = __builtin_bswap64 (fat_arch.offset); + } else { struct macho_fat_arch fat_arch_32; @@ -809,7 +813,10 @@ macho_add_fat (struct backtrace_state *state, const char *filename, arch_size); fat_arch.cputype = fat_arch_32.cputype; fat_arch.cpusubtype = fat_arch_32.cpusubtype; - fat_arch.offset = (uint64_t) fat_arch_32.offset; + if (swapped) + fat_arch.offset = (uint64_t) __builtin_bswap32(fat_arch_32.offset); + else + fat_arch.offset = (uint64_t) fat_arch_32.offset; fat_arch.size = (uint64_t) fat_arch_32.size; fat_arch.align = fat_arch_32.align; fat_arch.reserved = 0; @@ -821,14 +828,9 @@ macho_add_fat (struct backtrace_state *state, const char *filename, if (fcputype == cputype) { - uint64_t foffset; - /* FIXME: What about cpusubtype? */ - foffset = fat_arch.offset; - if (swapped) - foffset = __builtin_bswap64 (foffset); backtrace_release_view (state, &arch_view, error_callback, data); - return macho_add (state, filename, descriptor, foffset, match_uuid, + return macho_add (state, filename, descriptor, fat_arch.offset, match_uuid, base_address, skip_symtab, error_callback, data, fileline_fn, found_sym); }