commit cef6981283f4881c9d4d6df78db7ecd3b5028938
parent ab9d42a485be23e1f3ee3d9c1488157ffcd28f76
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Thu, 12 Dec 2024 15:05:42 +0000
Use custom linker script, eliminate crt1.c
Diffstat:
8 files changed, 78 insertions(+), 82 deletions(-)
diff --git a/Tupfile b/Tupfile
@@ -1,7 +1,7 @@
CFLAGS = -Os -fno-asynchronous-unwind-tables -no-pie -g
LDFLAGS = -static -nostartfiles -nostdlib -no-pie -Xlinker --gc-sections
-: foreach *.c *.s |> cc $(CFLAGS) -c -o %o %f |> x86_64/%B.o {objs.x86_64}
-: {objs.x86_64} |> cc $(LDFLAGS) -o %o %f |> echo.x86_64
+: foreach *.c *.s |> cc $(CFLAGS) -c -o %o %f |> obj/%B.o {objs}
+: {objs} |> cc $(LDFLAGS) -o %o -T x86_64.ld %f |> echo
.gitignore
diff --git a/Tupfile.ini b/Tupfile.ini
diff --git a/crt0.s b/crt0.s
@@ -1,14 +0,0 @@
-.intel_syntax noprefix
-
-.global _start
-
-.text
-
-_start: # _start is the entry point known to the linker
- xor ebp, ebp # effectively RBP := 0, mark the end of stack frames
- mov edi, [rsp] # get argc from the stack (implicitly zero-extended to 64-bit)
- lea rsi, [rsp+8] # take the address of argv from the stack
- lea rdx, [rsp+16] # take the address of envp from the stack
- xor eax, eax # per ABI and compatibility with icc
- jmp start # %edi, %rsi, %rdx are the three args (of which first two are C standard) to main
-
diff --git a/crt1.c b/crt1.c
@@ -1,14 +0,0 @@
-#include "syscall.h"
-
-extern char __bss_start[], _end[];
-extern int main(int, char**, char**);
-
-__attribute__((noreturn))
-void start(int argc, char* argv[], char* envp[])
-{
- for (char* p = __bss_start; p < _end; ++p)
- *p = 0;
-
- exit(main(argc, argv, envp));
- __builtin_trap();
-}
diff --git a/echo.c b/echo.c
@@ -1,52 +0,0 @@
-#include "syscall.h"
-
-static char buf[0x1000];
-static unsigned bufsize;
-
-static void putflush()
-{
- if (bufsize && write(1, buf, bufsize) != bufsize)
- exit(1);
- bufsize = 0;
-}
-
-static void putch(char c)
-{
- buf[bufsize++] = c;
- if (c == '\n' || bufsize == sizeof buf)
- putflush();
-}
-
-static void putstr(char const* s)
-{
- while(*s)
- putch(*s++);
-}
-/*
-static void* sbrk(unsigned size)
-{
- static void* end;
-
- if (!end)
- end = brk(NULL);
-
- end += size;
-
- if (brk(end) != end)
- exit(1);
-
- return end;
-}
-*/
-int main(int argc, char* argv[])
-{
-// sbrk(0);
- if (argc > 1)
- putstr(argv[1]);
- for (int i = 2; i < argc; ++i)
- {
- putch(' ');
- putstr(argv[i]);
- }
- putch('\n');
-}
diff --git a/main.c b/main.c
@@ -0,0 +1,36 @@
+#include "syscall.h"
+
+static unsigned short bufsize;
+static char buf[0x1000 - sizeof bufsize];
+
+static void putflush()
+{
+ if (bufsize && write(1, buf, bufsize) != bufsize)
+ exit(1);
+ bufsize = 0;
+}
+
+static void putch(char c)
+{
+ buf[bufsize++] = c;
+ if (c == '\n' || bufsize == sizeof buf)
+ putflush();
+}
+
+static void putstr(char const* s)
+{
+ while(*s)
+ putch(*s++);
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc > 1)
+ putstr(argv[1]);
+ for (int i = 2; i < argc; ++i)
+ {
+ putch(' ');
+ putstr(argv[i]);
+ }
+ putch('\n');
+}
diff --git a/start.s b/start.s
@@ -0,0 +1,13 @@
+.intel_syntax noprefix
+
+.global start
+
+.text
+
+start: # start is the entry point known to the linker
+ mov rdi, [rsp] # get argc from the stack
+ lea rsi, [rsp+8] # take the address of argv from the stack
+ lea rdx, [rsp+16] # take the address of envp from the stack
+ call main # %edi, %rsi, %rdx are the three args (of which first two are C standard) to main
+ mov rdi, rax
+ jmp exit
diff --git a/x86_64.ld b/x86_64.ld
@@ -0,0 +1,27 @@
+SECTIONS
+{
+ . = 0x10000;
+ .text (READONLY) :
+ {
+ *(.text)
+ }
+
+ .rodata (READONLY) :
+ ALIGN(0x1000)
+ {
+ *(.rodata.*)
+ *(.rodata)
+ }
+
+ .bss :
+ ALIGN(0x1000)
+ {
+ *(.bss)
+ }
+ .data :
+ {
+ *(.data)
+ }
+}
+
+ENTRY(start)