summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/bfin/crt1.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/bfin/crt1.S')
-rw-r--r--libc/sysdeps/linux/bfin/crt1.S122
1 files changed, 88 insertions, 34 deletions
diff --git a/libc/sysdeps/linux/bfin/crt1.S b/libc/sysdeps/linux/bfin/crt1.S
index b9b6e3b86..ead8dbfbe 100644
--- a/libc/sysdeps/linux/bfin/crt1.S
+++ b/libc/sysdeps/linux/bfin/crt1.S
@@ -1,23 +1,35 @@
-/* Initial C runtime code for Blackfin
- *
- * Copyright (C) 2004-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
/* When we enter this piece of code, the user stack looks like this:
-* [SP] argc argument counter (integer)
+* argc argument counter (integer)
* argv[0] program name (pointer)
* argv[1...N] program args (pointers)
* NULL
* env[0...N] environment variables (pointers)
* NULL
-
+
* When we are done here, we want
* R0=argc
-* R1=argv
-* R2=__init
-* SP=__fini
+* R1=*argv[0]
+* R2=*envp[0]
*/
#include <features.h>
@@ -29,44 +41,86 @@
.global ___uClibc_main;
.type ___uClibc_main,STT_FUNC;
-#define __UCLIBC_CTOR_DTOR__
-#if defined(__UCLIBC_CTOR_DTOR__)
-.weak __init;
-.weak __fini;
-#endif
+/* Stick in a dummy reference to main(), so that if an application
+ * is linking when the main() function is in a static library (.a)
+ * we can be sure that main() actually gets linked in */
+
+.type _main,STT_FUNC;
__start:
+#ifdef __BFIN_FDPIC__
+ /* P0 contains a pointer to the program's load map. */
+ call .Lcall;
+.Lcall:
+ R4 = RETS;
+ SP += -12;
+ R0.L = .Lcall;
+ R0.H = .Lcall;
+ R1.L = __ROFIXUP_LIST__;
+ R1.H = __ROFIXUP_LIST__;
+ R2.L = __ROFIXUP_END__;
+ R2.H = __ROFIXUP_END__;
+ R1 = R1 - R0;
+ R1 = R1 + R4;
+ R2 = R2 - R0;
+ R2 = R2 + R4;
+ R0 = P0;
+ CALL ___self_reloc;
+ SP += 12;
+ P3 = R0;
+#endif
+
/* clear the frame pointer and the L registers. */
FP = 0;
L0 = 0;
L1 = 0;
L2 = 0;
L3 = 0;
-
-/* Load register R0 (argc) from the stack to its final resting place */
+
+/* Load register R1 (argc) from the stack to its final resting place */
P0 = SP;
- R0 = [P0++];
+ R1 = [P0++];
-/* Copy argv pointer into R1 */
- R1 = P0;
+/* Copy argv pointer into R2 -- which its final resting place */
+ R2 = P0;
-#if defined(__UCLIBC_CTOR_DTOR__)
-/* Load __init into R2 */
- R2.H = __init;
- R2.L = __init;
+/* Skip to the end of argv and put a pointer to the environment in
+ [SP + 12] */
+ R3 = R1;
+ R3 <<= 2;
+ R3 += 4;
+ R3 = R2 + R3;
-/* Load __fini onto the stack */
- SP += -16;
+ SP += -24;
+ [SP + 12] = R3;
+
+/* Ok, now run uClibc's main() -- shouldn't return */
+#if defined L_crt1 && defined __UCLIBC_CTOR_DTOR__
+#ifdef __BFIN_FDPIC__
+ R3 = [P3 + __init@FUNCDESC_GOT17M4];
+#else
+ R3.H = __init;
+ R3.L = __init;
+#endif
+ [SP+16] = R3;
+#ifdef __BFIN_FDPIC__
+ R3 = [P3 + __fini@FUNCDESC_GOT17M4];
+#else
R3.H = __fini;
R3.L = __fini;
- [SP+12] = R3;
-#else
-/* Just fixup the stack */
- sp += -12;
+#endif
+ [SP+20] = R3;
+#else /* no ctor/dtor handling */
+ R3 = 0;
+ [SP + 16] = R3;
+ [SP + 20] = R3;
#endif
-/* Ok, now run uClibc's main() -- shouldn't return */
+#ifdef __BFIN_FDPIC__
+ R0 = [P3 + _main@FUNCDESC_GOT17M4];
+#else
+ R0.H = _main;
+ R0.L = _main;
+#endif
jump.l ___uClibc_main;
-
-.size __start,.-__start