new mostly-C crt1 implementation
authorRich Felker <dalias@aerifal.cx>
Fri, 26 Jul 2013 05:49:14 +0000 (01:49 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 26 Jul 2013 05:49:14 +0000 (01:49 -0400)
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.

Makefile
arch/arm/crt_arch.h [new file with mode: 0644]
arch/i386/crt_arch.h [new file with mode: 0644]
arch/microblaze/crt_arch.h [new file with mode: 0644]
arch/mips/crt_arch.h [new file with mode: 0644]
arch/powerpc/crt_arch.h [new file with mode: 0644]
arch/x86_64/crt_arch.h [new file with mode: 0644]
crt/Scrt1.c
crt/crt1.c

index 2cd2342a55ff36c894dac6182ae8f12ea930bd1b..96910bd20886142f373d81933b0b98bb2af3a15e 100644 (file)
--- 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 (file)
index 0000000..979fb08
--- /dev/null
@@ -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 (file)
index 0000000..ae694f9
--- /dev/null
@@ -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 (file)
index 0000000..8917c69
--- /dev/null
@@ -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 (file)
index 0000000..d4ae52d
--- /dev/null
@@ -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 (file)
index 0000000..8cc53d9
--- /dev/null
@@ -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 (file)
index 0000000..db69295
--- /dev/null
@@ -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\
+");
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..822f10bb13fb4eb8b2affe5fcc4dca984b83ace7 100644 (file)
@@ -0,0 +1 @@
+#include "crt1.c"
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..14c4a52ab0ca6aba99679d92934cb5e24ccfc699 100644 (file)
@@ -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);
+}