1a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo//===-- RTDyldMemoryManager.cpp - Memory manager for MC-JIT -----*- C++ -*-===// 2a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// 3a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// The LLVM Compiler Infrastructure 4a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// 5a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// This file is distributed under the University of Illinois Open Source 6a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// License. See LICENSE.TXT for details. 7a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// 8a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo//===----------------------------------------------------------------------===// 9a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// 10a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// Implementation of the runtime dynamic memory manager base class. 11a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// 12a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo//===----------------------------------------------------------------------===// 13a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 14a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/Config/config.h" 15a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 16a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/Support/DynamicLibrary.h" 17a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/Support/ErrorHandling.h" 18c93cdefa306f0ec265af031750148ed82b122150Michael J. Spencer#include <cstdlib> 19c93cdefa306f0ec265af031750148ed82b122150Michael J. Spencer 20a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#ifdef __linux__ 21a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // These includes used by RTDyldMemoryManager::getPointerToNamedFunction() 22a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // for Glibc trickery. See comments in this function for more information. 23a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #ifdef HAVE_SYS_STAT_H 24a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <sys/stat.h> 25a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #endif 26a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <fcntl.h> 27a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <unistd.h> 28a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#endif 29a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 30a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlonamespace llvm { 31a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 32a4ea4a72031809911d77f543eb65175e00fe914eFilip PizloRTDyldMemoryManager::~RTDyldMemoryManager() {} 33a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 34a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// Determine whether we can register EH tables. 3547c7eee5338f6d8c05f86838b6a2fe41c7c771deSylvestre Ledru#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \ 36dbb832b83351cec97b025b61c26536ef50c3181cBill Wendling !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) 37a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#define HAVE_EHTABLE_SUPPORT 1 38a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#else 39a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#define HAVE_EHTABLE_SUPPORT 0 40a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#endif 41a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 42a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#if HAVE_EHTABLE_SUPPORT 43a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizloextern "C" void __register_frame(void*); 4443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorextern "C" void __deregister_frame(void*); 4543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#else 4643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// The building compiler does not have __(de)register_frame but 4743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// it may be found at runtime in a dynamically-loaded library. 4843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// For example, this happens when building LLVM with Visual C++ 4943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// but using the MingW runtime. 5043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid __register_frame(void *p) { 5143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static bool Searched = false; 5243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static void *rf = 0; 5343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 5443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (!Searched) { 5543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Searched = true; 5643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor rf = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol( 5743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor "__register_frame"); 5843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } 5943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (rf) 6043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor ((void (*)(void *))rf)(p); 6143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 62a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 6343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid __deregister_frame(void *p) { 6443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static bool Searched = false; 6543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static void *df = 0; 6643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 6743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (!Searched) { 6843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Searched = true; 6943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor df = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol( 7043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor "__deregister_frame"); 7143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } 7243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (df) 7343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor ((void (*)(void *))df)(p); 7443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 7543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#endif 7643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 7743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#ifdef __APPLE__ 7843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 7943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorstatic const char *processFDE(const char *Entry, bool isDeregister) { 80a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo const char *P = Entry; 81f102f31e15ac9c98f68aa1eaec82dffea966ad5eBenjamin Kramer uint32_t Length = *((const uint32_t *)P); 82a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo P += 4; 83f102f31e15ac9c98f68aa1eaec82dffea966ad5eBenjamin Kramer uint32_t Offset = *((const uint32_t *)P); 842369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper if (Offset != 0) { 852369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper if (isDeregister) 8643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __deregister_frame(const_cast<char *>(Entry)); 872369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper else 8843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __register_frame(const_cast<char *>(Entry)); 892369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper } 90a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo return P + Length; 91a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 92a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 93528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// This implementation handles frame registration for local targets. 94528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// Memory managers for remote targets should re-implement this function 95528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// and use the LoadAddr parameter. 96528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, 97528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor uint64_t LoadAddr, 98528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor size_t Size) { 9943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // On OS X OS X __register_frame takes a single FDE as an argument. 10043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // See http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/061768.html 101528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const char *P = (const char *)Addr; 102528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const char *End = P + Size; 103a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo do { 10443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor P = processFDE(P, false); 105a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo } while(P != End); 106a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 107a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 10843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, 10943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 11043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 11143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor const char *P = (const char *)Addr; 11243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor const char *End = P + Size; 11343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor do { 11443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor P = processFDE(P, true); 11543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } while(P != End); 11643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 11743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 11843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#else 11943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 12043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, 12143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 12243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 12343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // On Linux __register_frame takes a single argument: 12443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // a pointer to the start of the .eh_frame section. 12543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 12643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // How can it find the end? Because crtendS.o is linked 12743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // in and it has an .eh_frame section with four zero chars. 12843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __register_frame(Addr); 12943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 13043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 13143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, 13243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 13343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 13443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __deregister_frame(Addr); 13543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 13643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 13743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#endif 13843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 139a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlostatic int jit_noop() { 140a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo return 0; 141a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 142a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 1431ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// ARM math functions are statically linked on Android from libgcc.a, but not 1441ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// available at runtime for dynamic linking. On Linux these are usually placed 1451ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// in libgcc_s.so so can be found by normal dynamic lookup. 1461ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__BIONIC__) && defined(__arm__) 1471ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// List of functions which are statically linked on Android and can be generated 1481ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// by LLVM. This is done as a nested macro which is used once to declare the 1491ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// imported functions with ARM_MATH_DECL and once to compare them to the 1501ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// user-requested symbol in getSymbolAddress with ARM_MATH_CHECK. The test 1511ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// assumes that all functions start with __aeabi_ and getSymbolAddress must be 1521ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// modified if that changes. 1531ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_IMPORTS(PP) \ 1541ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2f) \ 1551ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2iz) \ 1561ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2lz) \ 1571ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2uiz) \ 1581ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2ulz) \ 1591ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dadd) \ 1601ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpeq) \ 1611ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpge) \ 1621ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpgt) \ 1631ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmple) \ 1641ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmplt) \ 1651ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpun) \ 1661ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ddiv) \ 1671ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dmul) \ 1681ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dsub) \ 1691ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2d) \ 1701ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2iz) \ 1711ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2lz) \ 1721ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2uiz) \ 1731ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2ulz) \ 1741ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fadd) \ 1751ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpeq) \ 1761ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpge) \ 1771ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpgt) \ 1781ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmple) \ 1791ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmplt) \ 1801ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpun) \ 1811ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fdiv) \ 1821ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fmul) \ 1831ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fsub) \ 1841ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_i2d) \ 1851ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_i2f) \ 1861ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_idiv) \ 1871ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_idivmod) \ 1881ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_l2d) \ 1891ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_l2f) \ 1901ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_lasr) \ 1911ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ldivmod) \ 1921ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_llsl) \ 1931ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_llsr) \ 1941ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_lmul) \ 1951ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ui2d) \ 1961ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ui2f) \ 1971ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uidiv) \ 1981ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uidivmod) \ 1991ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ul2d) \ 2001ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ul2f) \ 2011ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uldivmod) 2021ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 2031ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// Declare statically linked math functions on ARM. The function declarations 2041ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// here do not have the correct prototypes for each function in 2051ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// ARM_MATH_IMPORTS, but it doesn't matter because only the symbol addresses are 2061ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// needed. In particular the __aeabi_*divmod functions do not have calling 2071ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// conventions which match any C prototype. 2081ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_DECL(name) extern "C" void name(); 2091ab6084c9e785415da3a48083d53b25a38f0fb48Andrew KaylorARM_MATH_IMPORTS(ARM_MATH_DECL) 2101ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#undef ARM_MATH_DECL 2111ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif 2121ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 2138e9ec015348c5419b905c2ca6e39534429eda073Andrew Kayloruint64_t RTDyldMemoryManager::getSymbolAddress(const std::string &Name) { 2148e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // This implementation assumes that the host program is the target. 2158e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // Clients generating code for a remote target should implement their own 2168e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // memory manager. 2171ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__linux__) && defined(__GLIBC__) 218a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo //===--------------------------------------------------------------------===// 219a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // Function stubs that are invoked instead of certain library calls 220a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // 221a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // Force the following functions to be linked in to anything that uses the 222a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // JIT. This is a hack designed to work around the all-too-clever Glibc 223a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // strategy of making these functions work differently when inlined vs. when 224a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // not inlined, and hiding their real definitions in a separate archive file 225a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // that the dynamic linker can't see. For more info, search for 226a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. 2278e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "stat") return (uint64_t)&stat; 2288e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "fstat") return (uint64_t)&fstat; 2298e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "lstat") return (uint64_t)&lstat; 2308e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "stat64") return (uint64_t)&stat64; 2318e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "fstat64") return (uint64_t)&fstat64; 2328e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "lstat64") return (uint64_t)&lstat64; 2338e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "atexit") return (uint64_t)&atexit; 2348e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "mknod") return (uint64_t)&mknod; 2351ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif // __linux__ && __GLIBC__ 2361ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 2371ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // See ARM_MATH_IMPORTS definition for explanation 2381ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__BIONIC__) && defined(__arm__) 2391ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor if (Name.compare(0, 8, "__aeabi_") == 0) { 2401ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // Check if the user has requested any of the functions listed in 2411ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // ARM_MATH_IMPORTS, and if so redirect to the statically linked symbol. 2421ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_CHECK(fn) if (Name == #fn) return (uint64_t)&fn; 2431ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor ARM_MATH_IMPORTS(ARM_MATH_CHECK) 2441ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#undef ARM_MATH_CHECK 2451ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor } 2461ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif 247a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 248a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // We should not invoke parent's ctors/dtors from generated main()! 249a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // On Mingw and Cygwin, the symbol __main is resolved to 250a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors 251a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // (and register wrong callee's dtors with atexit(3)). 252a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // We expect ExecutionEngine::runStaticConstructorsDestructors() 253a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // is called before ExecutionEngine::runFunctionAsMain() is called. 2548e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "__main") return (uint64_t)&jit_noop; 255a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 256a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo const char *NameStr = Name.c_str(); 257a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); 2588e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Ptr) 2598e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return (uint64_t)Ptr; 260a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 261a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // If it wasn't found and if it starts with an underscore ('_') character, 262a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // try again without the underscore. 263a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo if (NameStr[0] == '_') { 264a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); 2658e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Ptr) 2668e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return (uint64_t)Ptr; 267a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo } 2688e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return 0; 2698e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor} 270a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 2718e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name, 2728e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor bool AbortOnFailure) { 2738e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor uint64_t Addr = getSymbolAddress(Name); 2748e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 2758e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (!Addr && AbortOnFailure) 276a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo report_fatal_error("Program used external function '" + Name + 277a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo "' which could not be resolved!"); 2788e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return (void*)Addr; 279a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 280a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 281a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} // namespace llvm 282