mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-17 13:00:43 +08:00
Properly check stack alignment [BZ #27901]
1. Replace if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) which may be optimized out by compiler, with int __attribute__ ((weak, noclone, noinline)) is_aligned (void *p, int align) { return (((uintptr_t) p) & (align - 1)) != 0; } 2. Add TEST_STACK_ALIGN_INIT to TEST_STACK_ALIGN. 3. Add a common TEST_STACK_ALIGN_INIT to check 16-byte stack alignment for both i386 and x86-64. 4. Update powerpc to use TEST_STACK_ALIGN_INIT. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
parent
1b992204f6
commit
79aec84102
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
/* Check stack alignment. Generic version.
|
||||
Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -18,17 +19,28 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int
|
||||
__attribute__ ((weak, noclone, noinline))
|
||||
is_aligned (void *p, int align)
|
||||
{
|
||||
return (((uintptr_t) p) & (align - 1)) != 0;
|
||||
}
|
||||
|
||||
#ifndef TEST_STACK_ALIGN_INIT
|
||||
# define TEST_STACK_ALIGN_INIT() 0
|
||||
#endif
|
||||
|
||||
#define TEST_STACK_ALIGN() \
|
||||
({ \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = 0; \
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
_ret; \
|
||||
})
|
||||
({ \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = TEST_STACK_ALIGN_INIT (); \
|
||||
\
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
_ret += is_aligned (&_d, __alignof (double)); \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, \
|
||||
__alignof (long double)); \
|
||||
_ret += is_aligned (&_ld, __alignof (long double)); \
|
||||
_ret; \
|
||||
})
|
||||
|
@ -1,44 +0,0 @@
|
||||
/* Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#ifndef __SSE__
|
||||
#include_next <tst-stack-align.h>
|
||||
#else
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define TEST_STACK_ALIGN() \
|
||||
({ \
|
||||
__m128 _m; \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = 0; \
|
||||
printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \
|
||||
if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
_ret; \
|
||||
})
|
||||
#endif
|
@ -1,41 +0,0 @@
|
||||
/* Copyright (C) 2004-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct { int i[4]; } int_al16 __attribute__((aligned (16)));
|
||||
|
||||
#define TEST_STACK_ALIGN() \
|
||||
({ \
|
||||
int_al16 _m; \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = 0; \
|
||||
printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \
|
||||
if ((((uintptr_t) &_m) & (__alignof (int_al16) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
_ret; \
|
||||
})
|
@ -1,4 +1,5 @@
|
||||
/* Copyright (C) 2005-2021 Free Software Foundation, Inc.
|
||||
/* Check stack alignment. PowerPC version.
|
||||
Copyright (C) 2005-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -15,10 +16,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define TEST_STACK_ALIGN() \
|
||||
#define TEST_STACK_ALIGN_INIT() \
|
||||
({ \
|
||||
/* Altivec __vector int etc. needs 16byte aligned stack. \
|
||||
Instead of using altivec.h here, use aligned attribute instead. */ \
|
||||
@ -27,20 +25,9 @@
|
||||
int _i __attribute__((aligned (16))); \
|
||||
int _j[3]; \
|
||||
} _s = { ._i = 18, ._j[0] = 19, ._j[1] = 20, ._j[2] = 21 }; \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = 0; \
|
||||
printf ("__vector int: { %d, %d, %d, %d } %p %zu\n", _s._i, _s._j[0], \
|
||||
_s._j[1], _s._j[2], &_s, __alignof (_s)); \
|
||||
if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
_ret; \
|
||||
})
|
||||
is_aligned (&_s, __alignof (_s)); \
|
||||
})
|
||||
|
||||
#include_next <tst-stack-align.h>
|
||||
|
28
sysdeps/x86/tst-stack-align.h
Normal file
28
sysdeps/x86/tst-stack-align.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* Check stack alignment. X86 version.
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef struct { int i[16]; } int_al16 __attribute__((aligned (16)));
|
||||
|
||||
#define TEST_STACK_ALIGN_INIT() \
|
||||
({ \
|
||||
int_al16 _m; \
|
||||
printf ("int_al16: %p %zu\n", &_m, __alignof (int_al16)); \
|
||||
is_aligned (&_m, __alignof (int_al16)); \
|
||||
})
|
||||
|
||||
#include_next <tst-stack-align.h>
|
@ -1,46 +0,0 @@
|
||||
/* Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define TEST_STACK_ALIGN() \
|
||||
({ \
|
||||
/* AMD64 ABI mandates 16byte aligned stack. \
|
||||
Unfortunately, current GCC doesn't support __int128 or __float128 \
|
||||
types, so use aligned attribute instead. */ \
|
||||
struct _S \
|
||||
{ \
|
||||
int _i __attribute__((aligned (16))); \
|
||||
int _pad[3]; \
|
||||
} _s = { ._i = 18 }; \
|
||||
double _d = 12.0; \
|
||||
long double _ld = 15.0; \
|
||||
int _ret = 0; \
|
||||
printf ("__int128: %d %p %zu\n", _s._i, &_s, __alignof (_s)); \
|
||||
if ((((uintptr_t) &_s) & (__alignof (_s) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
|
||||
if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
\
|
||||
printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
|
||||
if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
|
||||
_ret = 1; \
|
||||
_ret; \
|
||||
})
|
Loading…
Reference in New Issue
Block a user