Changeset View
Changeset View
Standalone View
Standalone View
lib/csu/powerpc64/crt1_c.c
Show All 38 Lines | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <stdlib.h> | |||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <sys/elf.h> | #include <sys/elf.h> | ||||
static uint32_t cpu_features; | |||||
static uint32_t cpu_features2; | |||||
#include "libc_private.h" | #include "libc_private.h" | ||||
#include "ignore_init.c" | #include "csu_common.h" | ||||
struct Struct_Obj_Entry; | struct Struct_Obj_Entry; | ||||
struct ps_strings; | struct ps_strings; | ||||
extern void _start(int, char **, char **, const struct Struct_Obj_Entry *, | void _start(int, char **, char **, const struct Struct_Obj_Entry *, | ||||
void (*)(void), struct ps_strings *); | void (*)(void), struct ps_strings *) __dead2; | ||||
#ifdef GCRT | |||||
extern void _mcleanup(void); | |||||
extern void monstartup(void *, void *); | |||||
extern int eprol; | |||||
extern int etext; | |||||
#endif | |||||
struct ps_strings *__ps_strings; | struct ps_strings *__ps_strings; | ||||
static void | |||||
init_cpu_features(char **env) | |||||
{ | |||||
const Elf_Auxinfo *aux; | |||||
/* Find the auxiliary vector on the stack. */ | |||||
while (*env++ != 0) /* Skip over environment, and NULL terminator */ | |||||
; | |||||
aux = (const Elf_Auxinfo *)env; | |||||
/* Digest the auxiliary vector. */ | |||||
for (; aux->a_type != AT_NULL; aux++) { | |||||
switch (aux->a_type) { | |||||
case AT_HWCAP: | |||||
cpu_features = (uint32_t)aux->a_un.a_val; | |||||
break; | |||||
case AT_HWCAP2: | |||||
cpu_features2 = (uint32_t)aux->a_un.a_val; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
/* The entry function. */ | /* The entry function. */ | ||||
/* | /* | ||||
* First 5 arguments are specified by the PowerPC SVR4 ABI. | * First 5 arguments are specified by the PowerPC SVR4 ABI. | ||||
* The last argument, ps_strings, is a BSD extension. | * The last argument, ps_strings, is a BSD extension. | ||||
*/ | */ | ||||
/* ARGSUSED */ | |||||
void | void | ||||
_start(int argc, char **argv, char **env, | _start(int argc, char **argv, char **env, | ||||
const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void), | const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void), | ||||
struct ps_strings *ps_strings) | struct ps_strings *ps_strings) | ||||
{ | { | ||||
handle_argv(argc, argv, env); | |||||
if (ps_strings != (struct ps_strings *)0) | if (ps_strings != (struct ps_strings *)0) | ||||
__ps_strings = ps_strings; | __ps_strings = ps_strings; | ||||
if (&_DYNAMIC != NULL) | |||||
atexit(cleanup); | |||||
else { | |||||
init_cpu_features(env); | |||||
process_irelocs(); | |||||
_init_tls(); | |||||
} | |||||
#ifdef GCRT | #ifdef GCRT | ||||
atexit(_mcleanup); | __libc_start1_gcrt(argc, argv, env, cleanup, main, &eprol, &etext); | ||||
monstartup(&eprol, &etext); | #else | ||||
__libc_start1(argc, argv, env, cleanup, main); | |||||
#endif | #endif | ||||
handle_static_init(argc, argv, env); | |||||
exit(main(argc, argv, env)); | |||||
} | } | ||||
#ifdef GCRT | #ifdef GCRT | ||||
__asm__(".text"); | __asm__(".text"); | ||||
__asm__("eprol:"); | __asm__("eprol:"); | ||||
__asm__(".previous"); | __asm__(".previous"); | ||||
#endif | #endif |