Chris Lattner | fdab728 | 2003-05-14 13:09:41 +0000 | [diff] [blame^] | 1 | /*===- crtend.c - Initialization code for programs ------------------------===*\ |
| 2 | * |
| 3 | * This file defines the __main function, which is used to run static |
| 4 | * constructors and destructors in C++ programs, or with C programs that use GCC |
| 5 | * extensions to accomplish the same effect. |
| 6 | * |
| 7 | * The main data structures used to implement this functionality is the |
| 8 | * llvm.global_ctors and llvm.global_dtors lists, which are null terminated |
| 9 | * lists of TorRec (defined below) structures. |
| 10 | * |
| 11 | \*===----------------------------------------------------------------------===*/ |
| 12 | |
| 13 | #include <stdlib.h> |
| 14 | |
| 15 | /* TorRec - The record type for each element of the ctor/dtor list */ |
| 16 | typedef struct TorRec { |
| 17 | int Priority; |
| 18 | void (*FP)(void); |
| 19 | } TorRec; |
| 20 | |
| 21 | /* __llvm_getGlobalCtors, __llvm_getGlobalDtors - Interface to the LLVM |
| 22 | * listend.ll file to get access to the start of the ctor and dtor lists... |
| 23 | */ |
| 24 | TorRec *__llvm_getGlobalCtors(void); |
| 25 | TorRec *__llvm_getGlobalDtors(void); |
| 26 | |
| 27 | static void run_destructors(void); |
| 28 | |
| 29 | /* __main - A call to this function is automatically inserted into the top of |
| 30 | * the "main" function in the program compiled. This function is responsible |
| 31 | * for calling static constructors before the program starts executing. |
| 32 | */ |
| 33 | void __main(void) { |
| 34 | /* Loop over all of the constructor records, calling each function pointer. */ |
| 35 | TorRec *R = __llvm_getGlobalCtors(); |
| 36 | |
| 37 | if (atexit(run_destructors)) |
| 38 | abort(); /* Should be able to install ONE atexit handler! */ |
| 39 | |
| 40 | /* FIXME: This should sort the list by priority! */ |
| 41 | for (; R->FP; ++R) |
| 42 | R->FP(); |
| 43 | } |
| 44 | |
| 45 | static void run_destructors(void) { |
| 46 | /* Loop over all of the destructor records, calling each function pointer. */ |
| 47 | TorRec *R = __llvm_getGlobalDtors(); |
| 48 | |
| 49 | /* FIXME: This should sort the list by priority! */ |
| 50 | for (; R->FP; ++R) |
| 51 | R->FP(); |
| 52 | } |