mirror of
https://github.com/bylaws/libadrenotools
synced 2024-11-21 14:29:15 -07:00
Rework hooking to avoid polluting global namespace with too many symbols
This commit is contained in:
parent
332425ac2e
commit
bec42142cf
11 changed files with 205 additions and 141 deletions
|
@ -4,11 +4,8 @@ if(NOT ${CMAKE_ANDROID_ARCH_ABI} STREQUAL arm64-v8a)
|
||||||
message(FATAL_ERROR "Unsupported target architecture: ${CMAKE_ANDROID_ARCH_ABI}. Please make an issue on the repo!")
|
message(FATAL_ERROR "Unsupported target architecture: ${CMAKE_ANDROID_ARCH_ABI}. Please make an issue on the repo!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(adrenotools LANGUAGES CXX)
|
project(adrenotools LANGUAGES CXX C)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
|
|
||||||
include_directories(lib/linkernsbypass)
|
|
||||||
add_subdirectory(lib/linkernsbypass)
|
add_subdirectory(lib/linkernsbypass)
|
||||||
|
|
||||||
set(LIB_SOURCES src/bcenabler.cpp
|
set(LIB_SOURCES src/bcenabler.cpp
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8a819a35e1585b8adfd95174299901362b57b154
|
Subproject commit 341f6e2d585c9501ad044338da34797c060aacf3
|
|
@ -8,11 +8,11 @@
|
||||||
#include <android/api-level.h>
|
#include <android/api-level.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <android_linker_ns.h>
|
#include <android_linker_ns.h>
|
||||||
#include "hook/main_hook.h"
|
#include "hook/hook_impl_params.h"
|
||||||
#include <adrenotools/driver.h>
|
#include <adrenotools/driver.h>
|
||||||
|
|
||||||
void *adrenotools_open_libvulkan(int dlopenMode, int featureFlags, const char *tmpLibDir, const char *hookLibDir, const char *customDriverDir, const char *customDriverName, const char *fileRedirectDir) {
|
void *adrenotools_open_libvulkan(int dlopenFlags, int featureFlags, const char *tmpLibDir, const char *hookLibDir, const char *customDriverDir, const char *customDriverName, const char *fileRedirectDir) {
|
||||||
// Bail out if linkernsbyapss failed to load, this probably means we're on api < 28
|
// Bail out if linkernsbypass failed to load, this probably means we're on api < 28
|
||||||
if (!linkernsbypass_load_status())
|
if (!linkernsbypass_load_status())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -47,8 +47,28 @@ void *adrenotools_open_libvulkan(int dlopenMode, int featureFlags, const char *t
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will be destroyed by the libmain_hook.so destructor on unload
|
// Create a namespace that can isolate our hook from the classloader namespace
|
||||||
auto *hookParam{new MainHookParam(featureFlags, tmpLibDir, hookLibDir, customDriverDir, customDriverName, fileRedirectDir)};
|
auto hookNs{android_create_namespace("adrenotools-libvulkan", hookLibDir, nullptr, ANDROID_NAMESPACE_TYPE_SHARED, nullptr, nullptr)};
|
||||||
|
|
||||||
return linkernsbypass_dlopen_unique_hooked("/system/lib64/libvulkan.so", tmpLibDir, dlopenMode, hookLibDir, "libmain_hook.so", nullptr, true, reinterpret_cast<void *>(hookParam));
|
// Link it to the default namespace so the hook can use libandroid etc
|
||||||
|
if (!linkernsbypass_link_namespace_to_default_all_libs(hookNs))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Preload the hook implementation, otherwise we get a weird issue where despite being in NEEDED of the hook lib the hook's symbols will overwrite ours and cause an infinite loop
|
||||||
|
auto hookImpl{linkernsbypass_namespace_dlopen("libhook_impl.so", RTLD_NOW, hookNs)};
|
||||||
|
if (!hookImpl)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Pass parameters to the hook implementation
|
||||||
|
auto initHookParam{reinterpret_cast<void (*)(const void *)>(dlsym(hookImpl, "init_hook_param"))};
|
||||||
|
if (!initHookParam)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
initHookParam(new HookImplParams(featureFlags, tmpLibDir, hookLibDir, customDriverDir, customDriverName, fileRedirectDir));
|
||||||
|
|
||||||
|
// Load the libvulkan hook into the isolated namespace
|
||||||
|
if (!linkernsbypass_namespace_dlopen("libmain_hook.so", RTLD_GLOBAL, hookNs))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return linkernsbypass_namespace_dlopen_unique("/system/lib64/libvulkan.so", tmpLibDir, dlopenFlags, hookNs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
add_library(main_hook SHARED main_hook.cpp)
|
add_library(hook_impl SHARED hook_impl.cpp hook_impl.h hook_impl_params.h)
|
||||||
|
|
||||||
|
target_compile_options(hook_impl PRIVATE -Wall -Wextra)
|
||||||
|
target_link_libraries(hook_impl linkernsbypass log)
|
||||||
|
target_include_directories(hook_impl PRIVATE ../../include)
|
||||||
|
set_target_properties(hook_impl PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
|
add_library(main_hook SHARED main_hook.c)
|
||||||
|
|
||||||
target_compile_options(main_hook PRIVATE -Wall -Wextra)
|
target_compile_options(main_hook PRIVATE -Wall -Wextra)
|
||||||
target_link_options(main_hook PRIVATE -z global)
|
target_link_options(main_hook PRIVATE -z global)
|
||||||
target_link_libraries(main_hook linkernsbypass log)
|
target_link_libraries(main_hook hook_impl)
|
||||||
target_include_directories(main_hook PRIVATE ../../include)
|
|
||||||
set_target_properties(main_hook PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
set_target_properties(main_hook PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
add_library(file_redirect_hook SHARED file_redirect_hook.cpp)
|
add_library(file_redirect_hook SHARED file_redirect_hook.c)
|
||||||
|
|
||||||
target_compile_options(file_redirect_hook PRIVATE -Wall -Wextra)
|
target_compile_options(file_redirect_hook PRIVATE -Wall -Wextra)
|
||||||
target_link_options(file_redirect_hook PRIVATE -z global)
|
target_link_options(file_redirect_hook PRIVATE -z global)
|
||||||
target_link_libraries(file_redirect_hook linkernsbypass dl log)
|
target_link_libraries(file_redirect_hook hook_impl)
|
||||||
target_include_directories(file_redirect_hook PRIVATE ../../include)
|
|
||||||
set_target_properties(file_redirect_hook PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
set_target_properties(file_redirect_hook PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
5
src/hook/file_redirect_hook.c
Normal file
5
src/hook/file_redirect_hook.c
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "hook_impl.h"
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) FILE *fopen(const char *filename, const char *mode) {
|
||||||
|
return hook_fopen(filename, mode);
|
||||||
|
}
|
|
@ -1,35 +1,9 @@
|
||||||
#include <string>
|
#include "hook_impl.h"
|
||||||
#include <cstdio>
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <android/log.h>
|
|
||||||
|
|
||||||
#define TAG "file_redirect_hook"
|
__attribute__((visibility("default"))) void init_hook_param(const void *param) {
|
||||||
#define LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##__VA_ARGS__)
|
init_file_redirect_hook_param(param);
|
||||||
|
|
||||||
static decltype(&fopen) libc_fopen{[]() {
|
|
||||||
auto libcHandle{dlopen("libc.so", RTLD_LAZY)};
|
|
||||||
if (!libcHandle)
|
|
||||||
__builtin_trap();
|
|
||||||
|
|
||||||
auto sym{dlsym(libcHandle, "fopen")};
|
|
||||||
if (!sym)
|
|
||||||
__builtin_trap();
|
|
||||||
|
|
||||||
return reinterpret_cast<decltype(&fopen)>(sym);
|
|
||||||
}()};
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
__attribute__((visibility("default"))) const char *hook_param; //!< The prefix to add to filesystem calls
|
|
||||||
|
|
||||||
__attribute__((visibility("default"))) FILE *fopen(const char *filename, const char *mode) {
|
|
||||||
if ((strncmp("/proc", filename, 5) == 0) || (strncmp("/sys", filename, 4) == 0)) {
|
|
||||||
LOGI("fopen: passthrough: %s", filename);
|
|
||||||
return libc_fopen(filename, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto replacement{std::string{hook_param} + filename};
|
|
||||||
LOGI("fopen: %s -> %s", filename, replacement.c_str());
|
|
||||||
|
|
||||||
return libc_fopen(replacement.c_str(), mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) FILE *fopen(const char *filename, const char *mode) {
|
||||||
|
return hook_fopen(filename, mode);
|
||||||
|
}
|
116
src/hook/hook_impl.cpp
Normal file
116
src/hook/hook_impl.cpp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <android_linker_ns.h>
|
||||||
|
#include <android/dlext.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "hook_impl_params.h"
|
||||||
|
#include "hook_impl.h"
|
||||||
|
|
||||||
|
#define TAG "hook_impl"
|
||||||
|
#define LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
const HookImplParams *hook_params; //!< Bunch of info needed to load/patch the driver
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void init_hook_param(const void *param) {
|
||||||
|
hook_params = reinterpret_cast<const HookImplParams *>(param);
|
||||||
|
LOGI("SET %p", param);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *hook_android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo) {
|
||||||
|
auto fallback{[&]() {
|
||||||
|
LOGI("hook_android_dlopen_ext: falling back!");
|
||||||
|
return android_dlopen_ext(filename, flags, extinfo);
|
||||||
|
}};
|
||||||
|
|
||||||
|
LOGI("hook_android_dlopen_ext: filename: %s", filename);
|
||||||
|
|
||||||
|
// Ignore non-vulkan libraries
|
||||||
|
if (!strstr(filename, "vulkan."))
|
||||||
|
return android_dlopen_ext(filename, flags, extinfo);
|
||||||
|
|
||||||
|
if (extinfo->library_namespace == nullptr || !(extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE)) {
|
||||||
|
LOGI("hook_android_dlopen_ext: hook failed: namespace not supplied!");
|
||||||
|
return fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
// customDriverDir will be empty if ADRENOTOOLS_DRIVER_CUSTOM isn't set therefore it's fine to have either way
|
||||||
|
auto driverNs{android_create_namespace(filename, hook_params->customDriverDir.c_str(),
|
||||||
|
hook_params->hookLibDir.c_str(), ANDROID_NAMESPACE_TYPE_SHARED,
|
||||||
|
nullptr, extinfo->library_namespace)};
|
||||||
|
if (!driverNs) {
|
||||||
|
LOGI("hook_android_dlopen_ext: hook failed: namespace not supplied!");
|
||||||
|
return fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We depend on libandroid which is unlikely to be in the supplied driver namespace so we have to link it over
|
||||||
|
android_link_namespaces(driverNs, nullptr, "libandroid.so");
|
||||||
|
|
||||||
|
// Preload ourself, a new instance will be created since we have different linker ancestory
|
||||||
|
// If we don't preload we get a weird issue where despite being in NEEDED of the hook lib the hook's symbols will overwrite ours and cause an infinite loop
|
||||||
|
auto hookImpl{linkernsbypass_namespace_dlopen("libhook_impl.so", RTLD_NOW, driverNs)};
|
||||||
|
if (!hookImpl)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Pass parameters to ourself
|
||||||
|
auto initHookParam{reinterpret_cast<void (*)(const void *)>(dlsym(hookImpl, "init_hook_param"))};
|
||||||
|
if (!initHookParam)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
initHookParam(hook_params);
|
||||||
|
|
||||||
|
if (hook_params->featureFlags & ADRENOTOOLS_DRIVER_FILE_REDIRECT) {
|
||||||
|
if (!linkernsbypass_namespace_dlopen("libfile_redirect_hook.so", RTLD_GLOBAL, driverNs)) {
|
||||||
|
LOGI("hook_android_dlopen_ext: hook failed: failed to apply libfopen_redirect_hook!");
|
||||||
|
return fallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGI("hook_android_dlopen_ext: applied libfile_redirect_hook");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use our new namespace to load the vulkan driver
|
||||||
|
auto newExtinfo{*extinfo};
|
||||||
|
newExtinfo.library_namespace = driverNs;
|
||||||
|
|
||||||
|
// TODO: If there is already an instance of a vulkan driver loaded hooks won't be applied, this will only be the case for skiavk generally
|
||||||
|
// To fix this we would need to search /proc/self/maps for the file to a loaded instance of the library in order to read it to patch the soname and load it uniquely
|
||||||
|
if (hook_params->featureFlags & ADRENOTOOLS_DRIVER_CUSTOM) {
|
||||||
|
LOGI("hook_android_dlopen_ext: loading custom driver: %s%s", hook_params->customDriverDir.c_str(), hook_params->customDriverName.c_str());
|
||||||
|
return android_dlopen_ext(hook_params->customDriverName.c_str(), flags, &newExtinfo);
|
||||||
|
} else {
|
||||||
|
LOGI("hook_android_dlopen_ext: loading default driver: %s", filename);
|
||||||
|
return android_dlopen_ext(filename, flags, &newExtinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *hook_android_load_sphal_library(const char *filename, int flags) {
|
||||||
|
LOGI("hook_android_load_sphal_library: filename: %s", filename);
|
||||||
|
|
||||||
|
// https://android.googlesource.com/platform/system/core/+/master/libvndksupport/linker.cpp
|
||||||
|
for (const char *name : {"sphal", "vendor", "default"}) {
|
||||||
|
if (auto vendorNs{android_get_exported_namespace(name)}) {
|
||||||
|
android_dlextinfo dlextinfo{
|
||||||
|
.flags = ANDROID_DLEXT_USE_NAMESPACE,
|
||||||
|
.library_namespace = vendorNs,
|
||||||
|
};
|
||||||
|
|
||||||
|
return hook_android_dlopen_ext(filename, flags, &dlextinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) FILE *hook_fopen(const char *filename, const char *mode) {
|
||||||
|
if (!strncmp("/proc", filename, 5) || !strncmp("/sys", filename, 4)) {
|
||||||
|
LOGI("hook_fopen: passthrough: %s", filename);
|
||||||
|
return fopen(filename, mode);
|
||||||
|
}
|
||||||
|
LOGI("LET %p", hook_params);
|
||||||
|
auto replacement{hook_params->fileRedirectDir + filename};
|
||||||
|
LOGI("hook_fopen: %s -> %s", filename, replacement.c_str());
|
||||||
|
|
||||||
|
return fopen(replacement.c_str(), mode);
|
||||||
|
}
|
25
src/hook/hook_impl.h
Normal file
25
src/hook/hook_impl.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
// Copyright © 2021 Billy Laws
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <android/dlext.h>
|
||||||
|
|
||||||
|
void init_hook_param(const void *param);
|
||||||
|
|
||||||
|
void *hook_android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo);
|
||||||
|
|
||||||
|
void *hook_android_load_sphal_library(const char *filename, int flags);
|
||||||
|
|
||||||
|
FILE *hook_fopen(const char *filename, const char *mode);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#include <adrenotools/priv.h>
|
#include <adrenotools/priv.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Holds the parameters for the main libvulkan.so hook
|
* @brief Holds the parameters needed for all hooks
|
||||||
* @note See comments for adrenotools_open_libvulkan as a reference for member variables
|
* @note See comments for adrenotools_open_libvulkan as a reference for member variables
|
||||||
*/
|
*/
|
||||||
struct MainHookParam {
|
struct HookImplParams {
|
||||||
int featureFlags;
|
int featureFlags;
|
||||||
std::string tmpLibDir;
|
std::string tmpLibDir;
|
||||||
std::string hookLibDir;
|
std::string hookLibDir;
|
||||||
|
@ -18,7 +18,8 @@ struct MainHookParam {
|
||||||
std::string customDriverName;
|
std::string customDriverName;
|
||||||
std::string fileRedirectDir;
|
std::string fileRedirectDir;
|
||||||
|
|
||||||
MainHookParam(int featureFlags, const char *tmpLibDir, const char *hookLibDir, const char *customDriverDir, const char *customDriverName, const char *fileRedirectDir)
|
HookImplParams(int featureFlags, const char *tmpLibDir, const char *hookLibDir, const char *customDriverDir,
|
||||||
|
const char *customDriverName, const char *fileRedirectDir)
|
||||||
: featureFlags(featureFlags),
|
: featureFlags(featureFlags),
|
||||||
tmpLibDir(tmpLibDir ? tmpLibDir : ""),
|
tmpLibDir(tmpLibDir ? tmpLibDir : ""),
|
||||||
hookLibDir(hookLibDir),
|
hookLibDir(hookLibDir),
|
9
src/hook/main_hook.c
Normal file
9
src/hook/main_hook.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "hook_impl.h"
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo) {
|
||||||
|
return hook_android_dlopen_ext(filename, flags, extinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((visibility("default"))) void *android_load_sphal_library(const char *filename, int flags) {
|
||||||
|
return hook_android_load_sphal_library(filename, flags);
|
||||||
|
}
|
|
@ -1,88 +0,0 @@
|
||||||
#include <cstring>
|
|
||||||
#include <android/dlext.h>
|
|
||||||
#include <android_linker_ns.h>
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "main_hook.h"
|
|
||||||
|
|
||||||
#define TAG "driver_load_hook"
|
|
||||||
#define LOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
// The namespace that should be used to load vulkan drivers, set dlopen_hooked from the hookParam argument
|
|
||||||
__attribute__((visibility("default"))) const MainHookParam *hook_param;
|
|
||||||
|
|
||||||
__attribute__((destructor)) static void free_hook_param() {
|
|
||||||
delete hook_param;
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void *android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo) {
|
|
||||||
auto fallback{[&]() {
|
|
||||||
LOGI("android_dlopen_ext: falling back!");
|
|
||||||
return libdl_android_dlopen_ext(filename, flags, extinfo);
|
|
||||||
}};
|
|
||||||
|
|
||||||
LOGI("android_dlopen_ext: filename: %s", filename);
|
|
||||||
|
|
||||||
// Ignore non-vulkan libraries
|
|
||||||
if (!strstr(filename, "vulkan."))
|
|
||||||
return libdl_android_dlopen_ext(filename, flags, extinfo);
|
|
||||||
|
|
||||||
if (extinfo->library_namespace == nullptr || !(extinfo->flags & ANDROID_DLEXT_USE_NAMESPACE)) {
|
|
||||||
LOGI("android_dlopen_ext: hook failed: namespace not supplied!");
|
|
||||||
return fallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
// customDriverDir will be empty if ADRENOTOOLS_DRIVER_CUSTOM isn't set therefore it's fine to have either way
|
|
||||||
auto driverNs{android_create_namespace(filename, hook_param->customDriverDir.c_str(),
|
|
||||||
hook_param->hookLibDir.c_str(), ANDROID_NAMESPACE_TYPE_SHARED,
|
|
||||||
nullptr, extinfo->library_namespace)};
|
|
||||||
if (!driverNs) {
|
|
||||||
LOGI("android_dlopen_ext: hook failed: namespace not supplied!");
|
|
||||||
return fallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook libs depend on libandroid which is unlikely to be in the supplied driver namespace so we have to link it over
|
|
||||||
android_link_namespaces(driverNs, nullptr, "libandroid.so");
|
|
||||||
|
|
||||||
if (hook_param->featureFlags & ADRENOTOOLS_DRIVER_FILE_REDIRECT) {
|
|
||||||
if (!linkernsbypass_namespace_apply_hook("libfile_redirect_hook.so", driverNs,
|
|
||||||
reinterpret_cast<const void *>(hook_param->fileRedirectDir.c_str()))) {
|
|
||||||
LOGI("android_dlopen_ext: hook failed: failed to apply libfopen_redirect_hook!");
|
|
||||||
return fallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGI("android_dlopen_ext: applied libfopen_redirect_hook");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use our new namespace to load the vulkan driver
|
|
||||||
auto newExtinfo{*extinfo};
|
|
||||||
newExtinfo.library_namespace = driverNs;
|
|
||||||
|
|
||||||
// TODO: If there is already an instance of a vulkan driver loaded hooks won't be applied, this will only be the case for skiavk generally
|
|
||||||
// To fix this we would need to search /proc/self/maps for the file to a loaded instance of the library in order to read it to patch the soname and load it uniquely
|
|
||||||
if (hook_param->featureFlags & ADRENOTOOLS_DRIVER_CUSTOM) {
|
|
||||||
LOGI("android_dlopen_ext: loading custom driver: %s%s", hook_param->customDriverDir.c_str(), hook_param->customDriverName.c_str());
|
|
||||||
return libdl_android_dlopen_ext(hook_param->customDriverName.c_str(), flags, &newExtinfo);
|
|
||||||
} else {
|
|
||||||
LOGI("android_dlopen_ext: loading default driver: %s", filename);
|
|
||||||
return libdl_android_dlopen_ext(filename, flags, &newExtinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void *android_load_sphal_library(const char *filename, int flags) {
|
|
||||||
// https://android.googlesource.com/platform/system/core/+/master/libvndksupport/linker.cpp
|
|
||||||
for (const char *name : {"sphal", "vendor", "default"}) {
|
|
||||||
if (auto vendorNs{android_get_exported_namespace(name)}) {
|
|
||||||
android_dlextinfo dlextinfo{
|
|
||||||
.flags = ANDROID_DLEXT_USE_NAMESPACE,
|
|
||||||
.library_namespace = vendorNs,
|
|
||||||
};
|
|
||||||
|
|
||||||
return android_dlopen_ext(filename, flags, &dlextinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue