liblinux++

Log | Files | Refs

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:
MTupfile | 4++--
DTupfile.ini | 0
Dcrt0.s | 14--------------
Dcrt1.c | 14--------------
Decho.c | 52----------------------------------------------------
Amain.c | 36++++++++++++++++++++++++++++++++++++
Astart.s | 13+++++++++++++
Ax86_64.ld | 27+++++++++++++++++++++++++++
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)