aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-05-14 13:09:41 +0000
committerChris Lattner <sabre@nondot.org>2003-05-14 13:09:41 +0000
commitfdab72830183821c06ee87d4836e9a9b45bc8dcb (patch)
treee3bbbe98724e08a29ed71954adea1b5693869e7a /runtime
parentaa470c2d4780f4b1bd222f439303de12f14631ae (diff)
Initial checkin of crtend.o implementation
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6187 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'runtime')
-rw-r--r--runtime/GCCLibraries/crtend/Makefile9
-rw-r--r--runtime/GCCLibraries/crtend/crtend.c52
-rw-r--r--runtime/GCCLibraries/crtend/listend.ll25
3 files changed, 84 insertions, 2 deletions
diff --git a/runtime/GCCLibraries/crtend/Makefile b/runtime/GCCLibraries/crtend/Makefile
new file mode 100644
index 0000000000..049e35c863
--- /dev/null
+++ b/runtime/GCCLibraries/crtend/Makefile
@@ -0,0 +1,9 @@
+LEVEL = ../../..
+LIBNAME = crtend
+Source = crtend.c listend.ll
+
+include ../Makefile.libs
+
+install:: $(DESTLIBNAME)
+ cp $(DESTLIBNAME) $(INSTALL_DIR)/crtend.o
+ rm $(INSTALL_DIR)/libcrtend.bc
diff --git a/runtime/GCCLibraries/crtend/crtend.c b/runtime/GCCLibraries/crtend/crtend.c
new file mode 100644
index 0000000000..69eac4ff98
--- /dev/null
+++ b/runtime/GCCLibraries/crtend/crtend.c
@@ -0,0 +1,52 @@
+/*===- crtend.c - Initialization code for programs ------------------------===*\
+ *
+ * This file defines the __main function, which is used to run static
+ * constructors and destructors in C++ programs, or with C programs that use GCC
+ * extensions to accomplish the same effect.
+ *
+ * The main data structures used to implement this functionality is the
+ * llvm.global_ctors and llvm.global_dtors lists, which are null terminated
+ * lists of TorRec (defined below) structures.
+ *
+\*===----------------------------------------------------------------------===*/
+
+#include <stdlib.h>
+
+/* TorRec - The record type for each element of the ctor/dtor list */
+typedef struct TorRec {
+ int Priority;
+ void (*FP)(void);
+} TorRec;
+
+/* __llvm_getGlobalCtors, __llvm_getGlobalDtors - Interface to the LLVM
+ * listend.ll file to get access to the start of the ctor and dtor lists...
+ */
+TorRec *__llvm_getGlobalCtors(void);
+TorRec *__llvm_getGlobalDtors(void);
+
+static void run_destructors(void);
+
+/* __main - A call to this function is automatically inserted into the top of
+ * the "main" function in the program compiled. This function is responsible
+ * for calling static constructors before the program starts executing.
+ */
+void __main(void) {
+ /* Loop over all of the constructor records, calling each function pointer. */
+ TorRec *R = __llvm_getGlobalCtors();
+
+ if (atexit(run_destructors))
+ abort(); /* Should be able to install ONE atexit handler! */
+
+ /* FIXME: This should sort the list by priority! */
+ for (; R->FP; ++R)
+ R->FP();
+}
+
+static void run_destructors(void) {
+ /* Loop over all of the destructor records, calling each function pointer. */
+ TorRec *R = __llvm_getGlobalDtors();
+
+ /* FIXME: This should sort the list by priority! */
+ for (; R->FP; ++R)
+ R->FP();
+}
diff --git a/runtime/GCCLibraries/crtend/listend.ll b/runtime/GCCLibraries/crtend/listend.ll
index 2a334999e2..3614bab768 100644
--- a/runtime/GCCLibraries/crtend/listend.ll
+++ b/runtime/GCCLibraries/crtend/listend.ll
@@ -1,5 +1,26 @@
; global_ctors/global_dtors terminator: this is used to add a terminating null
; value to the initialization list.
-%llvm.global_ctors = appending global [1 x { int, void ()* }] [ { int, void ()* } { int 2147483647, void ()* null } ]
-%llvm.global_ctors = appending global [1 x { int, void ()* }] [ { int, void ()* } { int 2147483647, void ()* null } ]
+target endian = little
+target pointersize = 32
+
+%struct.TorRec = type { int, void ()* }
+
+%llvm.global_ctors = appending global [1 x %struct.TorRec] [
+ %struct.TorRec { int 2147483647, void ()* null }
+ ]
+
+%llvm.global_dtors = appending global [1 x %struct.TorRec] [
+ %struct.TorRec { int 2147483647, void ()* null }
+ ]
+
+implementation
+
+%struct.TorRec* %__llvm_getGlobalCtors() {
+ ret %struct.TorRec* getelementptr ([1 x %struct.TorRec]* %llvm.global_ctors,
+ long 0, long 0)
+}
+%struct.TorRec* %__llvm_getGlobalDtors() {
+ ret %struct.TorRec* getelementptr ([1 x %struct.TorRec]* %llvm.global_dtors,
+ long 0, long 0)
+}