xref: /dflybsd-src/lib/csu/x86_64/crt1.c (revision 9189eb5eb09dde1734a2d828c3b5f97cd105fd46)
1b2b3ffcdSSimon Schubert /*-
2b2b3ffcdSSimon Schubert  * Copyright 1996-1998 John D. Polstra.
3b2b3ffcdSSimon Schubert  * All rights reserved.
4b2b3ffcdSSimon Schubert  *
5b2b3ffcdSSimon Schubert  * Redistribution and use in source and binary forms, with or without
6b2b3ffcdSSimon Schubert  * modification, are permitted provided that the following conditions
7b2b3ffcdSSimon Schubert  * are met:
8b2b3ffcdSSimon Schubert  * 1. Redistributions of source code must retain the above copyright
9b2b3ffcdSSimon Schubert  *    notice, this list of conditions and the following disclaimer.
10b2b3ffcdSSimon Schubert  * 2. Redistributions in binary form must reproduce the above copyright
11b2b3ffcdSSimon Schubert  *    notice, this list of conditions and the following disclaimer in the
12b2b3ffcdSSimon Schubert  *    documentation and/or other materials provided with the distribution.
13b2b3ffcdSSimon Schubert  *
14b2b3ffcdSSimon Schubert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15b2b3ffcdSSimon Schubert  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16b2b3ffcdSSimon Schubert  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17b2b3ffcdSSimon Schubert  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18b2b3ffcdSSimon Schubert  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19b2b3ffcdSSimon Schubert  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20b2b3ffcdSSimon Schubert  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21b2b3ffcdSSimon Schubert  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22b2b3ffcdSSimon Schubert  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23b2b3ffcdSSimon Schubert  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24b2b3ffcdSSimon Schubert  */
25b2b3ffcdSSimon Schubert 
26b2b3ffcdSSimon Schubert #ifndef __GNUC__
27b2b3ffcdSSimon Schubert #error "GCC is needed to compile this file"
28b2b3ffcdSSimon Schubert #endif
29b2b3ffcdSSimon Schubert 
30*9189eb5eSzrj #include <sys/cdefs.h>
31f54055f1SSascha Wildner #include <machine/tls.h>
32*9189eb5eSzrj #include <elf.h>
33b2b3ffcdSSimon Schubert #include <stdlib.h>
34b2b3ffcdSSimon Schubert 
35b2b3ffcdSSimon Schubert #include "libc_private.h"
3679dc5732SJohn Marino #include "initfini.c"
37b2b3ffcdSSimon Schubert #include "crtbrand.c"
38b2b3ffcdSSimon Schubert 
39b2b3ffcdSSimon Schubert typedef void (*fptr)(void);
40b2b3ffcdSSimon Schubert 
41b2b3ffcdSSimon Schubert #ifdef GCRT
42b2b3ffcdSSimon Schubert extern void _mcleanup(void);
43b2b3ffcdSSimon Schubert extern void monstartup(void *, void *);
44b2b3ffcdSSimon Schubert extern int eprol;
45b2b3ffcdSSimon Schubert extern int etext;
46b2b3ffcdSSimon Schubert #endif
47b2b3ffcdSSimon Schubert 
48*9189eb5eSzrj /* static ifunc reloc support */
49*9189eb5eSzrj extern const Elf_Rela __rela_iplt_start[] __dso_hidden __weak_symbol;
50*9189eb5eSzrj extern const Elf_Rela __rela_iplt_end[] __dso_hidden __weak_symbol;
51*9189eb5eSzrj static void fix_iplta(void) __noinline;
52*9189eb5eSzrj 
53*9189eb5eSzrj static void
fix_iplta(void)54*9189eb5eSzrj fix_iplta(void)
55*9189eb5eSzrj {
56*9189eb5eSzrj 	const Elf_Rela *rela, *relalim;
57*9189eb5eSzrj 	Elf_Addr *where, target, *ptr;
58*9189eb5eSzrj 
59*9189eb5eSzrj 	rela = __rela_iplt_start;
60*9189eb5eSzrj 	relalim = __rela_iplt_end;
61*9189eb5eSzrj 	for (; rela < relalim; ++rela) {
62*9189eb5eSzrj 		if (ELF_R_TYPE(rela->r_info) != R_X86_64_IRELATIVE)
63*9189eb5eSzrj 			abort();
64*9189eb5eSzrj 		ptr = (Elf_Addr *)rela->r_addend;
65*9189eb5eSzrj 		where = (Elf_Addr *)rela->r_offset;
66*9189eb5eSzrj 		target = ((Elf_Addr (*)(void))ptr)();
67*9189eb5eSzrj 		*where = target;
68*9189eb5eSzrj 	}
69*9189eb5eSzrj }
70*9189eb5eSzrj 
7179dc5732SJohn Marino void _start(char **, void (*)(void));
72b2b3ffcdSSimon Schubert 
73b2b3ffcdSSimon Schubert /* The entry function. */
74b2b3ffcdSSimon Schubert void
_start(char ** ap,void (* cleanup)(void))75b2b3ffcdSSimon Schubert _start(char **ap, void (*cleanup)(void))
76b2b3ffcdSSimon Schubert {
77b2b3ffcdSSimon Schubert 	int argc;
78b2b3ffcdSSimon Schubert 	char **argv;
79b2b3ffcdSSimon Schubert 	char **env;
80b2b3ffcdSSimon Schubert 
81b2b3ffcdSSimon Schubert 	argc = *(long *)(void *)ap;
82b2b3ffcdSSimon Schubert 	argv = ap + 1;
83b2b3ffcdSSimon Schubert 	env = ap + 2 + argc;
84a834075aSJohn Marino 	handle_argv(argc, argv, env);
85b2b3ffcdSSimon Schubert 
86b2b3ffcdSSimon Schubert 	/*
87b2b3ffcdSSimon Schubert 	 * Setup the initial TLS space.  The RTLD does not set up our TLS
88b2b3ffcdSSimon Schubert 	 * (it can't, it doesn't know how our errno is declared).  It simply
89b2b3ffcdSSimon Schubert 	 * does all the groundwork required so that we can call
90b2b3ffcdSSimon Schubert 	 * _rtld_allocate_tls().
91b2b3ffcdSSimon Schubert 	 */
92b2b3ffcdSSimon Schubert 	_init_tls();
93b2b3ffcdSSimon Schubert 	_rtld_call_init();
94b2b3ffcdSSimon Schubert 
95b2b3ffcdSSimon Schubert 	if (&_DYNAMIC != NULL)
96b2b3ffcdSSimon Schubert 		atexit(cleanup);
97*9189eb5eSzrj 	else
98*9189eb5eSzrj 		fix_iplta();
99b2b3ffcdSSimon Schubert 
100b2b3ffcdSSimon Schubert #ifdef GCRT
101b2b3ffcdSSimon Schubert 	atexit(_mcleanup);
102b2b3ffcdSSimon Schubert 	monstartup(&eprol, &etext);
103b2b3ffcdSSimon Schubert #endif
104e2d7e866SJohn Marino 
105e2d7e866SJohn Marino 	handle_static_init(argc, argv, env);
10698b5f2ceSJohn Marino #ifdef GCRT
10798b5f2ceSJohn Marino 	/*
10898b5f2ceSJohn Marino 	 * This label was previously located just after the monstartup
10998b5f2ceSJohn Marino 	 * function.  It was relocated after the handle_static_init function
11098b5f2ceSJohn Marino 	 * to avoid an alternative conditional optimization performed by
11198b5f2ceSJohn Marino 	 * clang.  The optimization cause the compilation to fail with a
11298b5f2ceSJohn Marino 	 * label redefinition error.  The impact of the label relocation is
11398b5f2ceSJohn Marino 	 * the loss of profiling of handle_static_init function.
11498b5f2ceSJohn Marino 	 */
11598b5f2ceSJohn Marino __asm__("eprol:");
11698b5f2ceSJohn Marino #endif
117b2b3ffcdSSimon Schubert 	exit(main(argc, argv, env));
118b2b3ffcdSSimon Schubert }
119