summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2015-12-27 23:04:11 +0000
committerimp <imp@FreeBSD.org>2015-12-27 23:04:11 +0000
commit242eb0dd48954e213c0e8c98e17c6f8c35036171 (patch)
tree738e22ce5f535bb3cb23f43dbbb8df5930fcf1f3 /lib
parentff4639fd533acae73c015e5b8659f9f5abaa073c (diff)
downloadFreeBSD-src-242eb0dd48954e213c0e8c98e17c6f8c35036171.zip
FreeBSD-src-242eb0dd48954e213c0e8c98e17c6f8c35036171.tar.gz
The FILE structure has a mbstate_t in it. This structure needs to be
aligned on a int64_t boundary. However, when we allocate the array of these structures, we use ALIGNBYTES which defaults to sizeof(int) on arm, i386 and others. The i386 stuff can handle unaligned accesses seemlessly. However, arm cannot. Take this into account when creating the array of FILEs, and add some comments about why. Differential Revision: https://reviews.freebsd.org/D4708
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdio/findfp.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
index b8bb5af..6a68958 100644
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <spinlock.h>
@@ -96,11 +97,22 @@ moreglue(int n)
struct glue *g;
static FILE empty = { ._fl_mutex = PTHREAD_MUTEX_INITIALIZER };
FILE *p;
+ size_t align;
- g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE));
+ /*
+ * FILE has a mbstate_t variable. This variable tries to be int64_t
+ * aligned through its definition. int64_t may be larger than void *,
+ * which is the size traditionally used for ALIGNBYTES. So, use our own
+ * rounding instead of the MI ALIGN macros. If for some reason
+ * ALIGNBYTES is larger than int64_t, respect that too. There appears to
+ * be no portable way to ask for FILE's alignment requirements other
+ * than just knowing here.
+ */
+ align = MAX(ALIGNBYTES, sizeof(int64_t));
+ g = (struct glue *)malloc(sizeof(*g) + align + n * sizeof(FILE));
if (g == NULL)
return (NULL);
- p = (FILE *)ALIGN(g + 1);
+ p = (FILE *)roundup((uintptr_t)(g + 1), align);
g->next = NULL;
g->niobs = n;
g->iobs = p;
OpenPOWER on IntegriCloud