Mention IFUNC enhancements to testsuite in NEWS.
[platform/upstream/glibc.git] / elf / tst-align2.c
1 /* Copyright (C) 2005 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <errno.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/wait.h>
24 #include <tst-stack-align.h>
25 #include <unistd.h>
26
27 static int res, fds[2], result;
28 static bool test_destructors;
29
30 extern void in_dso (int *, bool *, int *);
31
32 static void __attribute__ ((constructor)) con (void)
33 {
34   res = TEST_STACK_ALIGN () ? -1 : 1;
35 }
36
37 static void __attribute__ ((destructor)) des (void)
38 {
39   if (!test_destructors)
40     return;
41
42   char c = TEST_STACK_ALIGN () ? 'B' : 'A';
43   write (fds[1], &c, 1);
44 }
45
46 static int
47 do_test (void)
48 {
49   if (!res)
50     {
51       puts ("binary's constructor has not been run");
52       result = 1;
53     }
54   else if (res != 1)
55     {
56       puts ("binary's constructor has been run without sufficient alignment");
57       result = 1;
58     }
59
60   if (TEST_STACK_ALIGN ())
61     {
62       puts ("insufficient stack alignment in do_test");
63       result = 1;
64     }
65
66   in_dso (&result, &test_destructors, &fds[1]);
67
68   if (pipe (fds) < 0)
69     {
70       printf ("couldn't create pipe: %m\n");
71       return 1;
72     }
73
74   pid_t pid = fork ();
75   if (pid < 0)
76     {
77       printf ("fork failed: %m\n");
78       return 1;
79     }
80
81   if (!pid)
82     {
83       close (fds[0]);
84       test_destructors = true;
85       exit (0);
86     }
87
88   close (fds[1]);
89
90   unsigned char c;
91   ssize_t len;
92   int des_seen = 0, dso_des_seen = 0;
93   while ((len = TEMP_FAILURE_RETRY (read (fds[0], &c, 1))) > 0)
94     {
95       switch (c)
96         {
97         case 'B':
98           puts ("insufficient alignment in binary's destructor");
99           result = 1;
100           /* FALLTHROUGH */
101         case 'A':
102           des_seen++;
103           break;
104         case 'D':
105           puts ("insufficient alignment in DSO destructor");
106           result = 1;
107           /* FALLTHROUGH */
108         case 'C':
109           dso_des_seen++;
110           break;
111         default:
112           printf ("unexpected character %x read from pipe", c);
113           result = 1;
114           break;
115         }
116     }
117
118   close (fds[0]);
119
120   if (des_seen != 1)
121     {
122       printf ("binary destructor run %d times instead of once\n", des_seen);
123       result = 1;
124     }
125
126   if (dso_des_seen != 1)
127     {
128       printf ("DSO destructor run %d times instead of once\n", dso_des_seen);
129       result = 1;
130     }
131
132   int status;
133   pid_t termpid;
134   termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
135   if (termpid == -1)
136     {
137       printf ("waitpid failed: %m\n");
138       result = 1;
139     }
140   else if (termpid != pid)
141     {
142       printf ("waitpid returned %ld != %ld\n",
143               (long int) termpid, (long int) pid);
144       result = 1;
145     }
146   else if (!WIFEXITED (status) || WEXITSTATUS (status))
147     {
148       puts ("child hasn't exited with exit status 0");
149       result = 1;
150     }
151
152   return result;
153 }
154
155 #define TEST_FUNCTION do_test ()
156 #include "../test-skeleton.c"