The calculation of OBJALLOC_ALIGN in include/objalloc.h ensures that
allocations are sufficiently aligned for doubles, but on CHERI
architectures it is possible that void * has a greater alignment
requirement than double.
Instead of deriving the alignment requirement from double alone, this
patch uses a union to compute the maximum alignment between double and
void *.
This fixes alignment faults seen when compiling the binutils for
pure-capability Morello. With this patch applied, the majority of
binutils tests pass when the binutils themselves are compiled for
purecap.
This patch is a backport of commit
a8af417a8a1559a3ebceb0c761cf26ebce5eab7f, initially upstreamed to
Morello GCC.
/* Work out the required alignment. */
-struct objalloc_align { char x; double d; };
+struct objalloc_align {
+ char x;
+ union {
+ double d;
+ void *p;
+ } u;
+};
#if defined (__STDC__) && __STDC__
#ifndef offsetof
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
-#define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
+#define OBJALLOC_ALIGN offsetof (struct objalloc_align, u)
/* Create an objalloc structure. Returns NULL if malloc fails. */