1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <dlfcn.h>
17
18 #include "dso_easy_symver.h"
19 #include "dso_hard_symver.h"
20 #include "dso_no_symver.h"
21 #include "dso_symver.h"
22
23 extern void *__dlsym_time64(void *__restrict, const char *__restrict);
24
25 /**
26 * @tc.name : dlsym_no_symver_0100
27 * @tc.desc : invoke a symbol programmatically
28 * @tc.level : Level 0
29 */
dlsym_no_symver_0100(void)30 void dlsym_no_symver_0100(void)
31 {
32 symver_log("start");
33
34 void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
35 if (!handle) {
36 symver_error("%s", dlerror());
37 return;
38 }
39
40 // Clear any existing error
41 dlerror();
42
43 functype func = (functype)dlsym(handle, dso_no_symver_symbol);
44 const char *error = dlerror();
45 if (error != NULL) {
46 symver_error("%s", error);
47 return;
48 }
49
50 const char *result = func();
51 symver_streq(result, dso_no_symver_symbol);
52
53 dlclose(handle);
54
55 symver_log("end");
56 }
57
58 /**
59 * @tc.name : dlsym_no_symver_0200
60 * @tc.desc : invoke an invalid symbol programmatically
61 * @tc.level : Level 2
62 */
dlsym_no_symver_0200(void)63 void dlsym_no_symver_0200(void)
64 {
65 symver_log("start");
66
67 void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
68 if (!handle) {
69 symver_error("%s", dlerror());
70 return;
71 }
72
73 // Clear any existing error
74 dlerror();
75
76 functype func = (functype)dlsym(handle, dso_symbol_invalid);
77 const char *error = dlerror();
78 if (error == NULL) {
79 symver_error();
80 return;
81 }
82
83 symver_log("error = %s", error);
84
85 dlclose(handle);
86
87 symver_log("end");
88 }
89
90 /**
91 * @tc.name : dlsym_easy_symver_0100
92 * @tc.desc : invoke a symbol directly after specifying a non-default version
93 * @tc.level : Level 0
94 */
dlsym_easy_symver_0100(void)95 void dlsym_easy_symver_0100(void)
96 {
97 symver_log("start");
98
99 __asm__(".symver dso_easy_symver, dso_easy_symver@OLD");
100 const char *result = dso_easy_symver();
101 symver_streq(result, dso_easy_symver_symbol_old);
102
103 symver_log("end");
104 }
105
106 /**
107 * @tc.name : dlsym_easy_symver_0200
108 * @tc.desc : invoke a symbol with versions programmatically
109 * @tc.level : Level 1
110 */
dlsym_easy_symver_0200(void)111 void dlsym_easy_symver_0200(void)
112 {
113 symver_log("start");
114
115 void *handle = dlopen(dso_easy_symver_name, RTLD_LAZY);
116 if (!handle) {
117 symver_error("%s", dlerror());
118 return;
119 }
120
121 // Clear any existing error
122 dlerror();
123
124 functype func = (functype)dlsym(handle, dso_easy_symver_symbol);
125 const char *error = dlerror();
126 if (error != NULL) {
127 symver_error("%s", error);
128 return;
129 }
130
131 const char *result = func();
132 symver_streq(result, dso_easy_symver_symbol_stable);
133
134 dlclose(handle);
135
136 symver_log("end");
137 }
138
139 /**
140 * @tc.name : dlsym_easy_symver_0300
141 * @tc.desc : invoke an invalid symbol programmatically
142 * @tc.level : Level 2
143 */
dlsym_easy_symver_0300(void)144 void dlsym_easy_symver_0300(void)
145 {
146 symver_log("start");
147
148 void *handle = dlopen(dso_easy_symver_name, RTLD_LAZY);
149 if (!handle) {
150 symver_error("%s", dlerror());
151 return;
152 }
153
154 // Clear any existing error
155 dlerror();
156
157 functype func = (functype)dlsym(handle, dso_symbol_invalid);
158 const char *error = dlerror();
159 if (error == NULL) {
160 symver_error();
161 return;
162 }
163
164 symver_log("error = %s", error);
165
166 dlclose(handle);
167
168 symver_log("end");
169 }
170
171 /**
172 * @tc.name : dlsym_hard_symver_0100
173 * @tc.desc : invoke a symbol directly after specifying a non-default version
174 * @tc.level : Level 0
175 */
dlsym_hard_symver_0100(void)176 void dlsym_hard_symver_0100(void)
177 {
178 symver_log("start");
179
180 __asm__(".symver dso_hard_symver_ld, dso_hard_symver_ld@OLD");
181 const char *result = dso_hard_symver_ld();
182 symver_streq(result, dso_hard_symver_ld_symbol_old);
183
184 symver_log("end");
185 }
186
187 /**
188 * @tc.name : dlsym_hard_symver_0200
189 * @tc.desc : invoke a symbol with versions programmatically
190 * @tc.level : Level 1
191 */
dlsym_hard_symver_0200(void)192 void dlsym_hard_symver_0200(void)
193 {
194 symver_log("start");
195
196 void *handle = dlopen(dso_hard_symver_name, RTLD_LAZY);
197 if (!handle) {
198 symver_error("%s", dlerror());
199 return;
200 }
201
202 // Clear any existing error
203 dlerror();
204
205 functype func = (functype)dlsym(handle, dso_hard_symver_if_symbol);
206 const char *error = dlerror();
207 if (error != NULL) {
208 symver_error("%s", error);
209 return;
210 }
211
212 const char *result = func();
213 symver_streq(result, dso_hard_symver_if_symbol_stable);
214
215 dlclose(handle);
216
217 symver_log("end");
218 }
219
220 /**
221 * @tc.name : dlsym_hard_symver_0300
222 * @tc.desc : invoke an invalid symbol programmatically
223 * @tc.level : Level 2
224 */
dlsym_hard_symver_0300(void)225 void dlsym_hard_symver_0300(void)
226 {
227 symver_log("start");
228
229 void *handle = dlopen(dso_hard_symver_name, RTLD_LAZY);
230 if (!handle) {
231 symver_error("%s", dlerror());
232 return;
233 }
234
235 // Clear any existing error
236 dlerror();
237
238 functype func = (functype)dlsym(handle, dso_symbol_invalid);
239 const char *error = dlerror();
240 if (error == NULL) {
241 symver_error();
242 return;
243 }
244
245 symver_log("error = %s", error);
246
247 dlclose(handle);
248
249 symver_log("end");
250 }
251
252 /**
253 * @tc.name : dlsym_time64_no_symver_0100
254 * @tc.desc : invoke a symbol programmatically
255 * @tc.level : Level 0
256 */
dlsym_time64_no_symver_0100(void)257 void dlsym_time64_no_symver_0100(void)
258 {
259 symver_log("start");
260
261 void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
262 if (!handle) {
263 symver_error("%s", dlerror());
264 return;
265 }
266
267 // Clear any existing error
268 dlerror();
269
270 functype func = (functype)__dlsym_time64(handle, dso_no_symver_symbol);
271 const char *error = dlerror();
272 if (error != NULL) {
273 symver_error("%s", error);
274 return;
275 }
276
277 const char *result = func();
278 symver_streq(result, dso_no_symver_symbol);
279
280 dlclose(handle);
281
282 symver_log("end");
283 }
284
main(int argc,char * argv[])285 int main(int argc, char *argv[])
286 {
287 symver_log("start");
288
289 dlsym_no_symver_0100();
290 dlsym_no_symver_0200();
291 dlsym_time64_no_symver_0100();
292
293 dlsym_easy_symver_0100();
294 dlsym_easy_symver_0200();
295 dlsym_easy_symver_0300();
296
297 dlsym_hard_symver_0100();
298 dlsym_hard_symver_0200();
299 dlsym_hard_symver_0300();
300
301 symver_log("t_status = %d", t_status);
302 symver_log("end");
303
304 return t_status;
305 }
306