aboutsummaryrefslogtreecommitdiff
path: root/lib/csu/common/crtbegin.c
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2018-10-25 17:39:41 +0000
committerAndrew Turner <andrew@FreeBSD.org>2018-10-25 17:39:41 +0000
commit31d62a73c2e6ac0ff413a7a17700ffc7dce254ef (patch)
tree8e38af4c0995bdf5f590fb13f735df0b9ff1a3d7 /lib/csu/common/crtbegin.c
parentad054101ebaa437404badd9cade3817a625f6a35 (diff)
downloadsrc-31d62a73c2e6ac0ff413a7a17700ffc7dce254ef.tar.gz
src-31d62a73c2e6ac0ff413a7a17700ffc7dce254ef.zip
Implement a BSD licensed crtbegin/crtend
These are needed for .ctors/.dtors and .jcr handling. The former needs all the function pointers to be called in the correct order from the .init/.fini section. The latter just needs to call a gcj specific function if it exists with a pointer to the start of the .jcr section. This is currently disabled until __dso_handle support is added. Reviewed by: emaste MFC after: 1 month Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D17587
Notes
Notes: svn path=/head/; revision=339738
Diffstat (limited to 'lib/csu/common/crtbegin.c')
-rw-r--r--lib/csu/common/crtbegin.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/csu/common/crtbegin.c b/lib/csu/common/crtbegin.c
new file mode 100644
index 000000000000..46e604927ac0
--- /dev/null
+++ b/lib/csu/common/crtbegin.c
@@ -0,0 +1,99 @@
+/*-
+ * SPDX-License-Identifier: BSD-1-Clause
+ *
+ * Copyright 2018 Andrew Turner
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include "crt.h"
+
+typedef void (*crt_func)(void);
+
+/*
+ * On some architectures and toolchains we may need to call the .dtors.
+ * These are called in the order they are in the ELF file.
+ */
+#ifdef HAVE_CTORS
+static void __do_global_dtors_aux(void) __used;
+
+crt_func __CTOR_LIST__[] __section(".ctors") __hidden = {
+ (crt_func)-1
+};
+crt_func __DTOR_LIST__[] __section(".dtors") __hidden = {
+ (crt_func)-1
+};
+
+static void
+__do_global_dtors_aux(void)
+{
+ crt_func fn;
+ int n;
+
+ for (n = 1;; n++) {
+ fn = __DTOR_LIST__[n];
+ if (fn == (crt_func)0 || fn == (crt_func)-1)
+ break;
+ fn();
+ }
+}
+
+asm (
+ ".pushsection .fini \n"
+ "\t" INIT_CALL_SEQ(__do_global_dtors_aux) "\n"
+ ".popsection \n"
+);
+#endif
+
+/*
+ * Handler for gcj. These provide a _Jv_RegisterClasses function and fill
+ * out the .jcr section. We just need to call this function with a pointer
+ * to the appropriate section.
+ */
+extern void _Jv_RegisterClasses(void *) __weak_symbol;
+static void register_classes(void) __used;
+
+crt_func __JCR_LIST__[] __section(".jcr") __used __hidden = { };
+
+#ifndef CTORS_CONSTRUCTORS
+__attribute__((constructor))
+#endif
+static void
+register_classes(void)
+{
+
+ if (_Jv_RegisterClasses != NULL && __JCR_LIST__[0] != 0)
+ _Jv_RegisterClasses(__JCR_LIST__);
+}
+
+/*
+ * We can't use constructors when they use the .ctors section as they may be
+ * placed before __CTOR_LIST__.
+ */
+#ifdef CTORS_CONSTRUCTORS
+asm (
+ ".pushsection .init \n"
+ "\t" INIT_CALL_SEQ(register_classes) "\n"
+ ".popsection \n"
+);
+#endif