:: commit ba7ed52f6ac16619945779cc24cccdb374a15dff

mintsuki <mintsuki@protonmail.com> — 2020-09-03 23:37

parents: 5379787967

Enable lto and move naked assembly functions to own files

diff --git a/limine.bin b/limine.bin
index 90577a52..1bf49b19 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/src/Makefile b/src/Makefile
index 27e1c32f..0679154e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
 CC = ../toolchain/bin/i386-elf-gcc
 LD = ../toolchain/bin/i386-elf-gcc
 
-CFLAGS = -Os -pipe -Wall -Wextra
+CFLAGS = -flto -Os -pipe -Wall -Wextra
 
 INTERNAL_CFLAGS = \
 	-std=gnu99 \
@@ -15,7 +15,7 @@ INTERNAL_CFLAGS = \
 	-I. \
 	-Wno-address-of-packed-member
 
-LDFLAGS = -O2
+LDFLAGS = -flto -Os
 
 INTERNAL_LDFLAGS = \
 	-nostdlib \
@@ -27,7 +27,8 @@ INTERNAL_LDFLAGS = \
 .PHONY: all clean
 
 C_FILES := $(shell find ./ -type f -name '*.c' | sort)
-OBJ := $(C_FILES:.c=.o)
+ASM_FILES := $(shell find ./ -type f -name '*.asm' | grep -v bootsect | sort)
+OBJ := $(C_FILES:.c=.o) $(ASM_FILES:.asm=.o)
 
 all: limine.bin
 
@@ -38,5 +39,8 @@ limine.bin: $(OBJ)
 %.o: %.c
 	$(CC) $(CFLAGS) $(INTERNAL_CFLAGS) -c $< -o $@
 
+%.o: %.asm
+	nasm $< -f elf32 -o $@
+
 clean:
 	rm -f $(OBJ)
diff --git a/src/lib/blib.c b/src/lib/blib.c
index 6f598cd3..7fab85c8 100644
--- a/src/lib/blib.c
+++ b/src/lib/blib.c
@@ -68,127 +68,6 @@ void *balloc_aligned(size_t count, size_t alignment) {
     return ret;
 }
 
-__attribute__((used)) static uint32_t int_08_ticks_counter;
-
-__attribute__((naked)) static void int_08_isr(void) {
-    ASM_BASIC(
-        ".code16\n\t"
-        "inc dword ptr cs:[int_08_ticks_counter]\n\t"
-        "int 0x40\n\t"   // call callback
-        "iret\n\t"
-        ".code32\n\t"
-    );
-}
-
-uint32_t *ivt = 0; // this variable is not static else gcc will optimise the
-                   // 0 ptr to a ud2
-
-__attribute__((used)) static void hook_int_08(void) {
-    ivt[0x40] = ivt[0x08];  // int 0x40 is callback interrupt
-    ivt[0x08] = (uint16_t)(size_t)int_08_isr;
-}
-
-__attribute__((used)) static void dehook_int_08(void) {
-    ivt[0x08] = ivt[0x40];
-}
-
-// This is a dirty hack but we need to execute this full function in real mode
-__attribute__((naked))
-int pit_sleep_and_quit_on_keypress(uint32_t ticks) {
-    ASM_BASIC(
-        "call hook_int_08\n\t"
-
-        // pit_ticks in edx
-        "mov edx, dword ptr ss:[esp+4]\n\t"
-
-        "lea ecx, int_08_ticks_counter\n\t"
-
-        "mov dword ptr ds:[ecx], 0\n\t"
-
-        // Save non-scratch GPRs
-        "push ebx\n\t"
-        "push esi\n\t"
-        "push edi\n\t"
-        "push ebp\n\t"
-
-        // Jump to real mode
-        FARJMP32("0x08", "1f")
-        "1: .code16\n\t"
-        "mov ax, 0x10\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-        "mov eax, cr0\n\t"
-        "and al, 0xfe\n\t"
-        "mov cr0, eax\n\t"
-        FARJMP16("0", "1f")
-        "1:\n\t"
-        "mov ax, 0\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-
-        "sti\n\t"
-
-        "10:\n\t"
-
-        "cmp dword ptr ds:[ecx], edx\n\t"
-        "je 30f\n\t" // out on timeout
-
-        "push ecx\n\t"
-        "push edx\n\t"
-        "mov ah, 0x01\n\t"
-        "xor al, al\n\t"
-        "int 0x16\n\t"
-        "pop edx\n\t"
-        "pop ecx\n\t"
-
-        "jz 10b\n\t" // loop
-
-        // on keypress
-        "xor ax, ax\n\t"
-        "int 0x16\n\t"
-        "mov eax, 1\n\t"
-        "jmp 20f\n\t"  // out
-
-        "30:\n\t"   // out on timeout
-        "xor eax, eax\n\t"
-
-        "20:\n\t"
-
-        "cli\n\t"
-
-        // Jump back to pmode
-        "mov ebx, cr0\n\t"
-        "or bl, 1\n\t"
-        "mov cr0, ebx\n\t"
-        FARJMP16("0x18", "1f")
-        "1: .code32\n\t"
-        "mov bx, 0x20\n\t"
-        "mov ds, bx\n\t"
-        "mov es, bx\n\t"
-        "mov fs, bx\n\t"
-        "mov gs, bx\n\t"
-        "mov ss, bx\n\t"
-
-        // Restore non-scratch GPRs
-        "pop ebp\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "pop ebx\n\t"
-
-        // Exit
-        "push eax\n\t"
-        "call dehook_int_08\n\t"
-        "pop eax\n\t"
-        "ret\n\t"
-    );
-}
-
 uint64_t strtoui(const char *s) {
     uint64_t n = 0;
     while (*s)
diff --git a/src/lib/builtins.asm b/src/lib/builtins.asm
new file mode 100644
index 00000000..924cbe16
--- /dev/null
+++ b/src/lib/builtins.asm
@@ -0,0 +1,75 @@
+section .text
+
+global memcpy
+memcpy:
+    push esi
+    push edi
+    mov eax, dword [esp+12]
+    mov edi, eax
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+    rep movsb
+    pop edi
+    pop esi
+    ret
+
+global memset
+memset:
+    push edi
+    mov edx, dword [esp+8]
+    mov edi, edx
+    mov eax, dword [esp+12]
+    mov ecx, dword [esp+16]
+    rep stosb
+    mov eax, edx
+    pop edi
+    ret
+
+global memmove
+memmove:
+    push esi
+    push edi
+    mov eax, dword [esp+12]
+    mov edi, eax
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+
+    cmp edi, esi
+    ja .copy_backwards
+
+    rep movsb
+    jmp .done
+
+  .copy_backwards:
+    lea edi, [edi+ecx-1]
+    lea esi, [esi+ecx-1]
+    std
+    rep movsb
+    cld
+
+  .done:
+    pop edi
+    pop esi
+    ret
+
+global memcmp
+memcmp:
+    push esi
+    push edi
+    mov edi, dword [esp+12]
+    mov esi, dword [esp+16]
+    mov ecx, dword [esp+20]
+    repe cmpsb
+    jecxz .equal
+    mov al, byte [edi-1]
+    sub al, byte [esi-1]
+    movsx eax, al
+    jmp .done
+
+  .equal:
+    mov eax, ecx
+
+  .done:
+    pop edi
+    pop esi
+    ret
diff --git a/src/lib/libc.c b/src/lib/libc.c
index d8038002..11b46fc3 100644
--- a/src/lib/libc.c
+++ b/src/lib/libc.c
@@ -17,90 +17,6 @@ int tolower(int c) {
     return c;
 }
 
-__attribute__((naked))
-void *memcpy(void *dest, const void *src, size_t n) {
-    ASM_BASIC(
-        "push esi\n\t"
-        "push edi\n\t"
-        "mov eax, dword ptr [esp+12]\n\t"
-        "mov edi, eax\n\t"
-        "mov esi, dword ptr [esp+16]\n\t"
-        "mov ecx, dword ptr [esp+20]\n\t"
-        "rep movsb\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "ret\n\t"
-    );
-}
-
-__attribute__((naked))
-void *memset(void *s, int c, size_t n) {
-    ASM_BASIC(
-        "push edi\n\t"
-        "mov edx, dword ptr [esp+8]\n\t"
-        "mov edi, edx\n\t"
-        "mov eax, dword ptr [esp+12]\n\t"
-        "mov ecx, dword ptr [esp+16]\n\t"
-        "rep stosb\n\t"
-        "mov eax, edx\n\t"
-        "pop edi\n\t"
-        "ret\n\t"
-    );
-}
-
-__attribute__((naked))
-void *memmove(void *dest, const void *src, size_t n) {
-    ASM_BASIC(
-        "push esi\n\t"
-        "push edi\n\t"
-        "mov eax, dword ptr [esp+12]\n\t"
-        "mov edi, eax\n\t"
-        "mov esi, dword ptr [esp+16]\n\t"
-        "mov ecx, dword ptr [esp+20]\n\t"
-
-        "cmp edi, esi\n\t"
-        "ja 1f\n\t"
-
-        "rep movsb\n\t"
-        "jmp 2f\n\t"
-
-        "1:\n\t"
-        "lea edi, [edi+ecx-1]\n\t"
-        "lea esi, [esi+ecx-1]\n\t"
-        "std\n\t"
-        "rep movsb\n\t"
-        "cld\n\t"
-
-        "2:\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "ret\n\t"
-    );
-}
-
-__attribute__((naked))
-int memcmp(const void *s1, const void *s2, size_t n) {
-    ASM_BASIC(
-        "push esi\n\t"
-        "push edi\n\t"
-        "mov edi, dword ptr [esp+12]\n\t"
-        "mov esi, dword ptr [esp+16]\n\t"
-        "mov ecx, dword ptr [esp+20]\n\t"
-        "repe cmpsb\n\t"
-        "jecxz 1f\n\t"
-        "mov al, byte ptr [edi-1]\n\t"
-        "sub al, byte ptr [esi-1]\n\t"
-        "movsx eax, al\n\t"
-        "jmp 2f\n\t"
-        "1:\n\t"
-        "mov eax, ecx\n\t"
-        "2:\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "ret\n\t"
-    );
-}
-
 char *strcpy(char *dest, const char *src) {
     size_t i;
 
diff --git a/src/lib/part.c b/src/lib/part.c
index f9952712..a2cf71a4 100644
--- a/src/lib/part.c
+++ b/src/lib/part.c
@@ -93,22 +93,22 @@ struct mbr_entry {
 } __attribute__((packed));
 
 static int mbr_get_part(struct part *ret, int drive, int partition) {
-    // Variables.
+    // Check if actually valid mbr
+    uint16_t hint;
+    read(drive, &hint, 444, sizeof(uint16_t));
+    if (hint && hint != 0x5a5a)
+        return INVALID_TABLE;
+
     struct mbr_entry entry;
-    const size_t entry_address = 0x1be + sizeof(struct mbr_entry) * partition;
+    size_t entry_offset = 0x1be + sizeof(struct mbr_entry) * partition;
 
-    // Read the entry of the MBR.
-    int r;
-    if ((r = read(drive, &entry, entry_address, sizeof(struct mbr_entry)))) {
+    int r = read(drive, &entry, entry_offset, sizeof(struct mbr_entry));
+    if (r)
         return r;
-    }
 
-    // Check if the partition exists, fail if it doesnt.
-    if (entry.type == 0) {
+    if (entry.type == 0)
         return NO_PARTITION;
-    }
 
-    // Assign the final fields and return.
     ret->first_sect = entry.first_sect;
     ret->sect_count = entry.sect_count;
     return 0;
diff --git a/src/lib/real.asm b/src/lib/real.asm
new file mode 100644
index 00000000..5b815aa6
--- /dev/null
+++ b/src/lib/real.asm
@@ -0,0 +1,118 @@
+section .text
+
+global rm_int
+rm_int:
+    ; Self-modifying code: int $int_no
+    mov al, byte [esp+4]
+    mov byte [.int_no], al
+
+    ; Save out_regs
+    mov eax, dword [esp+8]
+    mov dword [.out_regs], eax
+
+    ; Save in_regs
+    mov eax, dword [esp+12]
+    mov dword [.in_regs], eax
+
+    ; Save GDT in case BIOS overwrites it
+    sgdt [.gdt]
+
+    ; Save non-scratch GPRs
+    push ebx
+    push esi
+    push edi
+    push ebp
+
+    ; Jump to real mode
+    jmp 0x08:.bits16
+  .bits16:
+    bits 16
+    mov ax, 0x10
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+    mov ss, ax
+    mov eax, cr0
+    and al, 0xfe
+    mov cr0, eax
+    jmp 0x00:.cszero
+  .cszero:
+    xor ax, ax
+    mov ss, ax
+
+    ; Load in_regs
+    mov dword [ss:.esp], esp
+    mov esp, dword [ss:.in_regs]
+    pop gs
+    pop fs
+    pop es
+    pop ds
+    popfd
+    pop ebp
+    pop edi
+    pop esi
+    pop edx
+    pop ecx
+    pop ebx
+    pop eax
+    mov esp, dword [ss:.esp]
+
+    sti
+
+    ; Indirect interrupt call
+    db 0xcd
+  .int_no:
+    db 0
+
+    cli
+
+    ; Load out_regs
+    mov dword [ss:.esp], esp
+    mov esp, dword [ss:.out_regs]
+    lea esp, [esp + 10*4]
+    push eax
+    push ebx
+    push ecx
+    push edx
+    push esi
+    push edi
+    push ebp
+    pushfd
+    push ds
+    push es
+    push fs
+    push gs
+    mov esp, dword [ss:.esp]
+
+    ; Restore GDT
+    lgdt [ss:.gdt]
+
+    ; Jump back to pmode
+    mov eax, cr0
+    or al, 1
+    mov cr0, eax
+    jmp 0x18:.bits32
+  .bits32:
+    bits 32
+    mov ax, 0x20
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+    mov ss, ax
+
+    ; Restore non-scratch GPRs
+    pop ebp
+    pop edi
+    pop esi
+    pop ebx
+
+    ; Exit
+    ret
+
+align 16
+  .esp:      dd 0
+  .out_regs: dd 0
+  .in_regs:  dd 0
+  .gdt:      dq 0
diff --git a/src/lib/real.c b/src/lib/real.c
deleted file mode 100644
index e4b5c6cf..00000000
--- a/src/lib/real.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <stdint.h>
-#include <lib/real.h>
-#include <lib/asm.h>
-
-__attribute__((naked))
-void rm_int(uint8_t int_no, struct rm_regs *out_regs, struct rm_regs *in_regs) {
-    ASM_BASIC(
-        // Self-modifying code: int $int_no
-        "mov al, byte ptr ss:[esp+4]\n\t"
-        "mov byte ptr ds:[3f], al\n\t"
-
-        // Save out_regs
-        "mov eax, dword ptr ss:[esp+8]\n\t"
-        "mov dword ptr ds:[6f], eax\n\t"
-
-        // Save in_regs
-        "mov eax, dword ptr ss:[esp+12]\n\t"
-        "mov dword ptr ds:[7f], eax\n\t"
-
-        // Save GDT in case BIOS overwrites it
-        "sgdt [8f]\n\t"
-
-        // Save non-scratch GPRs
-        "push ebx\n\t"
-        "push esi\n\t"
-        "push edi\n\t"
-        "push ebp\n\t"
-
-        // Jump to real mode
-        FARJMP32("0x08", "1f")
-        "1: .code16\n\t"
-        "mov ax, 0x10\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-        "mov eax, cr0\n\t"
-        "and al, 0xfe\n\t"
-        "mov cr0, eax\n\t"
-        FARJMP16("0", "1f")
-        "1:\n\t"
-        "xor ax, ax\n\t"
-        "mov ss, ax\n\t"
-
-        // Load in_regs
-        "mov dword ptr ss:[5f], esp\n\t"
-        "mov esp, dword ptr ss:[7f]\n\t"
-        "pop gs\n\t"
-        "pop fs\n\t"
-        "pop es\n\t"
-        "pop ds\n\t"
-        "popfd\n\t"
-        "pop ebp\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "pop edx\n\t"
-        "pop ecx\n\t"
-        "pop ebx\n\t"
-        "pop eax\n\t"
-        "mov esp, dword ptr ss:[5f]\n\t"
-
-        "sti\n\t"
-
-        // Indirect interrupt call
-        ".byte 0xcd\n\t"
-        "3: .byte 0\n\t"
-
-        "cli\n\t"
-
-        // Load out_regs
-        "mov dword ptr ss:[5f], esp\n\t"
-        "mov esp, dword ptr ss:[6f]\n\t"
-        "lea esp, [esp + 10*4]\n\t"
-        "push eax\n\t"
-        "push ebx\n\t"
-        "push ecx\n\t"
-        "push edx\n\t"
-        "push esi\n\t"
-        "push edi\n\t"
-        "push ebp\n\t"
-        "pushfd\n\t"
-        "push ds\n\t"
-        "push es\n\t"
-        "push fs\n\t"
-        "push gs\n\t"
-        "mov esp, dword ptr ss:[5f]\n\t"
-
-        // Restore GDT
-        "lgdt ss:[8f]\n\t"
-
-        // Jump back to pmode
-        "mov eax, cr0\n\t"
-        "or al, 1\n\t"
-        "mov cr0, eax\n\t"
-        FARJMP16("0x18", "1f")
-        "1: .code32\n\t"
-        "mov ax, 0x20\n\t"
-        "mov ds, ax\n\t"
-        "mov es, ax\n\t"
-        "mov fs, ax\n\t"
-        "mov gs, ax\n\t"
-        "mov ss, ax\n\t"
-
-        // Restore non-scratch GPRs
-        "pop ebp\n\t"
-        "pop edi\n\t"
-        "pop esi\n\t"
-        "pop ebx\n\t"
-
-        // Exit
-        "ret\n\t"
-
-        // ESP
-        "5: .long 0\n\t"
-        // out_regs
-        "6: .long 0\n\t"
-        // in_regs
-        "7: .long 0\n\t"
-        // gdt
-        "8: .long 0\n\t"
-        "   .long 0\n\t"
-    );
-}
diff --git a/src/lib/sleep.asm b/src/lib/sleep.asm
new file mode 100644
index 00000000..9f0bcef5
--- /dev/null
+++ b/src/lib/sleep.asm
@@ -0,0 +1,105 @@
+section .text
+
+int_08_ticks_counter: dd 0
+
+int_08_isr:
+    bits 16
+    inc dword [cs:int_08_ticks_counter]
+    int 0x80   ; call callback
+    iret
+    bits 32
+
+global pit_sleep_and_quit_on_keypress
+pit_sleep_and_quit_on_keypress:
+    ; Hook int 0x08
+    mov edx, dword [0x08*4]
+    mov dword [0x80*4], edx
+    mov edx, int_08_isr
+    mov dword [0x08*4], int_08_isr
+
+    ; pit_ticks in edx
+    mov edx, dword [esp+4]
+
+    mov dword [int_08_ticks_counter], 0
+
+    ; Save non-scratch GPRs
+    push ebx
+    push esi
+    push edi
+    push ebp
+
+    ; Jump to real mode
+    jmp 0x08:.bits16
+  .bits16:
+    bits 16
+    mov ax, 0x10
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+    mov ss, ax
+    mov eax, cr0
+    and al, 0xfe
+    mov cr0, eax
+    jmp 0x00:.cszero
+  .cszero:
+    xor ax, ax
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+    mov ss, ax
+
+    sti
+
+  .loop:
+    cmp dword [int_08_ticks_counter], edx
+    je .timeout
+
+    push ecx
+    push edx
+    mov ah, 0x01
+    xor al, al
+    int 0x16
+    pop edx
+    pop ecx
+
+    jz .loop
+
+    ; on keypress
+    xor ax, ax
+    int 0x16
+    mov eax, 1
+    jmp .done
+
+  .timeout:
+    xor eax, eax
+
+  .done:
+    cli
+
+    ; Jump back to pmode
+    mov ebx, cr0
+    or bl, 1
+    mov cr0, ebx
+    jmp 0x18:.bits32
+  .bits32:
+    bits 32
+    mov bx, 0x20
+    mov ds, bx
+    mov es, bx
+    mov fs, bx
+    mov gs, bx
+    mov ss, bx
+
+    ; Restore non-scratch GPRs
+    pop ebp
+    pop edi
+    pop esi
+    pop ebx
+
+    ; Dehook int 0x08
+    mov edx, dword [0x80*4]
+    mov dword [0x08*4], edx
+
+    ret
tab: 248 wrap: offon