]>
Commit | Line | Data |
---|---|---|
bfff8b1b | 1 | /* Copyright (C) 2000-2017 Free Software Foundation, Inc. |
eec8ef5a UD |
2 | This file is part of the GNU C Library. |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
eec8ef5a UD |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
eec8ef5a | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
eec8ef5a | 17 | |
ef4ad06f L |
18 | /* This file must be compiled as PIE to avoid copy relocation when |
19 | accessing protected symbols defined in shared libaries since copy | |
20 | relocation doesn't work with protected symbols and linker in | |
21 | binutils 2.26 enforces this rule. */ | |
22 | ||
eec8ef5a UD |
23 | #include <stdio.h> |
24 | #include <stdlib.h> | |
25 | #include <string.h> | |
26 | ||
715ed1e9 AJ |
27 | #include "vismod.h" |
28 | ||
741845cb AJ |
29 | /* Prototype for our test function. */ |
30 | extern int do_test (void); | |
31 | ||
32 | #define TEST_FUNCTION do_test () | |
33 | ||
34 | /* This defines the `main' function and some more. */ | |
35 | #include <test-skeleton.c> | |
36 | ||
eec8ef5a UD |
37 | |
38 | /* Prototypes for local functions. */ | |
39 | extern int protlocal (void); | |
40 | ||
41 | const char *protvarlocal = __FILE__; | |
42 | extern const char *protvarinmod; | |
43 | extern const char *protvaritcpt; | |
44 | ||
45 | int | |
741845cb | 46 | do_test (void) |
eec8ef5a UD |
47 | { |
48 | int res = 0; | |
49 | int val; | |
50 | ||
51 | /* First test: check whether .protected is handled correctly by the | |
52 | assembler/linker. The uses of `protlocal' in the DSOs and in the | |
53 | main program should all be resolved with the local definitions. */ | |
54 | val = protlocal () + calllocal1 () + calllocal2 (); | |
55 | if (val != 0x155) | |
56 | { | |
57 | puts ("\ | |
58 | The handling of `.protected' seems to be implemented incorrectly: giving up"); | |
59 | abort (); | |
60 | } | |
61 | puts ("`.protected' seems to be handled correctly, good!"); | |
62 | ||
63 | /* Function pointers: for functions which are marked local and for | |
64 | which definitions are available all function pointers must be | |
65 | distinct. */ | |
66 | if (protlocal == getlocal1 ()) | |
67 | { | |
68 | puts ("`protlocal' in main and mod1 have same address"); | |
69 | res = 1; | |
70 | } | |
71 | if (protlocal == getlocal2 ()) | |
72 | { | |
73 | puts ("`protlocal' in main and mod2 have same address"); | |
74 | res = 1; | |
75 | } | |
76 | if (getlocal1 () == getlocal2 ()) | |
77 | { | |
78 | puts ("`protlocal' in mod1 and mod2 have same address"); | |
79 | res = 1; | |
80 | } | |
81 | if (getlocal1 () () + getlocal2 () () != 0x44) | |
82 | { | |
83 | puts ("pointers to `protlocal' in mod1 or mod2 incorrect"); | |
84 | res = 1; | |
85 | } | |
86 | ||
87 | /* Next test. This is similar to the last one but the function we | |
88 | are calling is not defined in the main object. This means that | |
89 | the invocation in the main object uses the definition in the | |
90 | first DSO. */ | |
91 | if (protinmod != getinmod1 ()) | |
92 | { | |
5972c58b RM |
93 | printf ("&protinmod in main (%p) != &protinmod in mod1 (%p)\n", |
94 | protinmod, getinmod1 ()); | |
eec8ef5a UD |
95 | res = 1; |
96 | } | |
97 | if (protinmod == getinmod2 ()) | |
98 | { | |
99 | puts ("`protinmod' in main and mod2 have same address"); | |
100 | res = 1; | |
101 | } | |
102 | if (getinmod1 () == getinmod2 ()) | |
103 | { | |
104 | puts ("`protinmod' in mod1 and mod2 have same address"); | |
105 | res = 1; | |
106 | } | |
107 | if (protinmod () + getinmod1 () () + getinmod2 () () != 0x4800) | |
108 | { | |
109 | puts ("pointers to `protinmod' in mod1 or mod2 incorrect"); | |
110 | res = 1; | |
111 | } | |
112 | val = protinmod () + callinmod1 () + callinmod2 (); | |
113 | if (val != 0x15800) | |
114 | { | |
115 | printf ("calling of `protinmod' leads to wrong result (%#x)\n", val); | |
116 | res = 1; | |
117 | } | |
118 | ||
119 | /* A very similar text. Same setup for the main object and the modules | |
120 | but this time we have another definition in a preloaded module. This | |
121 | one intercepts the references from the main object. */ | |
122 | if (protitcpt != getitcpt3 ()) | |
123 | { | |
5972c58b RM |
124 | printf ("&protitcpt in main (%p) != &protitcpt in mod3 (%p)\n", |
125 | &protitcpt, getitcpt3 ()); | |
eec8ef5a UD |
126 | res = 1; |
127 | } | |
128 | if (protitcpt == getitcpt1 ()) | |
129 | { | |
130 | puts ("`protitcpt' in main and mod1 have same address"); | |
131 | res = 1; | |
132 | } | |
133 | if (protitcpt == getitcpt2 ()) | |
134 | { | |
135 | puts ("`protitcpt' in main and mod2 have same address"); | |
136 | res = 1; | |
137 | } | |
138 | if (getitcpt1 () == getitcpt2 ()) | |
139 | { | |
140 | puts ("`protitcpt' in mod1 and mod2 have same address"); | |
141 | res = 1; | |
142 | } | |
143 | val = protitcpt () + getitcpt1 () () + getitcpt2 () () + getitcpt3 () (); | |
144 | if (val != 0x8440000) | |
145 | { | |
146 | printf ("\ | |
147 | pointers to `protitcpt' in mod1 or mod2 or mod3 incorrect (%#x)\n", val); | |
148 | res = 1; | |
149 | } | |
150 | val = protitcpt () + callitcpt1 () + callitcpt2 () + callitcpt3 (); | |
151 | if (val != 0x19540000) | |
152 | { | |
153 | printf ("calling of `protitcpt' leads to wrong result (%#x)\n", val); | |
154 | res = 1; | |
155 | } | |
156 | ||
157 | /* Now look at variables. First a variable which is available | |
158 | everywhere. We must have three different addresses. */ | |
5972c58b | 159 | if (&protvarlocal == getvarlocal1 ()) |
eec8ef5a UD |
160 | { |
161 | puts ("`protvarlocal' in main and mod1 have same address"); | |
162 | res = 1; | |
163 | } | |
5972c58b | 164 | if (&protvarlocal == getvarlocal2 ()) |
eec8ef5a UD |
165 | { |
166 | puts ("`protvarlocal' in main and mod2 have same address"); | |
167 | res = 1; | |
168 | } | |
169 | if (getvarlocal1 () == getvarlocal2 ()) | |
170 | { | |
171 | puts ("`protvarlocal' in mod1 and mod2 have same address"); | |
172 | res = 1; | |
173 | } | |
174 | if (strcmp (protvarlocal, __FILE__) != 0) | |
175 | { | |
176 | puts ("`protvarlocal in main has wrong value"); | |
177 | res = 1; | |
178 | } | |
5972c58b | 179 | if (strcmp (*getvarlocal1 (), "vismod1.c") != 0) |
eec8ef5a UD |
180 | { |
181 | puts ("`getvarlocal1' returns wrong value"); | |
182 | res = 1; | |
183 | } | |
5972c58b | 184 | if (strcmp (*getvarlocal2 (), "vismod2.c") != 0) |
eec8ef5a UD |
185 | { |
186 | puts ("`getvarlocal2' returns wrong value"); | |
187 | res = 1; | |
188 | } | |
189 | ||
190 | /* Now the case where there is no local definition. */ | |
5972c58b | 191 | if (&protvarinmod != getvarinmod1 ()) |
eec8ef5a | 192 | { |
5972c58b RM |
193 | printf ("&protvarinmod in main (%p) != &protitcpt in mod1 (%p)\n", |
194 | &protvarinmod, getvarinmod1 ()); | |
d403820a UD |
195 | // XXX Possibly enable once fixed. |
196 | // res = 1; | |
eec8ef5a | 197 | } |
5972c58b | 198 | if (&protvarinmod == getvarinmod2 ()) |
eec8ef5a UD |
199 | { |
200 | puts ("`protvarinmod' in main and mod2 have same address"); | |
201 | res = 1; | |
202 | } | |
5972c58b | 203 | if (strcmp (*getvarinmod1 (), "vismod1.c") != 0) |
eec8ef5a UD |
204 | { |
205 | puts ("`getvarinmod1' returns wrong value"); | |
206 | res = 1; | |
207 | } | |
5972c58b | 208 | if (strcmp (*getvarinmod2 (), "vismod2.c") != 0) |
eec8ef5a UD |
209 | { |
210 | puts ("`getvarinmod2' returns wrong value"); | |
211 | res = 1; | |
212 | } | |
213 | ||
214 | /* And a test where a variable definition is intercepted. */ | |
5972c58b | 215 | if (&protvaritcpt == getvaritcpt1 ()) |
eec8ef5a UD |
216 | { |
217 | puts ("`protvaritcpt' in main and mod1 have same address"); | |
218 | res = 1; | |
219 | } | |
5972c58b | 220 | if (&protvaritcpt == getvaritcpt2 ()) |
eec8ef5a UD |
221 | { |
222 | puts ("`protvaritcpt' in main and mod2 have same address"); | |
223 | res = 1; | |
224 | } | |
5972c58b | 225 | if (&protvaritcpt != getvaritcpt3 ()) |
eec8ef5a | 226 | { |
5972c58b RM |
227 | printf ("&protvaritcpt in main (%p) != &protvaritcpt in mod3 (%p)\n", |
228 | &protvaritcpt, getvaritcpt3 ()); | |
d403820a UD |
229 | // XXX Possibly enable once fixed. |
230 | // res = 1; | |
eec8ef5a UD |
231 | } |
232 | if (getvaritcpt1 () == getvaritcpt2 ()) | |
233 | { | |
234 | puts ("`protvaritcpt' in mod1 and mod2 have same address"); | |
235 | res = 1; | |
236 | } | |
237 | if (strcmp (protvaritcpt, "vismod3.c") != 0) | |
238 | { | |
239 | puts ("`protvaritcpt in main has wrong value"); | |
240 | res = 1; | |
241 | } | |
5972c58b | 242 | if (strcmp (*getvaritcpt1 (), "vismod1.c") != 0) |
eec8ef5a UD |
243 | { |
244 | puts ("`getvaritcpt1' returns wrong value"); | |
245 | res = 1; | |
246 | } | |
5972c58b | 247 | if (strcmp (*getvaritcpt2 (), "vismod2.c") != 0) |
eec8ef5a UD |
248 | { |
249 | puts ("`getvaritcpt2' returns wrong value"); | |
250 | res = 1; | |
251 | } | |
252 | ||
253 | return res; | |
254 | } | |
255 | ||
256 | ||
257 | int | |
258 | protlocal (void) | |
259 | { | |
260 | return 0x1; | |
261 | } |