mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 17:53:37 +08:00
Test for stack alignment.
This commit is contained in:
parent
ec8c29dc01
commit
7d58530341
71
linuxthreads/tst-align.c
Normal file
71
linuxthreads/tst-align.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <tst-stack-align.h>
|
||||
|
||||
static void *
|
||||
tf (void *arg)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
puts ("in thread");
|
||||
|
||||
if (TEST_STACK_ALIGN ())
|
||||
ok = false;
|
||||
|
||||
return ok ? NULL : (void *) -1l;
|
||||
}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
puts ("in main");
|
||||
|
||||
if (TEST_STACK_ALIGN ())
|
||||
ok = false;
|
||||
|
||||
pthread_t th;
|
||||
if (pthread_create (&th, NULL, tf, NULL) != 0)
|
||||
{
|
||||
puts ("create failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *res;
|
||||
if (pthread_join (th, &res) != 0)
|
||||
{
|
||||
puts ("join failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (res != NULL)
|
||||
ok = false;
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
@ -24,6 +24,7 @@
|
||||
#define FUNC_PREFIX q
|
||||
#define FLOAT_FMT_FLAG "L"
|
||||
#define FLOAT_NAME_EXT l
|
||||
#define FLOAT_MIN_10_EXP LDBL_MIN_10_EXP
|
||||
#if LDBL_MANT_DIG == 64
|
||||
# define NDIGIT_MAX 21
|
||||
#elif LDBL_MANT_DIG == 53
|
||||
@ -40,5 +41,16 @@
|
||||
# error "NDIGIT_MAX must be precomputed"
|
||||
# define NDIGIT_MAX (lrint (ceil (M_LN2 / M_LN10 * LDBL_MANT_DIG + 1.0)))
|
||||
#endif
|
||||
#if LDBL_MIN_10_EXP == -37
|
||||
# define FLOAT_MIN_10_NORM 1.0e-37L
|
||||
#elif LDBL_MIN_10_EXP == -307
|
||||
# define FLOAT_MIN_10_NORM 1.0e-307L
|
||||
#elif LDBL_MIN_10_EXP == -4931
|
||||
# define FLOAT_MIN_10_NORM 1.0e-4931L
|
||||
#else
|
||||
/* libc can't depend on libm. */
|
||||
# error "FLOAT_MIN_10_NORM must be precomputed"
|
||||
# define FLOAT_MIN_10_NORM exp10l (LDBL_MIN_10_EXP)
|
||||
#endif
|
||||
|
||||
#include "efgcvt_r.c"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1998, 1999, 2000, 2004 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
|
||||
@ -20,6 +20,7 @@
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -59,6 +60,10 @@ static testcase ecvt_tests[] =
|
||||
{ 123.01, -4, 3, "" },
|
||||
{ 126.71, -4, 3, "" },
|
||||
{ 0.0, 4, 1, "0000" },
|
||||
#if DBL_MANT_DIG == 53
|
||||
{ 0x1p-1074, 3, -323, "494" },
|
||||
{ -0x1p-1074, 3, -323, "494" },
|
||||
#endif
|
||||
/* -1.0 is end marker. */
|
||||
{ -1.0, 0, 0, "" }
|
||||
};
|
||||
|
@ -205,7 +205,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
|
||||
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
|
||||
tst-sem8 tst-sem9 \
|
||||
tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
|
||||
tst-align \
|
||||
tst-align tst-align2 \
|
||||
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
|
||||
tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
|
||||
tst-raise1 \
|
||||
|
@ -22,4 +22,6 @@ endif
|
||||
|
||||
ifeq ($(subdir),nptl)
|
||||
CFLAGS-pthread_create.c += -mpreferred-stack-boundary=4
|
||||
CFLAGS-tst-align.c += -mpreferred-stack-boundary=4
|
||||
CFLAGS-tst-align2.c += -mpreferred-stack-boundary=4
|
||||
endif
|
||||
|
@ -397,9 +397,12 @@ union user_desc_init
|
||||
#define CALL_THREAD_FCT(descr) \
|
||||
({ void *__res; \
|
||||
int __ignore1, __ignore2; \
|
||||
asm volatile ("pushl %%gs:%P4\n\t" \
|
||||
asm volatile ("pushl %%eax\n\t" \
|
||||
"pushl %%eax\n\t" \
|
||||
"pushl %%eax\n\t" \
|
||||
"pushl %%gs:%P4\n\t" \
|
||||
"call *%%gs:%P3\n\t" \
|
||||
"addl $4, %%esp" \
|
||||
"addl $16, %%esp" \
|
||||
: "=a" (__res), "=c" (__ignore1), "=d" (__ignore2) \
|
||||
: "i" (offsetof (struct pthread, start_routine)), \
|
||||
"i" (offsetof (struct pthread, arg))); \
|
||||
|
87
nptl/tst-align2.c
Normal file
87
nptl/tst-align2.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright (C) 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <tst-stack-align.h>
|
||||
|
||||
static int
|
||||
f (void *arg)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if (TEST_STACK_ALIGN ())
|
||||
ok = false;
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
puts ("in main");
|
||||
|
||||
if (TEST_STACK_ALIGN ())
|
||||
ok = false;
|
||||
|
||||
#ifdef __ia64__
|
||||
extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
|
||||
size_t __child_stack_size, int __flags,
|
||||
void *__arg, ...);
|
||||
char st[256 * 1024];
|
||||
pid_t p = __clone2 (f, st, sizeof (st), 0, 0);
|
||||
#else
|
||||
char st[128 * 1024];
|
||||
pid_t p = clone (f, st + sizeof (st), 0, 0);
|
||||
#endif
|
||||
if (p == -1)
|
||||
{
|
||||
printf("clone failed: %m\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int e;
|
||||
if (waitpid (p, &e, __WCLONE) != p)
|
||||
{
|
||||
puts ("waitpid failed");
|
||||
kill (p, SIGKILL);
|
||||
return 1;
|
||||
}
|
||||
if (!WIFEXITED (e))
|
||||
{
|
||||
if (WIFSIGNALED (e))
|
||||
printf ("died from signal %s\n", strsignal (WTERMSIG (e)));
|
||||
else
|
||||
puts ("did not terminate correctly");
|
||||
return 1;
|
||||
}
|
||||
if (WEXITSTATUS (e) != 0)
|
||||
ok = false;
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
42
sysdeps/i386/tst-stack-align.h
Normal file
42
sysdeps/i386/tst-stack-align.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 2004 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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#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; \
|
||||
})
|
@ -67,7 +67,7 @@ ENTRY (BP_SYM (__clone))
|
||||
/* Insert the argument onto the new stack. Make sure the new
|
||||
thread is started with an alignment of (mod 16). */
|
||||
andl $0xfffffff0, %ecx
|
||||
subl $24,%ecx
|
||||
subl $28,%ecx
|
||||
movl ARG(%esp),%eax /* no negative argument counts */
|
||||
movl %eax,12(%ecx)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user