about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-07-26 01:49:14 -0400
committerRich Felker <dalias@aerifal.cx>2013-07-26 01:49:14 -0400
commitc5e34dabbb47d8e97a4deccbb421e0cd93c0094b (patch)
tree4a5c7acc2af2d931ad9a9eeeede865e772344531
parentf9dd79c8d191a8a5356d146c7ccf956677fea4e9 (diff)
downloadmusl-c5e34dabbb47d8e97a4deccbb421e0cd93c0094b.tar.gz
musl-c5e34dabbb47d8e97a4deccbb421e0cd93c0094b.tar.xz
musl-c5e34dabbb47d8e97a4deccbb421e0cd93c0094b.zip
new mostly-C crt1 implementation
the only immediate effect of this commit is enabling PIE support on
some archs that did not previously have any Scrt1.s, since the
existing asm files for crt1 override this C code. so some of the
crt_arch.h files committed are only there for the sake of documenting
what their archs "would do" if they used the new C-based crt1.

the expectation is that new archs should use this new system rather
than using heavy asm for crt1. aside from being easier and less
error-prone, it also ensures that PIE support is available immediately
(since Scrt1.o is generated from the same C source, using -fPIC)
rather than having to be added as an afterthought in the porting
process.
-rw-r--r--Makefile4
-rw-r--r--arch/arm/crt_arch.h9
-rw-r--r--arch/i386/crt_arch.h13
-rw-r--r--arch/microblaze/crt_arch.h11
-rw-r--r--arch/mips/crt_arch.h21
-rw-r--r--arch/powerpc/crt_arch.h12
-rw-r--r--arch/x86_64/crt_arch.h9
-rw-r--r--crt/Scrt1.c1
-rw-r--r--crt/crt1.c16
9 files changed, 96 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 2cd2342a..96910bd2 100644
--- a/Makefile
+++ b/Makefile
@@ -80,6 +80,10 @@ include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/
 
 src/ldso/dynlink.lo: arch/$(ARCH)/reloc.h
 
+crt/crt1.o crt/Scrt1.o: $(wildcard arch/$(ARCH)/crt_arch.h)
+
+crt/Scrt1.o: CFLAGS += -fPIC
+
 OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
 $(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
 
diff --git a/arch/arm/crt_arch.h b/arch/arm/crt_arch.h
new file mode 100644
index 00000000..979fb081
--- /dev/null
+++ b/arch/arm/crt_arch.h
@@ -0,0 +1,9 @@
+__asm__("\
+.global _start \n\
+_start: \n\
+	mov fp, #0 \n\
+	mov lr, #0 \n\
+	mov a1, sp \n\
+	and sp, sp, #-16 \n\
+	bl __cstart \n\
+");
diff --git a/arch/i386/crt_arch.h b/arch/i386/crt_arch.h
new file mode 100644
index 00000000..ae694f99
--- /dev/null
+++ b/arch/i386/crt_arch.h
@@ -0,0 +1,13 @@
+__asm__("\
+.text \n\
+.global _start \n\
+_start: \n\
+	xor %ebp,%ebp \n\
+	mov %esp,%eax \n\
+	and $-16,%esp \n\
+	push %eax \n\
+	push %eax \n\
+	push %eax \n\
+	push %eax \n\
+	call __cstart \n\
+");
diff --git a/arch/microblaze/crt_arch.h b/arch/microblaze/crt_arch.h
new file mode 100644
index 00000000..8917c695
--- /dev/null
+++ b/arch/microblaze/crt_arch.h
@@ -0,0 +1,11 @@
+__asm__("\
+.global _start \n\
+.align  2 \n\
+_start: \n\
+	add r19, r0, r0 \n\
+	ori r5, r1, 0 \n\
+	andi r1, r1, -8 \n\
+	addik r1, r1, -8 \n\
+	bri __cstart \n\
+	nop \n\
+");
diff --git a/arch/mips/crt_arch.h b/arch/mips/crt_arch.h
new file mode 100644
index 00000000..d4ae52d1
--- /dev/null
+++ b/arch/mips/crt_arch.h
@@ -0,0 +1,21 @@
+__asm__("\n\
+.set push\n\
+.set noreorder\n\
+.global __start\n\
+.global _start\n\
+.type   __start, @function\n\
+.type   _start, @function\n\
+__start:\n\
+_start:\n\
+	bal 1f \n\
+	move $fp, $0 \n\
+2:	.gpword 2b \n\
+1:	lw $gp, 0($ra) \n\
+	subu $gp, $ra, $gp \n\
+	move $4, $sp \n\
+	subu $sp, $sp, 16 \n\
+	and $sp, $sp, -8 \n\
+	lw $25, %call16(__cstart)($gp) \n\
+	jalr $25 \n\
+	nop \n\
+.set pop");
diff --git a/arch/powerpc/crt_arch.h b/arch/powerpc/crt_arch.h
new file mode 100644
index 00000000..8cc53d98
--- /dev/null
+++ b/arch/powerpc/crt_arch.h
@@ -0,0 +1,12 @@
+__asm__("\
+.global _start \n\
+.type   _start, %function \n\
+_start: \n\
+	mr 3, 1 \n\
+	clrrwi 1, 1, 4 \n\
+	li 0, 0 \n\
+	stwu 1, -16(1) \n\
+	mtlr 0 \n\
+	stw 0, 0(1) \n\
+	bl __cstart \n\
+");        
diff --git a/arch/x86_64/crt_arch.h b/arch/x86_64/crt_arch.h
new file mode 100644
index 00000000..db692950
--- /dev/null
+++ b/arch/x86_64/crt_arch.h
@@ -0,0 +1,9 @@
+__asm__("\
+.text \n\
+.global _start \n\
+_start: \n\
+	xor %rbp,%rbp \n\
+	mov %rsp,%rdi \n\
+	andq $-16,%rsp \n\
+	call __cstart \n\
+");
diff --git a/crt/Scrt1.c b/crt/Scrt1.c
index e69de29b..822f10bb 100644
--- a/crt/Scrt1.c
+++ b/crt/Scrt1.c
@@ -0,0 +1 @@
+#include "crt1.c"
diff --git a/crt/crt1.c b/crt/crt1.c
index e69de29b..14c4a52a 100644
--- a/crt/crt1.c
+++ b/crt/crt1.c
@@ -0,0 +1,16 @@
+#include <features.h>
+
+#include "crt_arch.h"
+
+int main();
+void _init() __attribute__((weak));
+void _fini() __attribute__((weak));
+_Noreturn int __libc_start_main(int (*)(), int, char **,
+	void (*)(), void(*)(), void(*)());
+
+void __cstart(long *p)
+{
+	int argc = p[0];
+	char **argv = (void *)(p+1);
+	__libc_start_main(main, argc, argv, _init, _fini, 0);
+}