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" 16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Compiler.h" 17a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/Support/DynamicLibrary.h" 18a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#include "llvm/Support/ErrorHandling.h" 19c93cdefa306f0ec265af031750148ed82b122150Michael J. Spencer#include <cstdlib> 20c93cdefa306f0ec265af031750148ed82b122150Michael J. Spencer 21a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#ifdef __linux__ 22a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // These includes used by RTDyldMemoryManager::getPointerToNamedFunction() 23a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // for Glibc trickery. See comments in this function for more information. 24a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #ifdef HAVE_SYS_STAT_H 25a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <sys/stat.h> 26a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #endif 27a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <fcntl.h> 28a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo #include <unistd.h> 29a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#endif 30a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 31a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlonamespace llvm { 32a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 33a4ea4a72031809911d77f543eb65175e00fe914eFilip PizloRTDyldMemoryManager::~RTDyldMemoryManager() {} 34a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 35a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo// Determine whether we can register EH tables. 3647c7eee5338f6d8c05f86838b6a2fe41c7c771deSylvestre Ledru#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \ 37dbb832b83351cec97b025b61c26536ef50c3181cBill Wendling !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) 38a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#define HAVE_EHTABLE_SUPPORT 1 39a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#else 40a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#define HAVE_EHTABLE_SUPPORT 0 41a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#endif 42a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 43a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo#if HAVE_EHTABLE_SUPPORT 44a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizloextern "C" void __register_frame(void*); 4543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorextern "C" void __deregister_frame(void*); 4643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#else 4743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// The building compiler does not have __(de)register_frame but 4843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// it may be found at runtime in a dynamically-loaded library. 4943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// For example, this happens when building LLVM with Visual C++ 5043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor// but using the MingW runtime. 5143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid __register_frame(void *p) { 5243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static bool Searched = false; 5343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static void *rf = 0; 5443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 5543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (!Searched) { 5643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Searched = true; 5743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor rf = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol( 5843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor "__register_frame"); 5943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } 6043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (rf) 6143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor ((void (*)(void *))rf)(p); 6243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 63a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 6443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid __deregister_frame(void *p) { 6543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static bool Searched = false; 6643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor static void *df = 0; 6743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 6843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (!Searched) { 6943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Searched = true; 7043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor df = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol( 7143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor "__deregister_frame"); 7243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } 7343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (df) 7443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor ((void (*)(void *))df)(p); 7543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 7643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#endif 7743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 7843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#ifdef __APPLE__ 7943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 8043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorstatic const char *processFDE(const char *Entry, bool isDeregister) { 81a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo const char *P = Entry; 82f102f31e15ac9c98f68aa1eaec82dffea966ad5eBenjamin Kramer uint32_t Length = *((const uint32_t *)P); 83a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo P += 4; 84f102f31e15ac9c98f68aa1eaec82dffea966ad5eBenjamin Kramer uint32_t Offset = *((const uint32_t *)P); 852369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper if (Offset != 0) { 862369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper if (isDeregister) 8743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __deregister_frame(const_cast<char *>(Entry)); 882369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper else 8943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __register_frame(const_cast<char *>(Entry)); 902369bf9ecf6f5ee1d06e44a4e9a7849060146f07Craig Topper } 91a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo return P + Length; 92a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 93a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 94528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// This implementation handles frame registration for local targets. 95528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// Memory managers for remote targets should re-implement this function 96528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor// and use the LoadAddr parameter. 97528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, 98528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor uint64_t LoadAddr, 99528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor size_t Size) { 10043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // On OS X OS X __register_frame takes a single FDE as an argument. 10143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // See http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/061768.html 102528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const char *P = (const char *)Addr; 103528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor const char *End = P + Size; 104a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo do { 10543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor P = processFDE(P, false); 106a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo } while(P != End); 107a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 108a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 10943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, 11043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 11143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 11243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor const char *P = (const char *)Addr; 11343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor const char *End = P + Size; 11443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor do { 11543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor P = processFDE(P, true); 11643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor } while(P != End); 11743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 11843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 11943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#else 12043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 12143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, 12243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 12343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 12443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // On Linux __register_frame takes a single argument: 12543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // a pointer to the start of the .eh_frame section. 12643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 12743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // How can it find the end? Because crtendS.o is linked 12843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor // in and it has an .eh_frame section with four zero chars. 12943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __register_frame(Addr); 13043507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 13143507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 13243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, 13343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor uint64_t LoadAddr, 13443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor size_t Size) { 13543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor __deregister_frame(Addr); 13643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 13743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 13843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor#endif 13943507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 140a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlostatic int jit_noop() { 141a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo return 0; 142a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 143a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 1441ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// ARM math functions are statically linked on Android from libgcc.a, but not 1451ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// available at runtime for dynamic linking. On Linux these are usually placed 1461ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// in libgcc_s.so so can be found by normal dynamic lookup. 1471ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__BIONIC__) && defined(__arm__) 1481ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// List of functions which are statically linked on Android and can be generated 1491ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// by LLVM. This is done as a nested macro which is used once to declare the 1501ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// imported functions with ARM_MATH_DECL and once to compare them to the 1511ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// user-requested symbol in getSymbolAddress with ARM_MATH_CHECK. The test 1521ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// assumes that all functions start with __aeabi_ and getSymbolAddress must be 1531ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// modified if that changes. 1541ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_IMPORTS(PP) \ 1551ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2f) \ 1561ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2iz) \ 1571ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2lz) \ 1581ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2uiz) \ 1591ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_d2ulz) \ 1601ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dadd) \ 1611ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpeq) \ 1621ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpge) \ 1631ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpgt) \ 1641ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmple) \ 1651ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmplt) \ 1661ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dcmpun) \ 1671ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ddiv) \ 1681ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dmul) \ 1691ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_dsub) \ 1701ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2d) \ 1711ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2iz) \ 1721ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2lz) \ 1731ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2uiz) \ 1741ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_f2ulz) \ 1751ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fadd) \ 1761ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpeq) \ 1771ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpge) \ 1781ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpgt) \ 1791ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmple) \ 1801ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmplt) \ 1811ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fcmpun) \ 1821ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fdiv) \ 1831ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fmul) \ 1841ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_fsub) \ 1851ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_i2d) \ 1861ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_i2f) \ 1871ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_idiv) \ 1881ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_idivmod) \ 1891ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_l2d) \ 1901ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_l2f) \ 1911ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_lasr) \ 1921ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ldivmod) \ 1931ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_llsl) \ 1941ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_llsr) \ 1951ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_lmul) \ 1961ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ui2d) \ 1971ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ui2f) \ 1981ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uidiv) \ 1991ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uidivmod) \ 2001ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ul2d) \ 2011ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_ul2f) \ 2021ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor PP(__aeabi_uldivmod) 2031ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 2041ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// Declare statically linked math functions on ARM. The function declarations 2051ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// here do not have the correct prototypes for each function in 2061ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// ARM_MATH_IMPORTS, but it doesn't matter because only the symbol addresses are 2071ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// needed. In particular the __aeabi_*divmod functions do not have calling 2081ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor// conventions which match any C prototype. 2091ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_DECL(name) extern "C" void name(); 2101ab6084c9e785415da3a48083d53b25a38f0fb48Andrew KaylorARM_MATH_IMPORTS(ARM_MATH_DECL) 2111ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#undef ARM_MATH_DECL 2121ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif 2131ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#if defined(__linux__) && defined(__GLIBC__) && \ 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (defined(__i386__) || defined(__x86_64__)) 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesextern "C" LLVM_ATTRIBUTE_WEAK void __morestack(); 217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif 218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesuint64_t 22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesRTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) { 2218e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // This implementation assumes that the host program is the target. 2228e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // Clients generating code for a remote target should implement their own 2238e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // memory manager. 2241ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__linux__) && defined(__GLIBC__) 225a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo //===--------------------------------------------------------------------===// 226a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // Function stubs that are invoked instead of certain library calls 227a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // 228a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // Force the following functions to be linked in to anything that uses the 229a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // JIT. This is a hack designed to work around the all-too-clever Glibc 230a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // strategy of making these functions work differently when inlined vs. when 231a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // not inlined, and hiding their real definitions in a separate archive file 232a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // that the dynamic linker can't see. For more info, search for 233a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. 2348e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "stat") return (uint64_t)&stat; 2358e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "fstat") return (uint64_t)&fstat; 2368e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "lstat") return (uint64_t)&lstat; 2378e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "stat64") return (uint64_t)&stat64; 2388e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "fstat64") return (uint64_t)&fstat64; 2398e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "lstat64") return (uint64_t)&lstat64; 2408e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "atexit") return (uint64_t)&atexit; 2418e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "mknod") return (uint64_t)&mknod; 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#if defined(__i386__) || defined(__x86_64__) 244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // __morestack lives in libgcc, a static library. 245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (&__morestack && Name == "__morestack") 246ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return (uint64_t)&__morestack; 247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#endif 2481ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif // __linux__ && __GLIBC__ 2491ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor 2501ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // See ARM_MATH_IMPORTS definition for explanation 2511ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#if defined(__BIONIC__) && defined(__arm__) 2521ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor if (Name.compare(0, 8, "__aeabi_") == 0) { 2531ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // Check if the user has requested any of the functions listed in 2541ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor // ARM_MATH_IMPORTS, and if so redirect to the statically linked symbol. 2551ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#define ARM_MATH_CHECK(fn) if (Name == #fn) return (uint64_t)&fn; 2561ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor ARM_MATH_IMPORTS(ARM_MATH_CHECK) 2571ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#undef ARM_MATH_CHECK 2581ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor } 2591ab6084c9e785415da3a48083d53b25a38f0fb48Andrew Kaylor#endif 260a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 261a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // We should not invoke parent's ctors/dtors from generated main()! 262a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // On Mingw and Cygwin, the symbol __main is resolved to 263a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors 264a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // (and register wrong callee's dtors with atexit(3)). 265a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // We expect ExecutionEngine::runStaticConstructorsDestructors() 266a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo // is called before ExecutionEngine::runFunctionAsMain() is called. 2678e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name == "__main") return (uint64_t)&jit_noop; 268a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Try to demangle Name before looking it up in the process, otherwise symbol 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // '_<Name>' (if present) will shadow '<Name>', and there will be no way to 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // refer to the latter. 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 273a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo const char *NameStr = Name.c_str(); 274a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (NameStr[0] == '_') 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr + 1)) 2778e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return (uint64_t)Ptr; 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // If we Name did not require demangling, or we failed to find the demangled 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // name, try again without demangling. 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return (uint64_t)sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); 2828e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor} 283a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 2848e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name, 2858e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor bool AbortOnFailure) { 2868e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor uint64_t Addr = getSymbolAddress(Name); 2878e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 2888e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (!Addr && AbortOnFailure) 289a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo report_fatal_error("Program used external function '" + Name + 290a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo "' which could not be resolved!"); 2918e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return (void*)Addr; 292a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} 293a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo 294a4ea4a72031809911d77f543eb65175e00fe914eFilip Pizlo} // namespace llvm 295