Make sure packed structs follow the gcc memory layout
authorUlf Hermann <ulf.hermann@qt.io>
Fri, 18 Aug 2017 12:05:10 +0000 (14:05 +0200)
committerMark Wielaard <mark@klomp.org>
Wed, 20 Sep 2017 19:40:31 +0000 (21:40 +0200)
gcc defaults to using struct layouts that follow the native conventions,
even if __attribute__((packed)) is given. In order to get the layout we
expect, we need to tell gcc to always use the gcc struct layout, at
least for packed structs. To do this, we can use the gcc_struct
attribute.

This is important, not only for porting to windows, but also potentially
for other platforms, as the bugs resulting from struct layout
differences are rather subtle and hard to find.

Signed-off-by: Ulf Hermann <ulf.hermann@qt.io>
12 files changed:
ChangeLog
backends/ChangeLog
backends/linux-core-note.c
configure.ac
lib/ChangeLog
lib/eu-config.h
libcpu/ChangeLog
libcpu/memory-access.h
libdw/ChangeLog
libdw/memory-access.h
libelf/ChangeLog
libelf/gelf_xlate.c

index c0034ba..cb87833 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+       * configure.ac: Check if the compiler supports
+       __attribute__((gcc_struct)).
+
 2017-09-19  Mark Wielaard  <mark@klomp.org>
 
        * README: Add basic build instructions.
index 79b50eb..8c3f42c 100644 (file)
@@ -1,3 +1,7 @@
+2017-08-18  Ulf Hermann <ulf.hermann@qt.io>
+
+       * linux-core-note.c: Use attribute_packed.
+
 2017-04-27  Ulf Hermann <ulf.hermann@qt.io>
 
        * Makefile.am: Use dso_LDFLAGS.
index 67638d7..08282ba 100644 (file)
@@ -111,7 +111,7 @@ struct EBLHOOK(prstatus)
   FIELD (INT, pr_fpvalid);
 }
 #ifdef ALIGN_PRSTATUS
-  __attribute__ ((packed, aligned (ALIGN_PRSTATUS)))
+  attribute_packed __attribute__ ((aligned (ALIGN_PRSTATUS)))
 #endif
 ;
 
index fb18dfc..4ab8816 100644 (file)
@@ -143,6 +143,19 @@ if test "$ac_cv_visibility" = "yes"; then
                  [Defined if __attribute__((visibility())) is supported])
 fi
 
+AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))],
+       ac_cv_gcc_struct, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+struct test { int x; } __attribute__((gcc_struct));
+])], ac_cv_gcc_struct=yes, ac_cv_gcc_struct=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_gcc_struct" = "yes"; then
+       AC_DEFINE([HAVE_GCC_STRUCT], [1],
+                 [Defined if __attribute__((gcc_struct)) is supported])
+fi
+
 AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
 save_CFLAGS="$CFLAGS"
 CFLAGS="$save_CFLAGS -fPIC -Werror"
index 23c0f41..6123045 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+       * eu-config.h: Define attribute_packed to either
+       __attribute__((packed)) or __attribute__((packed, gcc_struct)).
+
 2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
 
        * eu-config.h: Define attribute_hidden to be empty if the compiler
index 0709828..135803e 100644 (file)
 #define attribute_hidden /* empty */
 #endif
 
+#ifdef HAVE_GCC_STRUCT
+#define attribute_packed \
+  __attribute__ ((packed, gcc_struct))
+#else
+#define attribute_packed \
+  __attribute__ ((packed))
+#endif
+
 /* Define ALLOW_UNALIGNED if the architecture allows operations on
    unaligned memory locations.  */
 #define SANITIZE_UNDEFINED 1
index 173defe..c710e5a 100644 (file)
@@ -1,3 +1,7 @@
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+       * memory-access.h: Use attribute_packed.
+
 2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
 
        * Makefile.am: Use fpic_CFLAGS.
index 44210e2..779825f 100644 (file)
@@ -90,7 +90,7 @@ union unaligned
     int16_t s2;
     int32_t s4;
     int64_t s8;
-  } __attribute__ ((packed));
+  } attribute_packed;
 
 static inline uint16_t
 read_2ubyte_unaligned (const void *p)
index c13344a..94e9c9a 100644 (file)
@@ -1,3 +1,7 @@
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+       * memory-access.h: Use attribute_packed.
+
 2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
 
        * libdwP.h: Use attribute_hidden.
index a749b5a..afb651f 100644 (file)
@@ -170,7 +170,7 @@ union unaligned
     int16_t s2;
     int32_t s4;
     int64_t s8;
-  } __attribute__ ((packed));
+  } attribute_packed;
 
 # define read_2ubyte_unaligned(Dbg, Addr) \
   read_2ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
index 9793d06..7bd9e1b 100644 (file)
@@ -1,3 +1,7 @@
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+       * gelf_xlate.c: Use attribute_packed.
+
 2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
 
        * libelfP.h: Use attribute_hidden.
index f3d3b7a..479f143 100644 (file)
@@ -74,7 +74,7 @@ union unaligned
     uint16_t u16;
     uint32_t u32;
     uint64_t u64;
-  } __attribute__ ((packed));
+  } attribute_packed;
 
 #define FETCH(Bits, ptr)       (((const union unaligned *) ptr)->u##Bits)
 #define STORE(Bits, ptr, val)  (((union unaligned *) ptr)->u##Bits = val)