LLVM API Documentation
00001 //===-- Intercept.cpp - System function interception routines -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // If a function call occurs to an external function, the JIT is designed to use 00011 // the dynamic loader interface to find a function to call. This is useful for 00012 // calling system calls and library functions that are not available in LLVM. 00013 // Some system calls, however, need to be handled specially. For this reason, 00014 // we intercept some of them here and use our own stubs to handle them. 00015 // 00016 //===----------------------------------------------------------------------===// 00017 00018 #include "JIT.h" 00019 #include "llvm/System/DynamicLibrary.h" 00020 #include "llvm/Config/config.h" 00021 #include <iostream> 00022 using namespace llvm; 00023 00024 // AtExitHandlers - List of functions to call when the program exits, 00025 // registered with the atexit() library function. 00026 static std::vector<void (*)()> AtExitHandlers; 00027 00028 /// runAtExitHandlers - Run any functions registered by the program's 00029 /// calls to atexit(3), which we intercept and store in 00030 /// AtExitHandlers. 00031 /// 00032 static void runAtExitHandlers() { 00033 while (!AtExitHandlers.empty()) { 00034 void (*Fn)() = AtExitHandlers.back(); 00035 AtExitHandlers.pop_back(); 00036 Fn(); 00037 } 00038 } 00039 00040 //===----------------------------------------------------------------------===// 00041 // Function stubs that are invoked instead of certain library calls 00042 //===----------------------------------------------------------------------===// 00043 00044 // Force the following functions to be linked in to anything that uses the 00045 // JIT. This is a hack designed to work around the all-too-clever Glibc 00046 // strategy of making these functions work differently when inlined vs. when 00047 // not inlined, and hiding their real definitions in a separate archive file 00048 // that the dynamic linker can't see. For more info, search for 00049 // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. 00050 #if defined(__linux__) 00051 #if defined(HAVE_SYS_STAT_H) 00052 #include <sys/stat.h> 00053 #endif 00054 void *FunctionPointers[] = { 00055 (void *)(intptr_t) stat, 00056 (void *)(intptr_t) fstat, 00057 (void *)(intptr_t) lstat, 00058 (void *)(intptr_t) stat64, 00059 (void *)(intptr_t) fstat64, 00060 (void *)(intptr_t) lstat64, 00061 (void *)(intptr_t) atexit, 00062 (void *)(intptr_t) mknod 00063 }; 00064 #endif // __linux__ 00065 00066 // __mainFunc - If the program does not have a linked in __main function, allow 00067 // it to run, but print a warning. 00068 static void __mainFunc() { 00069 fprintf(stderr, "WARNING: Program called __main but was not linked to " 00070 "libcrtend.a.\nThis probably won't hurt anything unless the " 00071 "program is written in C++.\n"); 00072 } 00073 00074 // jit_exit - Used to intercept the "exit" library call. 00075 static void jit_exit(int Status) { 00076 runAtExitHandlers(); // Run atexit handlers... 00077 exit(Status); 00078 } 00079 00080 // jit_atexit - Used to intercept the "atexit" library call. 00081 static int jit_atexit(void (*Fn)(void)) { 00082 AtExitHandlers.push_back(Fn); // Take note of atexit handler... 00083 return 0; // Always successful 00084 } 00085 00086 //===----------------------------------------------------------------------===// 00087 // 00088 /// getPointerToNamedFunction - This method returns the address of the specified 00089 /// function by using the dynamic loader interface. As such it is only useful 00090 /// for resolving library symbols, not code generated symbols. 00091 /// 00092 void *JIT::getPointerToNamedFunction(const std::string &Name) { 00093 // Check to see if this is one of the functions we want to intercept. Note, 00094 // we cast to intptr_t here to silence a -pedantic warning that complains 00095 // about casting a function pointer to a normal pointer. 00096 if (Name == "exit") return (void*)(intptr_t)&jit_exit; 00097 if (Name == "atexit") return (void*)(intptr_t)&jit_atexit; 00098 00099 // If the program does not have a linked in __main function, allow it to run, 00100 // but print a warning. 00101 if (Name == "__main") return (void*)(intptr_t)&__mainFunc; 00102 00103 // If it's an external function, look it up in the process image... 00104 void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(Name); 00105 if (Ptr) return Ptr; 00106 00107 std::cerr << "ERROR: Program used external function '" << Name 00108 << "' which could not be resolved!\n"; 00109 abort(); 00110 return 0; 00111 }