blob: 74e7831deeb7d00f8edfe3f92833db9e5226a8d6 [file] [log] [blame]
Chris Lattner65637682003-05-14 13:09:41 +00001/*===- crtend.c - Initialization code for programs ------------------------===*\
Chris Lattner0f2aeea2004-08-05 00:20:51 +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 Lattner65637682003-05-14 13:09:41 +00009 *
10 * This file defines the __main function, which is used to run static
11 * constructors and destructors in C++ programs, or with C programs that use GCC
12 * extensions to accomplish the same effect.
13 *
14 * The main data structures used to implement this functionality is the
15 * llvm.global_ctors and llvm.global_dtors lists, which are null terminated
16 * lists of TorRec (defined below) structures.
17 *
18\*===----------------------------------------------------------------------===*/
19
20#include <stdlib.h>
21
22/* TorRec - The record type for each element of the ctor/dtor list */
23typedef struct TorRec {
24 int Priority;
25 void (*FP)(void);
26} TorRec;
27
28/* __llvm_getGlobalCtors, __llvm_getGlobalDtors - Interface to the LLVM
29 * listend.ll file to get access to the start of the ctor and dtor lists...
30 */
31TorRec *__llvm_getGlobalCtors(void);
32TorRec *__llvm_getGlobalDtors(void);
33
34static void run_destructors(void);
35
36/* __main - A call to this function is automatically inserted into the top of
37 * the "main" function in the program compiled. This function is responsible
38 * for calling static constructors before the program starts executing.
39 */
40void __main(void) {
41 /* Loop over all of the constructor records, calling each function pointer. */
42 TorRec *R = __llvm_getGlobalCtors();
43
Chris Lattner86dd6d82003-12-19 07:51:46 +000044 /* Recursively calling main is not legal C, but lots of people do it for
45 * testing stuff. We might as well work for them.
46 */
47 static _Bool Initialized = 0;
48 if (Initialized) return;
49 Initialized = 1;
50
Chris Lattner0fe5e452003-06-26 04:20:38 +000051 /* Only register the global dtor handler if there is at least one global
52 * dtor!
53 */
54 if (__llvm_getGlobalDtors()[0].FP)
55 if (atexit(run_destructors))
56 abort(); /* Should be able to install ONE atexit handler! */
Chris Lattner65637682003-05-14 13:09:41 +000057
58 /* FIXME: This should sort the list by priority! */
Chris Lattner2b6d3c82004-02-17 18:45:06 +000059 if (R->FP)
60 for (; R->FP; ++R)
61 R->FP();
Chris Lattner65637682003-05-14 13:09:41 +000062}
63
64static void run_destructors(void) {
65 /* Loop over all of the destructor records, calling each function pointer. */
66 TorRec *R = __llvm_getGlobalDtors();
67
68 /* FIXME: This should sort the list by priority! */
69 for (; R->FP; ++R)
70 R->FP();
71}