1570af302Sopenharmony_ci#include <dlfcn.h> 2570af302Sopenharmony_ci#include <stdio.h> 3570af302Sopenharmony_ci#include <string.h> 4570af302Sopenharmony_ci#include "test.h" 5570af302Sopenharmony_ci 6570af302Sopenharmony_ci#define SO_HAS_DEPENDENCES "libdlopen_so_dep_dlopen_ns_dso.so" 7570af302Sopenharmony_ciconst char* dllName = "libdlopen_ns_dso.so"; 8570af302Sopenharmony_ciconst char* dllName2 = "libdlopen_dso.so"; 9570af302Sopenharmony_ciconst char* errPath_ns = "/src/common"; 10570af302Sopenharmony_ciconst char* ndk_so = "libdlopen_ns_dso_ndk.so"; 11570af302Sopenharmony_ciconst char* system_so = "libdlopen_ns_dso_sys.so"; 12570af302Sopenharmony_citypedef void*(*CALL_DLOPEN_PTR)(const char *); 13570af302Sopenharmony_ci 14570af302Sopenharmony_ci// Test whether it is ok for main to dlopen ndk so. 15570af302Sopenharmony_civoid main_dlopen_ndk_so() 16570af302Sopenharmony_ci{ 17570af302Sopenharmony_ci void *handle = dlopen(ndk_so, RTLD_NOW); 18570af302Sopenharmony_ci if (!handle) 19570af302Sopenharmony_ci t_error("main dlopen ndk so %s failed: %s\n", ndk_so, dlerror()); 20570af302Sopenharmony_ci if (dlclose(handle)) 21570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", ndk_so, dlerror()); 22570af302Sopenharmony_ci} 23570af302Sopenharmony_ci 24570af302Sopenharmony_ci// Test whether it is ok for system so to dlopen ndk so. 25570af302Sopenharmony_civoid system_so_dlopen_ndk_so() 26570af302Sopenharmony_ci{ 27570af302Sopenharmony_ci void *handle = dlopen(system_so, RTLD_NOW); 28570af302Sopenharmony_ci if (!handle) { 29570af302Sopenharmony_ci t_error("dlopen %s failed : %s \n", system_so, dlerror()); 30570af302Sopenharmony_ci } 31570af302Sopenharmony_ci CALL_DLOPEN_PTR call_dlopen = dlsym(handle, "call_dlopen"); 32570af302Sopenharmony_ci if (!call_dlopen) { 33570af302Sopenharmony_ci t_error("dlsym %s failed : %s \n", "call_dlopen", dlerror()); 34570af302Sopenharmony_ci } 35570af302Sopenharmony_ci void *res = call_dlopen(ndk_so); 36570af302Sopenharmony_ci if (!res) { 37570af302Sopenharmony_ci t_error("default ns so(%s) can't dlopen ndk so(%s)", system_so, ndk_so); 38570af302Sopenharmony_ci } 39570af302Sopenharmony_ci} 40570af302Sopenharmony_ci 41570af302Sopenharmony_ci// Test whether it is ok for ndk so to dlopen system so. 42570af302Sopenharmony_civoid ndk_so_dlopen_default_ns_so() 43570af302Sopenharmony_ci{ 44570af302Sopenharmony_ci Dl_namespace dlns; 45570af302Sopenharmony_ci dlns_init(&dlns, "ndk"); 46570af302Sopenharmony_ci void *handle = dlopen_ns(&dlns, ndk_so, RTLD_NOW); 47570af302Sopenharmony_ci if (!handle) { 48570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, so=%s) failed : %s \n", "ndk", ndk_so, dlerror()); 49570af302Sopenharmony_ci } 50570af302Sopenharmony_ci CALL_DLOPEN_PTR call_dlopen = dlsym(handle, "call_dlopen"); 51570af302Sopenharmony_ci if (!call_dlopen) { 52570af302Sopenharmony_ci t_error("dlsym %s failed : %s \n", "call_dlopen", dlerror()); 53570af302Sopenharmony_ci } 54570af302Sopenharmony_ci void *res = call_dlopen(system_so); 55570af302Sopenharmony_ci if (!res) { 56570af302Sopenharmony_ci t_error("ndk so(%s) can't dlopen system so(%s)", ndk_so, system_so); 57570af302Sopenharmony_ci } 58570af302Sopenharmony_ci} 59570af302Sopenharmony_ci 60570af302Sopenharmony_ci// Test whether dlopen same so twice by same ns to get same handle. 61570af302Sopenharmony_civoid dlopen_same_so_twice_by_same_ns(char * dllPath_ns) 62570af302Sopenharmony_ci{ 63570af302Sopenharmony_ci Dl_namespace dlns1; 64570af302Sopenharmony_ci dlns_init(&dlns1, "ns_for_dlopen_same_so_twice_by_same_ns"); 65570af302Sopenharmony_ci dlns_create(&dlns1, dllPath_ns); 66570af302Sopenharmony_ci 67570af302Sopenharmony_ci void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW); 68570af302Sopenharmony_ci if(!handle1) 69570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 70570af302Sopenharmony_ci 71570af302Sopenharmony_ci void* handle2 = dlopen_ns(&dlns1, dllName, RTLD_NOW); 72570af302Sopenharmony_ci if(!handle2) 73570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 74570af302Sopenharmony_ci 75570af302Sopenharmony_ci if (handle1 != handle2) 76570af302Sopenharmony_ci t_error("dlopen same so(%s) by same ns but handle is different %s \n", dllName); 77570af302Sopenharmony_ci 78570af302Sopenharmony_ci if(dlclose(handle1)) 79570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 80570af302Sopenharmony_ci 81570af302Sopenharmony_ci if(dlclose(handle2)) 82570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 83570af302Sopenharmony_ci} 84570af302Sopenharmony_ci 85570af302Sopenharmony_ci// Test whether dlopen same so by different ns to get different handle. 86570af302Sopenharmony_civoid dlopen_same_so_by_different_ns(char * dllPath_ns) 87570af302Sopenharmony_ci{ 88570af302Sopenharmony_ci Dl_namespace dlns1; 89570af302Sopenharmony_ci dlns_init(&dlns1, "ns_for_dlopen_same_so_by_different_ns_1"); 90570af302Sopenharmony_ci dlns_create(&dlns1, dllPath_ns); 91570af302Sopenharmony_ci 92570af302Sopenharmony_ci Dl_namespace dlns2; 93570af302Sopenharmony_ci dlns_init(&dlns2, "ns_for_dlopen_same_so_by_different_ns_2"); 94570af302Sopenharmony_ci dlns_create(&dlns2, dllPath_ns); 95570af302Sopenharmony_ci 96570af302Sopenharmony_ci void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW); 97570af302Sopenharmony_ci if(!handle1) 98570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 99570af302Sopenharmony_ci 100570af302Sopenharmony_ci void* handle2 = dlopen_ns(&dlns2, dllName, RTLD_NOW); 101570af302Sopenharmony_ci if(!handle2) 102570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns2.name, dllName, dlerror()); 103570af302Sopenharmony_ci 104570af302Sopenharmony_ci if (handle1 == handle2) 105570af302Sopenharmony_ci t_error("dlopen same so(%s) by same ns but handle is different %s \n", dllName); 106570af302Sopenharmony_ci 107570af302Sopenharmony_ci if(dlclose(handle1)) 108570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 109570af302Sopenharmony_ci 110570af302Sopenharmony_ci if(dlclose(handle2)) 111570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 112570af302Sopenharmony_ci} 113570af302Sopenharmony_ci 114570af302Sopenharmony_ci// Test whether dlopen same so by inherit ns to get same handle. 115570af302Sopenharmony_civoid dlopen_same_so_by_different_inherit_ns(char * dllPath_ns) 116570af302Sopenharmony_ci{ 117570af302Sopenharmony_ci Dl_namespace dlns1; 118570af302Sopenharmony_ci dlns_init(&dlns1, "ns_for_dlopen_same_so_by_different_inherit_ns_1"); 119570af302Sopenharmony_ci dlns_create(&dlns1, dllPath_ns); 120570af302Sopenharmony_ci 121570af302Sopenharmony_ci Dl_namespace dlns2; 122570af302Sopenharmony_ci dlns_init(&dlns2, "ns_for_dlopen_same_so_by_different_inherit_ns_2"); 123570af302Sopenharmony_ci dlns_create2(&dlns2, errPath_ns, 0); 124570af302Sopenharmony_ci dlns_inherit(&dlns2, &dlns1, dllName); 125570af302Sopenharmony_ci 126570af302Sopenharmony_ci void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW); 127570af302Sopenharmony_ci if(!handle1) 128570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 129570af302Sopenharmony_ci 130570af302Sopenharmony_ci void* handle2 = dlopen_ns(&dlns2, dllName, RTLD_NOW); 131570af302Sopenharmony_ci if(!handle2) 132570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns2.name, dllName, dlerror()); 133570af302Sopenharmony_ci 134570af302Sopenharmony_ci if (handle1 != handle2) 135570af302Sopenharmony_ci t_error("dlopen same so(%s) by inherit ns but handle is different %s \n", dllName); 136570af302Sopenharmony_ci 137570af302Sopenharmony_ci if(dlclose(handle1)) 138570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 139570af302Sopenharmony_ci 140570af302Sopenharmony_ci if(dlclose(handle2)) 141570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 142570af302Sopenharmony_ci} 143570af302Sopenharmony_ci 144570af302Sopenharmony_civoid dlopen_seperated(char * dllPath_ns) 145570af302Sopenharmony_ci{ 146570af302Sopenharmony_ci Dl_namespace dlns_default; 147570af302Sopenharmony_ci dlns_get(NULL, &dlns_default); 148570af302Sopenharmony_ci Dl_namespace dlns1; 149570af302Sopenharmony_ci dlns_init(&dlns1, "ns_for_no_seperated"); 150570af302Sopenharmony_ci dlns_create2(&dlns1, errPath_ns, 0); 151570af302Sopenharmony_ci dlns_inherit(&dlns1, &dlns_default, "libc++.so"); 152570af302Sopenharmony_ci void* handle = NULL; 153570af302Sopenharmony_ci // current ns can't load this so. 154570af302Sopenharmony_ci handle = dlopen_ns(&dlns1, dllName, RTLD_NOW); 155570af302Sopenharmony_ci if(handle) 156570af302Sopenharmony_ci t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 157570af302Sopenharmony_ci 158570af302Sopenharmony_ci // current ns can load the so by absolute path. 159570af302Sopenharmony_ci char absolute_path_1[512]; 160570af302Sopenharmony_ci snprintf(absolute_path_1, sizeof(absolute_path_1), "%s/%s", dllPath_ns, dllName); 161570af302Sopenharmony_ci handle = dlopen_ns(&dlns1, absolute_path_1, RTLD_NOW); 162570af302Sopenharmony_ci if (!handle) 163570af302Sopenharmony_ci t_error("%s can load %s by absolute path but failed : %s \n", dlns1.name, absolute_path_1, dlerror()); 164570af302Sopenharmony_ci 165570af302Sopenharmony_ci if(dlclose(handle)) 166570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", absolute_path_1, dlerror()); 167570af302Sopenharmony_ci 168570af302Sopenharmony_ci // current ns can't load the so by absolute path if it has inaccessible dependent so. 169570af302Sopenharmony_ci char absolute_path_2[512]; 170570af302Sopenharmony_ci snprintf(absolute_path_2, sizeof(absolute_path_2), "%s/%s", dllPath_ns, SO_HAS_DEPENDENCES); 171570af302Sopenharmony_ci handle = dlopen_ns(&dlns1, absolute_path_2, RTLD_NOW); 172570af302Sopenharmony_ci if (handle) 173570af302Sopenharmony_ci t_error("%s can't load %s by absolute path because but it has inaccessible dependent so but succeed : %s \n", dlns1.name, absolute_path_2, dlerror()); 174570af302Sopenharmony_ci} 175570af302Sopenharmony_ci 176570af302Sopenharmony_civoid dlopen_inherit(char* dllPath_ns) 177570af302Sopenharmony_ci{ 178570af302Sopenharmony_ci Dl_namespace dlns_default; 179570af302Sopenharmony_ci dlns_get(NULL, &dlns_default); 180570af302Sopenharmony_ci Dl_namespace inherit_A, inherit_B; 181570af302Sopenharmony_ci dlns_init(&inherit_A, "inherir_error_lib_A"); 182570af302Sopenharmony_ci dlns_init(&inherit_B, "inherir_error_lib_B"); 183570af302Sopenharmony_ci dlns_create2(&inherit_A, NULL, 0); 184570af302Sopenharmony_ci dlns_create2(&inherit_B, dllPath_ns, 0); 185570af302Sopenharmony_ci dlns_inherit(&inherit_B, &dlns_default, "libc++.so"); 186570af302Sopenharmony_ci 187570af302Sopenharmony_ci // inherit_A can't load the so because search path is NULL. 188570af302Sopenharmony_ci void* handle1 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 189570af302Sopenharmony_ci if(handle1){ 190570af302Sopenharmony_ci t_error("dlopen_ns_by_ini_no_inherit handle %s should not open successfully \n", dllName); 191570af302Sopenharmony_ci dlclose(handle1); 192570af302Sopenharmony_ci } 193570af302Sopenharmony_ci 194570af302Sopenharmony_ci // inherit_A can load the so by inherit_B. 195570af302Sopenharmony_ci dlns_inherit(&inherit_A, &inherit_B, dllName); 196570af302Sopenharmony_ci void* handle2 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 197570af302Sopenharmony_ci if(!handle2) 198570af302Sopenharmony_ci t_error("dlopen_ns_by_dlns_inherir handle get error %s open failed : %s \n", dllName, dlerror()); 199570af302Sopenharmony_ci 200570af302Sopenharmony_ci if(dlclose(handle2)) 201570af302Sopenharmony_ci t_error("dlclose_by_dlns_inherir handle %s close failed : %s\n", dllName, dlerror()); 202570af302Sopenharmony_ci 203570af302Sopenharmony_ci // inherit_A can't load the so by inherit ns if the so isn't in shared libs. 204570af302Sopenharmony_ci dlns_inherit(&inherit_A, &inherit_B, dllName2); 205570af302Sopenharmony_ci void* handle3 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 206570af302Sopenharmony_ci if(handle3){ 207570af302Sopenharmony_ci t_error("dlopen_ns_by_ini_no_inherit handle2 %s should not open successfully \n", dllName); 208570af302Sopenharmony_ci dlclose(handle3); 209570af302Sopenharmony_ci } 210570af302Sopenharmony_ci} 211570af302Sopenharmony_ci 212570af302Sopenharmony_civoid dlopen_inherit_check_can_pass(char* dllPath_ns) 213570af302Sopenharmony_ci{ 214570af302Sopenharmony_ci Dl_namespace dlns_default; 215570af302Sopenharmony_ci dlns_get(NULL, &dlns_default); 216570af302Sopenharmony_ci Dl_namespace transitivity_A, transitivity_B, transitivity_C; 217570af302Sopenharmony_ci dlns_init(&transitivity_A, "transitivity_A"); 218570af302Sopenharmony_ci dlns_init(&transitivity_B, "transitivity_B"); 219570af302Sopenharmony_ci dlns_init(&transitivity_C, "transitivity_C"); 220570af302Sopenharmony_ci dlns_create2(&transitivity_A, NULL, 0); 221570af302Sopenharmony_ci dlns_create2(&transitivity_B, NULL, 0); 222570af302Sopenharmony_ci dlns_create2(&transitivity_C, dllPath_ns, 0); 223570af302Sopenharmony_ci dlns_inherit(&transitivity_A, &transitivity_B, NULL); 224570af302Sopenharmony_ci dlns_inherit(&transitivity_B, &transitivity_C, dllName); 225570af302Sopenharmony_ci dlns_inherit(&transitivity_C, &dlns_default, "libc++.so"); 226570af302Sopenharmony_ci 227570af302Sopenharmony_ci void* handleB = dlopen_ns(&transitivity_B, dllName, RTLD_LAZY); 228570af302Sopenharmony_ci if(!handleB) 229570af302Sopenharmony_ci t_error("dlopen_ns_by_inherit_transitivity handleB get error %s open failed : %s \n", dllName, dlerror()); 230570af302Sopenharmony_ci 231570af302Sopenharmony_ci void* handleC = dlopen_ns(&transitivity_C, dllName, RTLD_LAZY); 232570af302Sopenharmony_ci if(!handleC) 233570af302Sopenharmony_ci t_error("dlopen_ns_by_inherit_transitivity handleC get error %s open failed : %s \n", dllName, dlerror()); 234570af302Sopenharmony_ci 235570af302Sopenharmony_ci if(dlclose(handleC)) 236570af302Sopenharmony_ci t_error("dlclose_by_inherit_transitivity handleC %s close failed : %s\n", dllName, dlerror()); 237570af302Sopenharmony_ci if(dlclose(handleB)) 238570af302Sopenharmony_ci t_error("dlclose_by_inherit_transitivity handleB %s close failed : %s\n", dllName, dlerror()); 239570af302Sopenharmony_ci 240570af302Sopenharmony_ci // transitivity_A can't load so because inherit can't pass. 241570af302Sopenharmony_ci void* handleA = dlopen_ns(&transitivity_A, dllName, RTLD_LAZY); 242570af302Sopenharmony_ci if(handleA){ 243570af302Sopenharmony_ci t_error("dlopen_ns_by_inherit_transitivity handleA %s should not open successfully \n", dllName); 244570af302Sopenharmony_ci dlclose(handleA); 245570af302Sopenharmony_ci } 246570af302Sopenharmony_ci} 247570af302Sopenharmony_ci 248570af302Sopenharmony_civoid dlopen_test_dlns_create2() 249570af302Sopenharmony_ci{ 250570af302Sopenharmony_ci Dl_namespace dlns; 251570af302Sopenharmony_ci dlns_init(&dlns, "ns_for_create2"); 252570af302Sopenharmony_ci // ns_for_create2 doesn't exist, it will use default ns to search so. 253570af302Sopenharmony_ci void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY); 254570af302Sopenharmony_ci if(!handle) 255570af302Sopenharmony_ci t_error("dlopen_ns %s use a non-existent ns failed: %s\n", dllName, dlerror()); 256570af302Sopenharmony_ci 257570af302Sopenharmony_ci if(dlclose(handle)) 258570af302Sopenharmony_ci t_error("dlclose %s failed : %s \n", dllName, dlerror()); 259570af302Sopenharmony_ci 260570af302Sopenharmony_ci // 0: ns_for_create2 doesn't inherit default ns. 261570af302Sopenharmony_ci dlns_create2(&dlns, errPath_ns, 0); 262570af302Sopenharmony_ci void* handle2 = dlopen_ns(&dlns, dllName, RTLD_LAZY); 263570af302Sopenharmony_ci if(handle2) 264570af302Sopenharmony_ci t_error("%s namespace can't see %s but dlopen succee.\n", "ns_for_create2", dllName); 265570af302Sopenharmony_ci} 266570af302Sopenharmony_ci 267570af302Sopenharmony_ciint main(int argc, char *argv[]) 268570af302Sopenharmony_ci{ 269570af302Sopenharmony_ci char buf[512],path[512]; 270570af302Sopenharmony_ci char* i; 271570af302Sopenharmony_ci //带so的路径 272570af302Sopenharmony_ci if (!t_pathrel(buf, sizeof buf, argv[0], "libdlopen_ns_dso.so")) { 273570af302Sopenharmony_ci t_error("failed to obtain relative path to libdlopen_ns_dso.so\n"); 274570af302Sopenharmony_ci return 1; 275570af302Sopenharmony_ci } 276570af302Sopenharmony_ci //包含so的路径 277570af302Sopenharmony_ci if (!t_pathrel(path, sizeof path, argv[0], "")) { 278570af302Sopenharmony_ci t_error("failed to obtain relative path to path\n"); 279570af302Sopenharmony_ci return 1; 280570af302Sopenharmony_ci } 281570af302Sopenharmony_ci path[strlen (path) -1 ] ='\0'; 282570af302Sopenharmony_ci main_dlopen_ndk_so(); 283570af302Sopenharmony_ci system_so_dlopen_ndk_so(); 284570af302Sopenharmony_ci ndk_so_dlopen_default_ns_so(); 285570af302Sopenharmony_ci dlopen_same_so_twice_by_same_ns(path); 286570af302Sopenharmony_ci dlopen_same_so_by_different_ns(path); 287570af302Sopenharmony_ci dlopen_same_so_by_different_inherit_ns(path); 288570af302Sopenharmony_ci dlopen_seperated(path); 289570af302Sopenharmony_ci dlopen_test_dlns_create2(); 290570af302Sopenharmony_ci dlopen_inherit(path); 291570af302Sopenharmony_ci dlopen_inherit_check_can_pass(path); 292570af302Sopenharmony_ci 293570af302Sopenharmony_ci return t_status; 294570af302Sopenharmony_ci}