chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/wait.h>
25 #include <tst-stack-align.h>
26 #include <unistd.h>
27
28 static int res, fds[2], result;
29 static bool test_destructors;
30
31 extern void in_dso (int *, bool *, int *);
32
33 static void __attribute__ ((constructor)) con (void)
34 {
35   res = TEST_STACK_ALIGN () ? -1 : 1;
36 }
37
38 static void __attribute__ ((destructor)) des (void)
39 {
40   if (!test_destructors)
41     return;
42
43   char c = TEST_STACK_ALIGN () ? 'B' : 'A';
44   write (fds[1], &c, 1);
45 }
46
47 static int
48 do_test (void)
49 {
50   if (!res)
51     {
52       puts ("binary's constructor has not been run");
53       result = 1;
54     }
55   else if (res != 1)
56     {
57       puts ("binary's constructor has been run without sufficient alignment");
58       result = 1;
59     }
60
61   if (TEST_STACK_ALIGN ())
62     {
63       puts ("insufficient stack alignment in do_test");
64       result = 1;
65     }
66
67   in_dso (&result, &test_destructors, &fds[1]);
68
69   if (pipe (fds) < 0)
70     {
71       printf ("couldn't create pipe: %m\n");
72       return 1;
73     }
74
75   pid_t pid = fork ();
76   if (pid < 0)
77     {
78       printf ("fork failed: %m\n");
79       return 1;
80     }
81
82   if (!pid)
83     {
84       close (fds[0]);
85       test_destructors = true;
86       exit (0);
87     }
88
89   close (fds[1]);
90
91   unsigned char c;
92   ssize_t len;
93   int des_seen = 0, dso_des_seen = 0;
94   while ((len = TEMP_FAILURE_RETRY (read (fds[0], &c, 1))) > 0)
95     {
96       switch (c)
97         {
98         case 'B':
99           puts ("insufficient alignment in binary's destructor");
100           result = 1;
101           /* FALLTHROUGH */
102         case 'A':
103           des_seen++;
104           break;
105         case 'D':
106           puts ("insufficient alignment in DSO destructor");
107           result = 1;
108           /* FALLTHROUGH */
109         case 'C':
110           dso_des_seen++;
111           break;
112         default:
113           printf ("unexpected character %x read from pipe", c);
114           result = 1;
115           break;
116         }
117     }
118
119   close (fds[0]);
120
121   if (des_seen != 1)
122     {
123       printf ("binary destructor run %d times instead of once\n", des_seen);
124       result = 1;
125     }
126
127   if (dso_des_seen != 1)
128     {
129       printf ("DSO destructor run %d times instead of once\n", dso_des_seen);
130       result = 1;
131     }
132
133   int status;
134   pid_t termpid;
135   termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
136   if (termpid == -1)
137     {
138       printf ("waitpid failed: %m\n");
139       result = 1;
140     }
141   else if (termpid != pid)
142     {
143       printf ("waitpid returned %ld != %ld\n",
144               (long int) termpid, (long int) pid);
145       result = 1;
146     }
147   else if (!WIFEXITED (status) || WEXITSTATUS (status))
148     {
149       puts ("child hasn't exited with exit status 0");
150       result = 1;
151     }
152
153   return result;
154 }
155
156 #define TEST_FUNCTION do_test ()
157 #include "../test-skeleton.c"