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