blob: 6162e938aba717c56bdbcf7322823ce6f89b5995 [file] [log] [blame]
Chris Lattner5a9ea752003-05-14 13:26:47 +00001//===-- Intercept.cpp - System function interception routines -------------===//
John Criswell482202a2003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner5a9ea752003-05-14 13:26:47 +00009//
10// If a function call occurs to an external function, the JIT is designed to use
Brian Gaekee8bbcfc2003-10-10 17:02:42 +000011// the dynamic loader interface to find a function to call. This is useful for
Chris Lattner5a9ea752003-05-14 13:26:47 +000012// calling system calls and library functions that are not available in LLVM.
13// Some system calls, however, need to be handled specially. For this reason,
14// we intercept some of them here and use our own stubs to handle them.
15//
16//===----------------------------------------------------------------------===//
17
18#include "VM.h"
Brian Gaekee8bbcfc2003-10-10 17:02:42 +000019#include "Support/DynamicLinker.h"
Chris Lattnerc67e3402003-05-14 13:27:36 +000020#include <iostream>
Chris Lattner5a9ea752003-05-14 13:26:47 +000021
Brian Gaekea7669032003-09-05 18:42:01 +000022// AtExitHandlers - List of functions to call when the program exits,
23// registered with the atexit() library function.
24static std::vector<void (*)()> AtExitHandlers;
Chris Lattner2537ca32003-05-14 13:53:40 +000025
Brian Gaekea7669032003-09-05 18:42:01 +000026/// runAtExitHandlers - Run any functions registered by the program's
27/// calls to atexit(3), which we intercept and store in
28/// AtExitHandlers.
29///
Chris Lattner2537ca32003-05-14 13:53:40 +000030void VM::runAtExitHandlers() {
Brian Gaekea7669032003-09-05 18:42:01 +000031 while (!AtExitHandlers.empty()) {
32 void (*Fn)() = AtExitHandlers.back();
33 AtExitHandlers.pop_back();
Chris Lattner2537ca32003-05-14 13:53:40 +000034 Fn();
35 }
36}
37
Chris Lattner5a9ea752003-05-14 13:26:47 +000038//===----------------------------------------------------------------------===//
Brian Gaekea7669032003-09-05 18:42:01 +000039// Function stubs that are invoked instead of certain library calls
Chris Lattner5a9ea752003-05-14 13:26:47 +000040//===----------------------------------------------------------------------===//
41
42// NoopFn - Used if we have nothing else to call...
43static void NoopFn() {}
44
Brian Gaekea7669032003-09-05 18:42:01 +000045// jit_exit - Used to intercept the "exit" library call.
Chris Lattner5a9ea752003-05-14 13:26:47 +000046static void jit_exit(int Status) {
Brian Gaekea7669032003-09-05 18:42:01 +000047 VM::runAtExitHandlers(); // Run atexit handlers...
Chris Lattner2537ca32003-05-14 13:53:40 +000048 exit(Status);
Chris Lattner5a9ea752003-05-14 13:26:47 +000049}
50
Brian Gaekea7669032003-09-05 18:42:01 +000051// jit_atexit - Used to intercept the "atexit" library call.
Chris Lattner5a9ea752003-05-14 13:26:47 +000052static int jit_atexit(void (*Fn)(void)) {
Brian Gaekea7669032003-09-05 18:42:01 +000053 AtExitHandlers.push_back(Fn); // Take note of atexit handler...
Chris Lattner2537ca32003-05-14 13:53:40 +000054 return 0; // Always successful
Chris Lattner5a9ea752003-05-14 13:26:47 +000055}
56
57//===----------------------------------------------------------------------===//
58//
59/// getPointerToNamedFunction - This method returns the address of the specified
Brian Gaekee8bbcfc2003-10-10 17:02:42 +000060/// function by using the dynamic loader interface. As such it is only useful
61/// for resolving library symbols, not code generated symbols.
Chris Lattner5a9ea752003-05-14 13:26:47 +000062///
63void *VM::getPointerToNamedFunction(const std::string &Name) {
64 // Check to see if this is one of the functions we want to intercept...
Chris Lattnerc67e3402003-05-14 13:27:36 +000065 if (Name == "exit") return (void*)&jit_exit;
Chris Lattner2537ca32003-05-14 13:53:40 +000066 if (Name == "atexit") return (void*)&jit_atexit;
Chris Lattner5a9ea752003-05-14 13:26:47 +000067
68 // If it's an external function, look it up in the process image...
Brian Gaekee8bbcfc2003-10-10 17:02:42 +000069 void *Ptr = GetAddressOfSymbol(Name);
Chris Lattner5a9ea752003-05-14 13:26:47 +000070 if (Ptr == 0) {
71 std::cerr << "WARNING: Cannot resolve fn '" << Name
72 << "' using a dummy noop function instead!\n";
73 Ptr = (void*)NoopFn;
74 }
75
76 return Ptr;
77}