15db71995Sopenharmony_ci/* 25db71995Sopenharmony_ci * Copyright (c) 2021-2022 The Khronos Group Inc. 35db71995Sopenharmony_ci * Copyright (c) 2021-2022 Valve Corporation 45db71995Sopenharmony_ci * Copyright (c) 2021-2022 LunarG, Inc. 55db71995Sopenharmony_ci * 65db71995Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 75db71995Sopenharmony_ci * of this software and/or associated documentation files (the "Materials"), to 85db71995Sopenharmony_ci * deal in the Materials without restriction, including without limitation the 95db71995Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 105db71995Sopenharmony_ci * sell copies of the Materials, and to permit persons to whom the Materials are 115db71995Sopenharmony_ci * furnished to do so, subject to the following conditions: 125db71995Sopenharmony_ci * 135db71995Sopenharmony_ci * The above copyright notice(s) and this permission notice shall be included in 145db71995Sopenharmony_ci * all copies or substantial portions of the Materials. 155db71995Sopenharmony_ci * 165db71995Sopenharmony_ci * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175db71995Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 185db71995Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 195db71995Sopenharmony_ci * 205db71995Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 215db71995Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 225db71995Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 235db71995Sopenharmony_ci * USE OR OTHER DEALINGS IN THE MATERIALS. 245db71995Sopenharmony_ci * 255db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com> 265db71995Sopenharmony_ci */ 275db71995Sopenharmony_ci 285db71995Sopenharmony_ci#include "shim.h" 295db71995Sopenharmony_ci 305db71995Sopenharmony_ci#include <algorithm> 315db71995Sopenharmony_ci 325db71995Sopenharmony_ci#if defined(__APPLE__) 335db71995Sopenharmony_ci#include <CoreFoundation/CoreFoundation.h> 345db71995Sopenharmony_ci#endif 355db71995Sopenharmony_ci 365db71995Sopenharmony_ciPlatformShim platform_shim; 375db71995Sopenharmony_ciextern "C" { 385db71995Sopenharmony_ci#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) 395db71995Sopenharmony_ciPlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders) { 405db71995Sopenharmony_ci platform_shim = PlatformShim(folders); 415db71995Sopenharmony_ci return &platform_shim; 425db71995Sopenharmony_ci} 435db71995Sopenharmony_ci#elif defined(__APPLE__) 445db71995Sopenharmony_ciFRAMEWORK_EXPORT PlatformShim* get_platform_shim(std::vector<fs::FolderManager>* folders) { 455db71995Sopenharmony_ci platform_shim = PlatformShim(folders); 465db71995Sopenharmony_ci return &platform_shim; 475db71995Sopenharmony_ci} 485db71995Sopenharmony_ci#endif 495db71995Sopenharmony_ci 505db71995Sopenharmony_ci// Necessary for MacOS function shimming 515db71995Sopenharmony_ci#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__GNU__) 525db71995Sopenharmony_ci#define OPENDIR_FUNC_NAME opendir 535db71995Sopenharmony_ci#define READDIR_FUNC_NAME readdir 545db71995Sopenharmony_ci#define CLOSEDIR_FUNC_NAME closedir 555db71995Sopenharmony_ci#define ACCESS_FUNC_NAME access 565db71995Sopenharmony_ci#define FOPEN_FUNC_NAME fopen 575db71995Sopenharmony_ci#define DLOPEN_FUNC_NAME dlopen 585db71995Sopenharmony_ci#define GETEUID_FUNC_NAME geteuid 595db71995Sopenharmony_ci#define GETEGID_FUNC_NAME getegid 605db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 615db71995Sopenharmony_ci#define SECURE_GETENV_FUNC_NAME secure_getenv 625db71995Sopenharmony_ci#endif 635db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 645db71995Sopenharmony_ci#define __SECURE_GETENV_FUNC_NAME __secure_getenv 655db71995Sopenharmony_ci#endif 665db71995Sopenharmony_ci#elif defined(__APPLE__) 675db71995Sopenharmony_ci#define OPENDIR_FUNC_NAME my_opendir 685db71995Sopenharmony_ci#define READDIR_FUNC_NAME my_readdir 695db71995Sopenharmony_ci#define CLOSEDIR_FUNC_NAME my_closedir 705db71995Sopenharmony_ci#define ACCESS_FUNC_NAME my_access 715db71995Sopenharmony_ci#define FOPEN_FUNC_NAME my_fopen 725db71995Sopenharmony_ci#define DLOPEN_FUNC_NAME my_dlopen 735db71995Sopenharmony_ci#define GETEUID_FUNC_NAME my_geteuid 745db71995Sopenharmony_ci#define GETEGID_FUNC_NAME my_getegid 755db71995Sopenharmony_ci#if !defined(TARGET_OS_IPHONE) 765db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 775db71995Sopenharmony_ci#define SECURE_GETENV_FUNC_NAME my_secure_getenv 785db71995Sopenharmony_ci#endif 795db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 805db71995Sopenharmony_ci#define __SECURE_GETENV_FUNC_NAME my__secure_getenv 815db71995Sopenharmony_ci#endif 825db71995Sopenharmony_ci#endif 835db71995Sopenharmony_ci#endif 845db71995Sopenharmony_ci 855db71995Sopenharmony_ciusing PFN_OPENDIR = DIR* (*)(const char* path_name); 865db71995Sopenharmony_ciusing PFN_READDIR = struct dirent* (*)(DIR* dir_stream); 875db71995Sopenharmony_ciusing PFN_CLOSEDIR = int (*)(DIR* dir_stream); 885db71995Sopenharmony_ciusing PFN_ACCESS = int (*)(const char* pathname, int mode); 895db71995Sopenharmony_ciusing PFN_FOPEN = FILE* (*)(const char* filename, const char* mode); 905db71995Sopenharmony_ciusing PFN_DLOPEN = void* (*)(const char* in_filename, int flags); 915db71995Sopenharmony_ciusing PFN_GETEUID = uid_t (*)(void); 925db71995Sopenharmony_ciusing PFN_GETEGID = gid_t (*)(void); 935db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) || defined(HAVE___SECURE_GETENV) 945db71995Sopenharmony_ciusing PFN_SEC_GETENV = char* (*)(const char* name); 955db71995Sopenharmony_ci#endif 965db71995Sopenharmony_ci 975db71995Sopenharmony_ci#if defined(__APPLE__) 985db71995Sopenharmony_ci#define real_opendir opendir 995db71995Sopenharmony_ci#define real_readdir readdir 1005db71995Sopenharmony_ci#define real_closedir closedir 1015db71995Sopenharmony_ci#define real_access access 1025db71995Sopenharmony_ci#define real_fopen fopen 1035db71995Sopenharmony_ci#define real_dlopen dlopen 1045db71995Sopenharmony_ci#define real_geteuid geteuid 1055db71995Sopenharmony_ci#define real_getegid getegid 1065db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 1075db71995Sopenharmony_ci#define real_secure_getenv secure_getenv 1085db71995Sopenharmony_ci#endif 1095db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 1105db71995Sopenharmony_ci#define real__secure_getenv __secure_getenv 1115db71995Sopenharmony_ci#endif 1125db71995Sopenharmony_ci#else 1135db71995Sopenharmony_ciPFN_OPENDIR real_opendir = nullptr; 1145db71995Sopenharmony_ciPFN_READDIR real_readdir = nullptr; 1155db71995Sopenharmony_ciPFN_CLOSEDIR real_closedir = nullptr; 1165db71995Sopenharmony_ciPFN_ACCESS real_access = nullptr; 1175db71995Sopenharmony_ciPFN_FOPEN real_fopen = nullptr; 1185db71995Sopenharmony_ciPFN_DLOPEN real_dlopen = nullptr; 1195db71995Sopenharmony_ciPFN_GETEUID real_geteuid = nullptr; 1205db71995Sopenharmony_ciPFN_GETEGID real_getegid = nullptr; 1215db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 1225db71995Sopenharmony_ciPFN_SEC_GETENV real_secure_getenv = nullptr; 1235db71995Sopenharmony_ci#endif 1245db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 1255db71995Sopenharmony_ciPFN_SEC_GETENV real__secure_getenv = nullptr; 1265db71995Sopenharmony_ci#endif 1275db71995Sopenharmony_ci#endif 1285db71995Sopenharmony_ci 1295db71995Sopenharmony_ciFRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) { 1305db71995Sopenharmony_ci#if !defined(__APPLE__) 1315db71995Sopenharmony_ci if (!real_opendir) real_opendir = (PFN_OPENDIR)dlsym(RTLD_NEXT, "opendir"); 1325db71995Sopenharmony_ci#endif 1335db71995Sopenharmony_ci if (platform_shim.is_during_destruction) { 1345db71995Sopenharmony_ci return real_opendir(path_name); 1355db71995Sopenharmony_ci } 1365db71995Sopenharmony_ci DIR* dir; 1375db71995Sopenharmony_ci if (platform_shim.is_fake_path(path_name)) { 1385db71995Sopenharmony_ci auto real_path_name = platform_shim.get_real_path_from_fake_path(fs::path(path_name)); 1395db71995Sopenharmony_ci dir = real_opendir(real_path_name.c_str()); 1405db71995Sopenharmony_ci platform_shim.dir_entries.push_back(DirEntry{dir, std::string(path_name), {}, 0, true}); 1415db71995Sopenharmony_ci } else if (platform_shim.is_known_path(path_name)) { 1425db71995Sopenharmony_ci dir = real_opendir(path_name); 1435db71995Sopenharmony_ci platform_shim.dir_entries.push_back(DirEntry{dir, std::string(path_name), {}, 0, false}); 1445db71995Sopenharmony_ci } else { 1455db71995Sopenharmony_ci dir = real_opendir(path_name); 1465db71995Sopenharmony_ci } 1475db71995Sopenharmony_ci 1485db71995Sopenharmony_ci return dir; 1495db71995Sopenharmony_ci} 1505db71995Sopenharmony_ci 1515db71995Sopenharmony_ciFRAMEWORK_EXPORT struct dirent* READDIR_FUNC_NAME(DIR* dir_stream) { 1525db71995Sopenharmony_ci#if !defined(__APPLE__) 1535db71995Sopenharmony_ci if (!real_readdir) real_readdir = (PFN_READDIR)dlsym(RTLD_NEXT, "readdir"); 1545db71995Sopenharmony_ci#endif 1555db71995Sopenharmony_ci if (platform_shim.is_during_destruction) { 1565db71995Sopenharmony_ci return real_readdir(dir_stream); 1575db71995Sopenharmony_ci } 1585db71995Sopenharmony_ci auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(), 1595db71995Sopenharmony_ci [dir_stream](DirEntry const& entry) { return entry.directory == dir_stream; }); 1605db71995Sopenharmony_ci 1615db71995Sopenharmony_ci if (it == platform_shim.dir_entries.end()) { 1625db71995Sopenharmony_ci return real_readdir(dir_stream); 1635db71995Sopenharmony_ci } 1645db71995Sopenharmony_ci // Folder was found but this is the first file to be read from it 1655db71995Sopenharmony_ci if (it->current_index == 0) { 1665db71995Sopenharmony_ci std::vector<struct dirent*> folder_contents; 1675db71995Sopenharmony_ci std::vector<std::string> dirent_filenames; 1685db71995Sopenharmony_ci while (true) { 1695db71995Sopenharmony_ci struct dirent* dir_entry = real_readdir(dir_stream); 1705db71995Sopenharmony_ci if (NULL == dir_entry) { 1715db71995Sopenharmony_ci break; 1725db71995Sopenharmony_ci } 1735db71995Sopenharmony_ci folder_contents.push_back(dir_entry); 1745db71995Sopenharmony_ci dirent_filenames.push_back(&dir_entry->d_name[0]); 1755db71995Sopenharmony_ci } 1765db71995Sopenharmony_ci auto real_path = it->folder_path; 1775db71995Sopenharmony_ci if (it->is_fake_path) { 1785db71995Sopenharmony_ci real_path = platform_shim.redirection_map.at(it->folder_path).str(); 1795db71995Sopenharmony_ci } 1805db71995Sopenharmony_ci auto filenames = get_folder_contents(platform_shim.folders, real_path); 1815db71995Sopenharmony_ci 1825db71995Sopenharmony_ci // Add the dirent structures in the order they appear in the FolderManager 1835db71995Sopenharmony_ci // Ignore anything which wasn't in the FolderManager 1845db71995Sopenharmony_ci for (auto const& file : filenames) { 1855db71995Sopenharmony_ci for (size_t i = 0; i < dirent_filenames.size(); i++) { 1865db71995Sopenharmony_ci if (file == dirent_filenames.at(i)) { 1875db71995Sopenharmony_ci it->contents.push_back(folder_contents.at(i)); 1885db71995Sopenharmony_ci break; 1895db71995Sopenharmony_ci } 1905db71995Sopenharmony_ci } 1915db71995Sopenharmony_ci } 1925db71995Sopenharmony_ci } 1935db71995Sopenharmony_ci if (it->current_index >= it->contents.size()) return nullptr; 1945db71995Sopenharmony_ci return it->contents.at(it->current_index++); 1955db71995Sopenharmony_ci} 1965db71995Sopenharmony_ci 1975db71995Sopenharmony_ciFRAMEWORK_EXPORT int CLOSEDIR_FUNC_NAME(DIR* dir_stream) { 1985db71995Sopenharmony_ci#if !defined(__APPLE__) 1995db71995Sopenharmony_ci if (!real_closedir) real_closedir = (PFN_CLOSEDIR)dlsym(RTLD_NEXT, "closedir"); 2005db71995Sopenharmony_ci#endif 2015db71995Sopenharmony_ci if (platform_shim.is_during_destruction) { 2025db71995Sopenharmony_ci return real_closedir(dir_stream); 2035db71995Sopenharmony_ci } 2045db71995Sopenharmony_ci auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(), 2055db71995Sopenharmony_ci [dir_stream](DirEntry const& entry) { return entry.directory == dir_stream; }); 2065db71995Sopenharmony_ci 2075db71995Sopenharmony_ci if (it != platform_shim.dir_entries.end()) { 2085db71995Sopenharmony_ci platform_shim.dir_entries.erase(it); 2095db71995Sopenharmony_ci } 2105db71995Sopenharmony_ci 2115db71995Sopenharmony_ci return real_closedir(dir_stream); 2125db71995Sopenharmony_ci} 2135db71995Sopenharmony_ci 2145db71995Sopenharmony_ciFRAMEWORK_EXPORT int ACCESS_FUNC_NAME(const char* in_pathname, int mode) { 2155db71995Sopenharmony_ci#if !defined(__APPLE__) 2165db71995Sopenharmony_ci if (!real_access) real_access = (PFN_ACCESS)dlsym(RTLD_NEXT, "access"); 2175db71995Sopenharmony_ci#endif 2185db71995Sopenharmony_ci fs::path path{in_pathname}; 2195db71995Sopenharmony_ci if (!path.has_parent_path()) { 2205db71995Sopenharmony_ci return real_access(in_pathname, mode); 2215db71995Sopenharmony_ci } 2225db71995Sopenharmony_ci 2235db71995Sopenharmony_ci if (platform_shim.is_fake_path(path.parent_path())) { 2245db71995Sopenharmony_ci fs::path real_path = platform_shim.get_real_path_from_fake_path(path.parent_path()); 2255db71995Sopenharmony_ci real_path /= path.filename(); 2265db71995Sopenharmony_ci return real_access(real_path.c_str(), mode); 2275db71995Sopenharmony_ci } 2285db71995Sopenharmony_ci return real_access(in_pathname, mode); 2295db71995Sopenharmony_ci} 2305db71995Sopenharmony_ci 2315db71995Sopenharmony_ciFRAMEWORK_EXPORT FILE* FOPEN_FUNC_NAME(const char* in_filename, const char* mode) { 2325db71995Sopenharmony_ci#if !defined(__APPLE__) 2335db71995Sopenharmony_ci if (!real_fopen) real_fopen = (PFN_FOPEN)dlsym(RTLD_NEXT, "fopen"); 2345db71995Sopenharmony_ci#endif 2355db71995Sopenharmony_ci fs::path path{in_filename}; 2365db71995Sopenharmony_ci if (!path.has_parent_path()) { 2375db71995Sopenharmony_ci return real_fopen(in_filename, mode); 2385db71995Sopenharmony_ci } 2395db71995Sopenharmony_ci 2405db71995Sopenharmony_ci FILE* f_ptr; 2415db71995Sopenharmony_ci if (platform_shim.is_fake_path(path.parent_path())) { 2425db71995Sopenharmony_ci auto real_path = platform_shim.get_real_path_from_fake_path(path.parent_path()) / path.filename(); 2435db71995Sopenharmony_ci f_ptr = real_fopen(real_path.c_str(), mode); 2445db71995Sopenharmony_ci } else { 2455db71995Sopenharmony_ci f_ptr = real_fopen(in_filename, mode); 2465db71995Sopenharmony_ci } 2475db71995Sopenharmony_ci 2485db71995Sopenharmony_ci return f_ptr; 2495db71995Sopenharmony_ci} 2505db71995Sopenharmony_ci 2515db71995Sopenharmony_ciFRAMEWORK_EXPORT void* DLOPEN_FUNC_NAME(const char* in_filename, int flags) { 2525db71995Sopenharmony_ci#if !defined(__APPLE__) 2535db71995Sopenharmony_ci if (!real_dlopen) real_dlopen = (PFN_DLOPEN)dlsym(RTLD_NEXT, "dlopen"); 2545db71995Sopenharmony_ci#endif 2555db71995Sopenharmony_ci 2565db71995Sopenharmony_ci if (platform_shim.is_dlopen_redirect_name(in_filename)) { 2575db71995Sopenharmony_ci return real_dlopen(platform_shim.dlopen_redirection_map[in_filename].c_str(), flags); 2585db71995Sopenharmony_ci } 2595db71995Sopenharmony_ci return real_dlopen(in_filename, flags); 2605db71995Sopenharmony_ci} 2615db71995Sopenharmony_ci 2625db71995Sopenharmony_ciFRAMEWORK_EXPORT uid_t GETEUID_FUNC_NAME(void) { 2635db71995Sopenharmony_ci#if !defined(__APPLE__) 2645db71995Sopenharmony_ci if (!real_geteuid) real_geteuid = (PFN_GETEUID)dlsym(RTLD_NEXT, "geteuid"); 2655db71995Sopenharmony_ci#endif 2665db71995Sopenharmony_ci if (platform_shim.use_fake_elevation) { 2675db71995Sopenharmony_ci // Root on linux is 0, so force pretending like we're root 2685db71995Sopenharmony_ci return 0; 2695db71995Sopenharmony_ci } else { 2705db71995Sopenharmony_ci return real_geteuid(); 2715db71995Sopenharmony_ci } 2725db71995Sopenharmony_ci} 2735db71995Sopenharmony_ci 2745db71995Sopenharmony_ciFRAMEWORK_EXPORT gid_t GETEGID_FUNC_NAME(void) { 2755db71995Sopenharmony_ci#if !defined(__APPLE__) 2765db71995Sopenharmony_ci if (!real_getegid) real_getegid = (PFN_GETEGID)dlsym(RTLD_NEXT, "getegid"); 2775db71995Sopenharmony_ci#endif 2785db71995Sopenharmony_ci if (platform_shim.use_fake_elevation) { 2795db71995Sopenharmony_ci // Root on linux is 0, so force pretending like we're root 2805db71995Sopenharmony_ci return 0; 2815db71995Sopenharmony_ci } else { 2825db71995Sopenharmony_ci return real_getegid(); 2835db71995Sopenharmony_ci } 2845db71995Sopenharmony_ci} 2855db71995Sopenharmony_ci 2865db71995Sopenharmony_ci#if !defined(TARGET_OS_IPHONE) 2875db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 2885db71995Sopenharmony_ciFRAMEWORK_EXPORT char* SECURE_GETENV_FUNC_NAME(const char* name) { 2895db71995Sopenharmony_ci#if !defined(__APPLE__) 2905db71995Sopenharmony_ci if (!real_secure_getenv) real_secure_getenv = (PFN_SEC_GETENV)dlsym(RTLD_NEXT, "secure_getenv"); 2915db71995Sopenharmony_ci#endif 2925db71995Sopenharmony_ci if (platform_shim.use_fake_elevation) { 2935db71995Sopenharmony_ci return NULL; 2945db71995Sopenharmony_ci } else { 2955db71995Sopenharmony_ci return real_secure_getenv(name); 2965db71995Sopenharmony_ci } 2975db71995Sopenharmony_ci} 2985db71995Sopenharmony_ci#endif 2995db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 3005db71995Sopenharmony_ciFRAMEWORK_EXPORT char* __SECURE_GETENV_FUNC_NAME(const char* name) { 3015db71995Sopenharmony_ci#if !defined(__APPLE__) 3025db71995Sopenharmony_ci if (!real__secure_getenv) real__secure_getenv = (PFN_SEC_GETENV)dlsym(RTLD_NEXT, "__secure_getenv"); 3035db71995Sopenharmony_ci#endif 3045db71995Sopenharmony_ci 3055db71995Sopenharmony_ci if (platform_shim.use_fake_elevation) { 3065db71995Sopenharmony_ci return NULL; 3075db71995Sopenharmony_ci } else { 3085db71995Sopenharmony_ci return real__secure_getenv(name); 3095db71995Sopenharmony_ci } 3105db71995Sopenharmony_ci} 3115db71995Sopenharmony_ci#endif 3125db71995Sopenharmony_ci#endif 3135db71995Sopenharmony_ci#if defined(__APPLE__) 3145db71995Sopenharmony_ciFRAMEWORK_EXPORT CFBundleRef my_CFBundleGetMainBundle() { 3155db71995Sopenharmony_ci static CFBundleRef global_bundle{}; 3165db71995Sopenharmony_ci return reinterpret_cast<CFBundleRef>(&global_bundle); 3175db71995Sopenharmony_ci} 3185db71995Sopenharmony_ciFRAMEWORK_EXPORT CFURLRef my_CFBundleCopyResourcesDirectoryURL([[maybe_unused]] CFBundleRef bundle) { 3195db71995Sopenharmony_ci static CFURLRef global_url{}; 3205db71995Sopenharmony_ci return reinterpret_cast<CFURLRef>(&global_url); 3215db71995Sopenharmony_ci} 3225db71995Sopenharmony_ciFRAMEWORK_EXPORT Boolean my_CFURLGetFileSystemRepresentation([[maybe_unused]] CFURLRef url, 3235db71995Sopenharmony_ci [[maybe_unused]] Boolean resolveAgainstBase, UInt8* buffer, 3245db71995Sopenharmony_ci CFIndex maxBufLen) { 3255db71995Sopenharmony_ci if (!platform_shim.bundle_contents.empty()) { 3265db71995Sopenharmony_ci CFIndex copy_len = (CFIndex)platform_shim.bundle_contents.size(); 3275db71995Sopenharmony_ci if (copy_len > maxBufLen) { 3285db71995Sopenharmony_ci copy_len = maxBufLen; 3295db71995Sopenharmony_ci } 3305db71995Sopenharmony_ci strncpy(reinterpret_cast<char*>(buffer), platform_shim.bundle_contents.c_str(), copy_len); 3315db71995Sopenharmony_ci return TRUE; 3325db71995Sopenharmony_ci } 3335db71995Sopenharmony_ci return FALSE; 3345db71995Sopenharmony_ci} 3355db71995Sopenharmony_ci#endif 3365db71995Sopenharmony_ci 3375db71995Sopenharmony_ci/* Shiming functions on apple is limited by the linker prefering to not use functions in the 3385db71995Sopenharmony_ci * executable in loaded dylibs. By adding an interposer, we redirect the linker to use our 3395db71995Sopenharmony_ci * version of the function over the real one, thus shimming the system function. 3405db71995Sopenharmony_ci */ 3415db71995Sopenharmony_ci#if defined(__APPLE__) 3425db71995Sopenharmony_ci#define MACOS_ATTRIB __attribute__((section("__DATA,__interpose"))) 3435db71995Sopenharmony_ci#define VOIDP_CAST(_func) reinterpret_cast<const void*>(&_func) 3445db71995Sopenharmony_ci 3455db71995Sopenharmony_cistruct Interposer { 3465db71995Sopenharmony_ci const void* shim_function; 3475db71995Sopenharmony_ci const void* underlying_function; 3485db71995Sopenharmony_ci}; 3495db71995Sopenharmony_ci 3505db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_opendir MACOS_ATTRIB = {VOIDP_CAST(my_opendir), VOIDP_CAST(opendir)}; 3515db71995Sopenharmony_ci// don't intercept readdir as it crashes when using ASAN with macOS 3525db71995Sopenharmony_ci// __attribute__((used)) static Interposer _interpose_readdir MACOS_ATTRIB = {VOIDP_CAST(my_readdir), VOIDP_CAST(readdir)}; 3535db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_closedir MACOS_ATTRIB = {VOIDP_CAST(my_closedir), VOIDP_CAST(closedir)}; 3545db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_access MACOS_ATTRIB = {VOIDP_CAST(my_access), VOIDP_CAST(access)}; 3555db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_fopen MACOS_ATTRIB = {VOIDP_CAST(my_fopen), VOIDP_CAST(fopen)}; 3565db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_dlopen MACOS_ATTRIB = {VOIDP_CAST(my_dlopen), VOIDP_CAST(dlopen)}; 3575db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_euid MACOS_ATTRIB = {VOIDP_CAST(my_geteuid), VOIDP_CAST(geteuid)}; 3585db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_egid MACOS_ATTRIB = {VOIDP_CAST(my_getegid), VOIDP_CAST(getegid)}; 3595db71995Sopenharmony_ci#if !defined(TARGET_OS_IPHONE) 3605db71995Sopenharmony_ci#if defined(HAVE_SECURE_GETENV) 3615db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_secure_getenv MACOS_ATTRIB = {VOIDP_CAST(my_secure_getenv), 3625db71995Sopenharmony_ci VOIDP_CAST(secure_getenv)}; 3635db71995Sopenharmony_ci#endif 3645db71995Sopenharmony_ci#if defined(HAVE___SECURE_GETENV) 3655db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose__secure_getenv MACOS_ATTRIB = {VOIDP_CAST(my__secure_getenv), 3665db71995Sopenharmony_ci VOIDP_CAST(__secure_getenv)}; 3675db71995Sopenharmony_ci#endif 3685db71995Sopenharmony_ci#endif 3695db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_CFBundleGetMainBundle MACOS_ATTRIB = {VOIDP_CAST(my_CFBundleGetMainBundle), 3705db71995Sopenharmony_ci VOIDP_CAST(CFBundleGetMainBundle)}; 3715db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_CFBundleCopyResourcesDirectoryURL MACOS_ATTRIB = { 3725db71995Sopenharmony_ci VOIDP_CAST(my_CFBundleCopyResourcesDirectoryURL), VOIDP_CAST(CFBundleCopyResourcesDirectoryURL)}; 3735db71995Sopenharmony_ci__attribute__((used)) static Interposer _interpose_CFURLGetFileSystemRepresentation MACOS_ATTRIB = { 3745db71995Sopenharmony_ci VOIDP_CAST(my_CFURLGetFileSystemRepresentation), VOIDP_CAST(CFURLGetFileSystemRepresentation)}; 3755db71995Sopenharmony_ci 3765db71995Sopenharmony_ci#endif 3775db71995Sopenharmony_ci} // extern "C" 378