From fdab72830183821c06ee87d4836e9a9b45bc8dcb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 14 May 2003 13:09:41 +0000 Subject: [PATCH 1/1] Initial checkin of crtend.o implementation git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6187 91177308-0d34-0410-b5e6-96231b3b80d8 --- runtime/GCCLibraries/crtend/Makefile | 9 +++++ runtime/GCCLibraries/crtend/crtend.c | 52 ++++++++++++++++++++++++++ runtime/GCCLibraries/crtend/listend.ll | 25 ++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 runtime/GCCLibraries/crtend/Makefile create mode 100644 runtime/GCCLibraries/crtend/crtend.c diff --git a/runtime/GCCLibraries/crtend/Makefile b/runtime/GCCLibraries/crtend/Makefile new file mode 100644 index 00000000000..049e35c8631 --- /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 00000000000..69eac4ff988 --- /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 + +/* 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 2a334999e25..3614bab7683 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) +} -- 2.34.1