]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 2005-2019 Free Software Foundation, Inc. |
be184b1d UD |
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 | |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
be184b1d UD |
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 | ||
36fe25fd | 155 | #include <support/test-driver.c> |