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);
        }

Reply via email to