1c1db8cf9SFrederich Munch//===- Unix/DynamicLibrary.cpp - Unix DL Implementation ---------*- C++ -*-===// 2c1db8cf9SFrederich Munch// 3*2946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c1db8cf9SFrederich Munch// 7c1db8cf9SFrederich Munch//===----------------------------------------------------------------------===// 8c1db8cf9SFrederich Munch// 9c1db8cf9SFrederich Munch// This file provides the UNIX specific implementation of DynamicLibrary. 10c1db8cf9SFrederich Munch// 11c1db8cf9SFrederich Munch//===----------------------------------------------------------------------===// 12c1db8cf9SFrederich Munch 13c1db8cf9SFrederich Munch#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN) 14c1db8cf9SFrederich Munch#include <dlfcn.h> 15c1db8cf9SFrederich Munch 16c1db8cf9SFrederich MunchDynamicLibrary::HandleSet::~HandleSet() { 17ad125800SFrederich Munch // Close the libraries in reverse order. 18ad125800SFrederich Munch for (void *Handle : llvm::reverse(Handles)) 19c1db8cf9SFrederich Munch ::dlclose(Handle); 20c1db8cf9SFrederich Munch if (Process) 21c1db8cf9SFrederich Munch ::dlclose(Process); 225fdd2cbaSFrederich Munch 235fdd2cbaSFrederich Munch // llvm_shutdown called, Return to default 245fdd2cbaSFrederich Munch DynamicLibrary::SearchOrder = DynamicLibrary::SO_Linker; 25c1db8cf9SFrederich Munch} 26c1db8cf9SFrederich Munch 27c1db8cf9SFrederich Munchvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 28c1db8cf9SFrederich Munch void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL); 29c1db8cf9SFrederich Munch if (!Handle) { 30c1db8cf9SFrederich Munch if (Err) *Err = ::dlerror(); 31c1db8cf9SFrederich Munch return &DynamicLibrary::Invalid; 32c1db8cf9SFrederich Munch } 33c1db8cf9SFrederich Munch 34c1db8cf9SFrederich Munch#ifdef __CYGWIN__ 35c1db8cf9SFrederich Munch // Cygwin searches symbols only in the main 36c1db8cf9SFrederich Munch // with the handle of dlopen(NULL, RTLD_GLOBAL). 378b66b00eSNuno Lopes if (!File) 38c1db8cf9SFrederich Munch Handle = RTLD_DEFAULT; 39c1db8cf9SFrederich Munch#endif 40c1db8cf9SFrederich Munch 41c1db8cf9SFrederich Munch return Handle; 42c1db8cf9SFrederich Munch} 43c1db8cf9SFrederich Munch 44c1db8cf9SFrederich Munchvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 45c1db8cf9SFrederich Munch ::dlclose(Handle); 46c1db8cf9SFrederich Munch} 47c1db8cf9SFrederich Munch 48c1db8cf9SFrederich Munchvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 49c1db8cf9SFrederich Munch return ::dlsym(Handle, Symbol); 50c1db8cf9SFrederich Munch} 51c1db8cf9SFrederich Munch 52c1db8cf9SFrederich Munch#else // !HAVE_DLOPEN 53c1db8cf9SFrederich Munch 54c1db8cf9SFrederich MunchDynamicLibrary::HandleSet::~HandleSet() {} 55c1db8cf9SFrederich Munch 56c1db8cf9SFrederich Munchvoid *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) { 57c1db8cf9SFrederich Munch if (Err) *Err = "dlopen() not supported on this platform"; 58c1db8cf9SFrederich Munch return &Invalid; 59c1db8cf9SFrederich Munch} 60c1db8cf9SFrederich Munch 61c1db8cf9SFrederich Munchvoid DynamicLibrary::HandleSet::DLClose(void *Handle) { 62c1db8cf9SFrederich Munch} 63c1db8cf9SFrederich Munch 64c1db8cf9SFrederich Munchvoid *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) { 65c1db8cf9SFrederich Munch return nullptr; 66c1db8cf9SFrederich Munch} 67c1db8cf9SFrederich Munch 68c1db8cf9SFrederich Munch#endif 69c1db8cf9SFrederich Munch 70c1db8cf9SFrederich Munch// Must declare the symbols in the global namespace. 71c1db8cf9SFrederich Munchstatic void *DoSearch(const char* SymbolName) { 72c1db8cf9SFrederich Munch#define EXPLICIT_SYMBOL(SYM) \ 731c43ad09SKeno Fischer extern void *SYM; if (!strcmp(SymbolName, #SYM)) return (void*)&SYM 74c1db8cf9SFrederich Munch 75c1db8cf9SFrederich Munch // If this is darwin, it has some funky issues, try to solve them here. Some 76c1db8cf9SFrederich Munch // important symbols are marked 'private external' which doesn't allow 77c1db8cf9SFrederich Munch // SearchForAddressOfSymbol to find them. As such, we special case them here, 78c1db8cf9SFrederich Munch // there is only a small handful of them. 79c1db8cf9SFrederich Munch 80c1db8cf9SFrederich Munch#ifdef __APPLE__ 81c1db8cf9SFrederich Munch { 82c1db8cf9SFrederich Munch // __eprintf is sometimes used for assert() handling on x86. 83c1db8cf9SFrederich Munch // 84c1db8cf9SFrederich Munch // FIXME: Currently disabled when using Clang, as we don't always have our 85c1db8cf9SFrederich Munch // runtime support libraries available. 86c1db8cf9SFrederich Munch#ifndef __clang__ 87c1db8cf9SFrederich Munch#ifdef __i386__ 88c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(__eprintf); 89c1db8cf9SFrederich Munch#endif 90c1db8cf9SFrederich Munch#endif 91c1db8cf9SFrederich Munch } 92c1db8cf9SFrederich Munch#endif 93c1db8cf9SFrederich Munch 94c1db8cf9SFrederich Munch#ifdef __CYGWIN__ 95c1db8cf9SFrederich Munch { 96c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(_alloca); 97c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(__main); 98c1db8cf9SFrederich Munch } 99c1db8cf9SFrederich Munch#endif 100c1db8cf9SFrederich Munch 101c1db8cf9SFrederich Munch#undef EXPLICIT_SYMBOL 102c1db8cf9SFrederich Munch 103c1db8cf9SFrederich Munch// This macro returns the address of a well-known, explicit symbol 104c1db8cf9SFrederich Munch#define EXPLICIT_SYMBOL(SYM) \ 105c1db8cf9SFrederich Munch if (!strcmp(SymbolName, #SYM)) return &SYM 106c1db8cf9SFrederich Munch 107f5d486f4SDimitry Andric// Under glibc we have a weird situation. The stderr/out/in symbols are both 108c1db8cf9SFrederich Munch// macros and global variables because of standards requirements. So, we 109c1db8cf9SFrederich Munch// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first. 110f5d486f4SDimitry Andric#if defined(__GLIBC__) 111c1db8cf9SFrederich Munch { 112c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stderr); 113c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stdout); 114c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stdin); 115c1db8cf9SFrederich Munch } 116c1db8cf9SFrederich Munch#else 117c1db8cf9SFrederich Munch // For everything else, we want to check to make sure the symbol isn't defined 118c1db8cf9SFrederich Munch // as a macro before using EXPLICIT_SYMBOL. 119c1db8cf9SFrederich Munch { 120c1db8cf9SFrederich Munch#ifndef stdin 121c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stdin); 122c1db8cf9SFrederich Munch#endif 123c1db8cf9SFrederich Munch#ifndef stdout 124c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stdout); 125c1db8cf9SFrederich Munch#endif 126c1db8cf9SFrederich Munch#ifndef stderr 127c1db8cf9SFrederich Munch EXPLICIT_SYMBOL(stderr); 128c1db8cf9SFrederich Munch#endif 129c1db8cf9SFrederich Munch } 130c1db8cf9SFrederich Munch#endif 131c1db8cf9SFrederich Munch#undef EXPLICIT_SYMBOL 132c1db8cf9SFrederich Munch 133c1db8cf9SFrederich Munch return nullptr; 134c1db8cf9SFrederich Munch} 135