/* * Copyright The async-profiler authors * SPDX-License-Identifier: Apache-2.0 */ #ifdef __linux__ #define EXT ".so" #else #define EXT ".dylib" #endif #include "codeCache.h" #include "profiler.h" #include "testRunner.hpp" #include const void* resolveSymbol(const char* lib, const char* name) { void* result = dlopen(lib, RTLD_NOW); if (!result) { printf("%s\n", dlerror()); return nullptr; } Profiler::instance()->updateSymbols(false); return Profiler::instance()->resolveSymbol(name); } #define ASSERT_RESOLVE(id) \ { \ void* result = dlopen("libreladyn" EXT, RTLD_NOW); /* see reladyn.c */ \ ASSERT(result); \ Profiler::instance()->updateSymbols(false); \ CodeCache* libreladyn = Profiler::instance()->findLibraryByName("libreladyn"); \ ASSERT(libreladyn); \ void* sym = libreladyn->findImport(id); \ ASSERT(sym); \ } TEST_CASE(ResolveFromRela_plt) { ASSERT_RESOLVE(im_pthread_create); } TEST_CASE(ResolveFromRela_dyn_R_GLOB_DAT) { ASSERT_RESOLVE(im_pthread_setspecific); } #ifdef __linux__ TEST_CASE(ResolveFromRela_dyn_R_ABS64) { ASSERT_RESOLVE(im_pthread_exit); } TEST_CASE(VirtAddrDifferentLoadAddr) { const void* sym = resolveSymbol("libvaddrdif" EXT, "vaddrdif_square"); ASSERT(sym); int (*square)(int) = (int (*)(int))sym; ASSERT_EQ(square(5), 25); } TEST_CASE(MappedTwiceAtZeroOffset) { const void* sym = resolveSymbol("libtwiceatzero" EXT, "twiceatzero_hello"); // Resolving the symbol without crashing is enough for this test case. ASSERT(sym); void (*hello)() = (void (*)())sym; hello(); } TEST_CASE(MultipleMatchingSymbols) { const void* sym = resolveSymbol("multiplematching" EXT, "Class::function"); ASSERT(sym); const void* sym_ok = resolveSymbol("multiplematching" EXT, "_ZN5Class8functionEv"); ASSERT_EQ(sym, sym_ok); const void* sym_cold = resolveSymbol("multiplematching" EXT, "_ZN5Class8functionEv.cold"); ASSERT_NE(sym, sym_cold); } #endif // __linux__