1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci#include <dlfcn.h>
17570af302Sopenharmony_ci
18570af302Sopenharmony_ci#include "dso_easy_symver.h"
19570af302Sopenharmony_ci#include "dso_hard_symver.h"
20570af302Sopenharmony_ci#include "dso_no_symver.h"
21570af302Sopenharmony_ci#include "dso_symver.h"
22570af302Sopenharmony_ci
23570af302Sopenharmony_ciextern void  *__dlsym_time64(void *__restrict, const char *__restrict);
24570af302Sopenharmony_ci
25570af302Sopenharmony_ci/**
26570af302Sopenharmony_ci * @tc.name      : dlsym_no_symver_0100
27570af302Sopenharmony_ci * @tc.desc      : invoke a symbol programmatically
28570af302Sopenharmony_ci * @tc.level     : Level 0
29570af302Sopenharmony_ci */
30570af302Sopenharmony_civoid dlsym_no_symver_0100(void)
31570af302Sopenharmony_ci{
32570af302Sopenharmony_ci    symver_log("start");
33570af302Sopenharmony_ci
34570af302Sopenharmony_ci    void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
35570af302Sopenharmony_ci    if (!handle) {
36570af302Sopenharmony_ci        symver_error("%s", dlerror());
37570af302Sopenharmony_ci        return;
38570af302Sopenharmony_ci    }
39570af302Sopenharmony_ci
40570af302Sopenharmony_ci    // Clear any existing error
41570af302Sopenharmony_ci    dlerror();
42570af302Sopenharmony_ci
43570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_no_symver_symbol);
44570af302Sopenharmony_ci    const char *error = dlerror();
45570af302Sopenharmony_ci    if (error != NULL) {
46570af302Sopenharmony_ci        symver_error("%s", error);
47570af302Sopenharmony_ci        return;
48570af302Sopenharmony_ci    }
49570af302Sopenharmony_ci
50570af302Sopenharmony_ci    const char *result = func();
51570af302Sopenharmony_ci    symver_streq(result, dso_no_symver_symbol);
52570af302Sopenharmony_ci
53570af302Sopenharmony_ci    dlclose(handle);
54570af302Sopenharmony_ci
55570af302Sopenharmony_ci    symver_log("end");
56570af302Sopenharmony_ci}
57570af302Sopenharmony_ci
58570af302Sopenharmony_ci/**
59570af302Sopenharmony_ci * @tc.name      : dlsym_no_symver_0200
60570af302Sopenharmony_ci * @tc.desc      : invoke an invalid symbol programmatically
61570af302Sopenharmony_ci * @tc.level     : Level 2
62570af302Sopenharmony_ci */
63570af302Sopenharmony_civoid dlsym_no_symver_0200(void)
64570af302Sopenharmony_ci{
65570af302Sopenharmony_ci    symver_log("start");
66570af302Sopenharmony_ci
67570af302Sopenharmony_ci    void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
68570af302Sopenharmony_ci    if (!handle) {
69570af302Sopenharmony_ci        symver_error("%s", dlerror());
70570af302Sopenharmony_ci        return;
71570af302Sopenharmony_ci    }
72570af302Sopenharmony_ci
73570af302Sopenharmony_ci    // Clear any existing error
74570af302Sopenharmony_ci    dlerror();
75570af302Sopenharmony_ci
76570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_symbol_invalid);
77570af302Sopenharmony_ci    const char *error = dlerror();
78570af302Sopenharmony_ci    if (error == NULL) {
79570af302Sopenharmony_ci        symver_error();
80570af302Sopenharmony_ci        return;
81570af302Sopenharmony_ci    }
82570af302Sopenharmony_ci
83570af302Sopenharmony_ci    symver_log("error = %s", error);
84570af302Sopenharmony_ci
85570af302Sopenharmony_ci    dlclose(handle);
86570af302Sopenharmony_ci
87570af302Sopenharmony_ci    symver_log("end");
88570af302Sopenharmony_ci}
89570af302Sopenharmony_ci
90570af302Sopenharmony_ci/**
91570af302Sopenharmony_ci * @tc.name      : dlsym_easy_symver_0100
92570af302Sopenharmony_ci * @tc.desc      : invoke a symbol directly after specifying a non-default version
93570af302Sopenharmony_ci * @tc.level     : Level 0
94570af302Sopenharmony_ci */
95570af302Sopenharmony_civoid dlsym_easy_symver_0100(void)
96570af302Sopenharmony_ci{
97570af302Sopenharmony_ci    symver_log("start");
98570af302Sopenharmony_ci
99570af302Sopenharmony_ci    __asm__(".symver dso_easy_symver, dso_easy_symver@OLD");
100570af302Sopenharmony_ci    const char *result = dso_easy_symver();
101570af302Sopenharmony_ci    symver_streq(result, dso_easy_symver_symbol_old);
102570af302Sopenharmony_ci
103570af302Sopenharmony_ci    symver_log("end");
104570af302Sopenharmony_ci}
105570af302Sopenharmony_ci
106570af302Sopenharmony_ci/**
107570af302Sopenharmony_ci * @tc.name      : dlsym_easy_symver_0200
108570af302Sopenharmony_ci * @tc.desc      : invoke a symbol with versions programmatically
109570af302Sopenharmony_ci * @tc.level     : Level 1
110570af302Sopenharmony_ci */
111570af302Sopenharmony_civoid dlsym_easy_symver_0200(void)
112570af302Sopenharmony_ci{
113570af302Sopenharmony_ci    symver_log("start");
114570af302Sopenharmony_ci
115570af302Sopenharmony_ci    void *handle = dlopen(dso_easy_symver_name, RTLD_LAZY);
116570af302Sopenharmony_ci    if (!handle) {
117570af302Sopenharmony_ci        symver_error("%s", dlerror());
118570af302Sopenharmony_ci        return;
119570af302Sopenharmony_ci    }
120570af302Sopenharmony_ci
121570af302Sopenharmony_ci    // Clear any existing error
122570af302Sopenharmony_ci    dlerror();
123570af302Sopenharmony_ci
124570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_easy_symver_symbol);
125570af302Sopenharmony_ci    const char *error = dlerror();
126570af302Sopenharmony_ci    if (error != NULL) {
127570af302Sopenharmony_ci        symver_error("%s", error);
128570af302Sopenharmony_ci        return;
129570af302Sopenharmony_ci    }
130570af302Sopenharmony_ci
131570af302Sopenharmony_ci    const char *result = func();
132570af302Sopenharmony_ci    symver_streq(result, dso_easy_symver_symbol_stable);
133570af302Sopenharmony_ci
134570af302Sopenharmony_ci    dlclose(handle);
135570af302Sopenharmony_ci
136570af302Sopenharmony_ci    symver_log("end");
137570af302Sopenharmony_ci}
138570af302Sopenharmony_ci
139570af302Sopenharmony_ci/**
140570af302Sopenharmony_ci * @tc.name      : dlsym_easy_symver_0300
141570af302Sopenharmony_ci * @tc.desc      : invoke an invalid symbol programmatically
142570af302Sopenharmony_ci * @tc.level     : Level 2
143570af302Sopenharmony_ci */
144570af302Sopenharmony_civoid dlsym_easy_symver_0300(void)
145570af302Sopenharmony_ci{
146570af302Sopenharmony_ci    symver_log("start");
147570af302Sopenharmony_ci
148570af302Sopenharmony_ci    void *handle = dlopen(dso_easy_symver_name, RTLD_LAZY);
149570af302Sopenharmony_ci    if (!handle) {
150570af302Sopenharmony_ci        symver_error("%s", dlerror());
151570af302Sopenharmony_ci        return;
152570af302Sopenharmony_ci    }
153570af302Sopenharmony_ci
154570af302Sopenharmony_ci    // Clear any existing error
155570af302Sopenharmony_ci    dlerror();
156570af302Sopenharmony_ci
157570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_symbol_invalid);
158570af302Sopenharmony_ci    const char *error = dlerror();
159570af302Sopenharmony_ci    if (error == NULL) {
160570af302Sopenharmony_ci        symver_error();
161570af302Sopenharmony_ci        return;
162570af302Sopenharmony_ci    }
163570af302Sopenharmony_ci
164570af302Sopenharmony_ci    symver_log("error = %s", error);
165570af302Sopenharmony_ci
166570af302Sopenharmony_ci    dlclose(handle);
167570af302Sopenharmony_ci
168570af302Sopenharmony_ci    symver_log("end");
169570af302Sopenharmony_ci}
170570af302Sopenharmony_ci
171570af302Sopenharmony_ci/**
172570af302Sopenharmony_ci * @tc.name      : dlsym_hard_symver_0100
173570af302Sopenharmony_ci * @tc.desc      : invoke a symbol directly after specifying a non-default version
174570af302Sopenharmony_ci * @tc.level     : Level 0
175570af302Sopenharmony_ci */
176570af302Sopenharmony_civoid dlsym_hard_symver_0100(void)
177570af302Sopenharmony_ci{
178570af302Sopenharmony_ci    symver_log("start");
179570af302Sopenharmony_ci
180570af302Sopenharmony_ci    __asm__(".symver dso_hard_symver_ld, dso_hard_symver_ld@OLD");
181570af302Sopenharmony_ci    const char *result = dso_hard_symver_ld();
182570af302Sopenharmony_ci    symver_streq(result, dso_hard_symver_ld_symbol_old);
183570af302Sopenharmony_ci
184570af302Sopenharmony_ci    symver_log("end");
185570af302Sopenharmony_ci}
186570af302Sopenharmony_ci
187570af302Sopenharmony_ci/**
188570af302Sopenharmony_ci * @tc.name      : dlsym_hard_symver_0200
189570af302Sopenharmony_ci * @tc.desc      : invoke a symbol with versions programmatically
190570af302Sopenharmony_ci * @tc.level     : Level 1
191570af302Sopenharmony_ci */
192570af302Sopenharmony_civoid dlsym_hard_symver_0200(void)
193570af302Sopenharmony_ci{
194570af302Sopenharmony_ci    symver_log("start");
195570af302Sopenharmony_ci
196570af302Sopenharmony_ci    void *handle = dlopen(dso_hard_symver_name, RTLD_LAZY);
197570af302Sopenharmony_ci    if (!handle) {
198570af302Sopenharmony_ci        symver_error("%s", dlerror());
199570af302Sopenharmony_ci        return;
200570af302Sopenharmony_ci    }
201570af302Sopenharmony_ci
202570af302Sopenharmony_ci    // Clear any existing error
203570af302Sopenharmony_ci    dlerror();
204570af302Sopenharmony_ci
205570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_hard_symver_if_symbol);
206570af302Sopenharmony_ci    const char *error = dlerror();
207570af302Sopenharmony_ci    if (error != NULL) {
208570af302Sopenharmony_ci        symver_error("%s", error);
209570af302Sopenharmony_ci        return;
210570af302Sopenharmony_ci    }
211570af302Sopenharmony_ci
212570af302Sopenharmony_ci    const char *result = func();
213570af302Sopenharmony_ci    symver_streq(result, dso_hard_symver_if_symbol_stable);
214570af302Sopenharmony_ci
215570af302Sopenharmony_ci    dlclose(handle);
216570af302Sopenharmony_ci
217570af302Sopenharmony_ci    symver_log("end");
218570af302Sopenharmony_ci}
219570af302Sopenharmony_ci
220570af302Sopenharmony_ci/**
221570af302Sopenharmony_ci * @tc.name      : dlsym_hard_symver_0300
222570af302Sopenharmony_ci * @tc.desc      : invoke an invalid symbol programmatically
223570af302Sopenharmony_ci * @tc.level     : Level 2
224570af302Sopenharmony_ci */
225570af302Sopenharmony_civoid dlsym_hard_symver_0300(void)
226570af302Sopenharmony_ci{
227570af302Sopenharmony_ci    symver_log("start");
228570af302Sopenharmony_ci
229570af302Sopenharmony_ci    void *handle = dlopen(dso_hard_symver_name, RTLD_LAZY);
230570af302Sopenharmony_ci    if (!handle) {
231570af302Sopenharmony_ci        symver_error("%s", dlerror());
232570af302Sopenharmony_ci        return;
233570af302Sopenharmony_ci    }
234570af302Sopenharmony_ci
235570af302Sopenharmony_ci    // Clear any existing error
236570af302Sopenharmony_ci    dlerror();
237570af302Sopenharmony_ci
238570af302Sopenharmony_ci    functype func = (functype)dlsym(handle, dso_symbol_invalid);
239570af302Sopenharmony_ci    const char *error = dlerror();
240570af302Sopenharmony_ci    if (error == NULL) {
241570af302Sopenharmony_ci        symver_error();
242570af302Sopenharmony_ci        return;
243570af302Sopenharmony_ci    }
244570af302Sopenharmony_ci
245570af302Sopenharmony_ci    symver_log("error = %s", error);
246570af302Sopenharmony_ci
247570af302Sopenharmony_ci    dlclose(handle);
248570af302Sopenharmony_ci
249570af302Sopenharmony_ci    symver_log("end");
250570af302Sopenharmony_ci}
251570af302Sopenharmony_ci
252570af302Sopenharmony_ci/**
253570af302Sopenharmony_ci * @tc.name      : dlsym_time64_no_symver_0100
254570af302Sopenharmony_ci * @tc.desc      : invoke a symbol programmatically
255570af302Sopenharmony_ci * @tc.level     : Level 0
256570af302Sopenharmony_ci */
257570af302Sopenharmony_civoid dlsym_time64_no_symver_0100(void)
258570af302Sopenharmony_ci{
259570af302Sopenharmony_ci    symver_log("start");
260570af302Sopenharmony_ci
261570af302Sopenharmony_ci    void *handle = dlopen(dso_no_symver_name, RTLD_LAZY);
262570af302Sopenharmony_ci    if (!handle) {
263570af302Sopenharmony_ci        symver_error("%s", dlerror());
264570af302Sopenharmony_ci        return;
265570af302Sopenharmony_ci    }
266570af302Sopenharmony_ci
267570af302Sopenharmony_ci    // Clear any existing error
268570af302Sopenharmony_ci    dlerror();
269570af302Sopenharmony_ci
270570af302Sopenharmony_ci    functype func = (functype)__dlsym_time64(handle, dso_no_symver_symbol);
271570af302Sopenharmony_ci    const char *error = dlerror();
272570af302Sopenharmony_ci    if (error != NULL) {
273570af302Sopenharmony_ci        symver_error("%s", error);
274570af302Sopenharmony_ci        return;
275570af302Sopenharmony_ci    }
276570af302Sopenharmony_ci
277570af302Sopenharmony_ci    const char *result = func();
278570af302Sopenharmony_ci    symver_streq(result, dso_no_symver_symbol);
279570af302Sopenharmony_ci
280570af302Sopenharmony_ci    dlclose(handle);
281570af302Sopenharmony_ci
282570af302Sopenharmony_ci    symver_log("end");
283570af302Sopenharmony_ci}
284570af302Sopenharmony_ci
285570af302Sopenharmony_ciint main(int argc, char *argv[])
286570af302Sopenharmony_ci{
287570af302Sopenharmony_ci    symver_log("start");
288570af302Sopenharmony_ci
289570af302Sopenharmony_ci    dlsym_no_symver_0100();
290570af302Sopenharmony_ci    dlsym_no_symver_0200();
291570af302Sopenharmony_ci    dlsym_time64_no_symver_0100();
292570af302Sopenharmony_ci
293570af302Sopenharmony_ci    dlsym_easy_symver_0100();
294570af302Sopenharmony_ci    dlsym_easy_symver_0200();
295570af302Sopenharmony_ci    dlsym_easy_symver_0300();
296570af302Sopenharmony_ci
297570af302Sopenharmony_ci    dlsym_hard_symver_0100();
298570af302Sopenharmony_ci    dlsym_hard_symver_0200();
299570af302Sopenharmony_ci    dlsym_hard_symver_0300();
300570af302Sopenharmony_ci
301570af302Sopenharmony_ci    symver_log("t_status = %d", t_status);
302570af302Sopenharmony_ci    symver_log("end");
303570af302Sopenharmony_ci
304570af302Sopenharmony_ci    return t_status;
305570af302Sopenharmony_ci}
306