svn commit: r200894 - projects/mips/lib/csu/mips
Warner Losh
imp at FreeBSD.org
Wed Dec 23 08:22:48 UTC 2009
Author: imp
Date: Wed Dec 23 08:22:48 2009
New Revision: 200894
URL: http://svn.freebsd.org/changeset/base/200894
Log:
Bring in support for n64 and n32 ABIs, at least at the base.
o Rename __start to __start_mips and change the args a little
o Create a new __start written in assembler that copes with the
different ABIs and rewrites the args a little to make their passing
more abi agnostic.
o Add an alias _start for __start for the Cavium toolchain (in the
cavium port, a custom ld script is used which references _start
instead of the traditional mips __start).
o call _init_tls() when we aren't being an a.out shared library (which
is the only time _DYNAMIC is != NULL, I think). We could likely
retire support for a.out shared libraries entirely, but that will be
in the future when I'm sure there's not some subtle reason to keep
them around.
# Note: the reason mips starts at __start instead of _start is purely
# historical, but I didn't want to change it here and in the
# toolchain. The Cavium build process is kind of the odd duck here,
# but it is trivial to support both, so why not...
Modified:
projects/mips/lib/csu/mips/crt1.c
Modified: projects/mips/lib/csu/mips/crt1.c
==============================================================================
--- projects/mips/lib/csu/mips/crt1.c Wed Dec 23 08:16:53 2009 (r200893)
+++ projects/mips/lib/csu/mips/crt1.c Wed Dec 23 08:22:48 2009 (r200894)
@@ -1,6 +1,4 @@
/*-
- * Copyright 1996-1998 John D. Polstra.
- * All rights reserved.
* Copyright (c) 1995 Christopher G. Demetriou
* All rights reserved.
*
@@ -65,37 +63,94 @@ extern int etext;
char **environ;
const char *__progname = "";
+struct ps_strings *__ps_strings;
void __gccmain(void) {}
void __main(void) {}
+/*
+ * Historically, mips has used __start for the beginning address of programs.
+ * However, the Cavium toolchain (and maybe others) use _start. Define both
+ * here. The assembler code here tries to juggle the arguments such that they
+ * are right for all ABIs and then calls __start_mips which is what used to
+ * be just plain __start, and still is on other BSD ports.
+ */
+
/* The entry function. */
+__asm(" .text \n"
+" .align 8 \n"
+" .globl _start \n"
+" _start: \n"
+" .globl __start \n"
+" __start: \n"
+#if defined(__mips_n32) || defined(__mips_n64)
+" .cpsetup $25, $24, __start\n"
+#else
+" .set noreorder \n"
+" .cpload $25 \n"
+" .set reorder \n"
+#endif
+" /* Get cleanup routine and main object set by rtld */\n"
+" /* Note that a2 is already set to ps_string by _rtld_start */\n"
+" /* move a3, a0 */\n"
+" /* move t0, a1 */\n"
+" /* Get argc, argv from stack */ \n"
+" /* lw a0, 0(sp) */\n"
+" /* move a1, sp */\n"
+" /* addu a1, 4 */\n"
+" \n"
+" /* Stack should 8bytes aligned */\n"
+" /* required by ABI to pass */\n"
+" /* 64-bits arguments */\n"
+" /* and sp, ~8 */\n"
+" /* subu sp, sp, 20 */\n"
+" /* sw t0, 16(sp) */\n"
+" \n"
+" move $7, $4 /* atexit */\n"
+" move $8, $5 /* main_obj entry */\n"
+#if defined(__mips_n64)
+" ld $4, 0($29) \n"
+" move $5, $29 \n"
+" addu $5, 8 \n"
+#else
+" lw $4, 0($29) \n"
+" move $5, $29 \n"
+" addu $5, 4 \n"
+#endif
+" \n"
+" and $29, 0xfffffff8 \n"
+" subu $29, $29, 24 /* args slot + cleanup + 4 bytes padding */ \n"
+" sw $8, 16($29) \n"
+"\n"
+" la $25, __start_mips \n"
+" nop \n"
+" j $25\n");
+/* ARGSUSED */
+
void
-__start(char **ap,
- void (*cleanup)(void), /* from shared loader */
- struct Struct_Obj_Entry *obj, /* from shared loader */
- struct ps_strings *ps_strings)
+__start_mips(int argc, char **argv, struct ps_strings *ps_strings,
+ void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused)
{
- int argc;
- char **argv;
char **env;
+ const char *s;
- argc = * (long *) ap;
- argv = ap + 1;
- env = ap + 2 + argc;
+ env = argv + argc + 1;
environ = env;
+
if(argc > 0 && argv[0] != NULL) {
- const char *s;
__progname = argv[0];
for (s = __progname; *s != '\0'; s++)
if (*s == '/')
__progname = s + 1;
}
-#ifndef NOSHARED
+ __ps_strings = ps_strings;
+
if (&_DYNAMIC != NULL)
atexit(cleanup);
-#endif
+ else
+ _init_tls();
+
#ifdef GCRT
atexit(_mcleanup);
#endif
More information about the svn-src-projects
mailing list