Преглед изворни кода

Kernel: Replace raw asm functions with naked ones

Hendiadyoin1 пре 4 година
родитељ
комит
9b7e48c6bd

+ 10 - 0
AK/Platform.h

@@ -54,6 +54,16 @@
 #endif
 #define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
 
+#ifdef NO_RETURN
+#    undef NO_RETURN
+#endif
+#define NO_RETURN [[noreturn]]
+
+#ifdef NAKED
+#    undef NAKED
+#endif
+#define NAKED __attribute__((naked))
+
 // GCC doesn't have __has_feature but clang does
 #ifndef __has_feature
 #    define __has_feature(...) 0

+ 5 - 0
Kernel/Arch/x86/Processor.h

@@ -32,6 +32,11 @@ struct ProcessorMessageEntry;
 struct TrapFrame;
 class ProcessorInfo;
 
+// FIXME: Find a better place for these
+extern "C" void thread_context_first_enter(void);
+extern "C" void exit_kernel_thread(void);
+extern "C" void do_assume_context(Thread* thread, u32 flags);
+
 struct [[gnu::aligned(16)]] FPUState
 {
     u8 buffer[512];

+ 114 - 114
Kernel/Arch/x86/common/Interrupts.cpp

@@ -42,122 +42,122 @@ static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interr
 // clang-format off
 
 #if ARCH(I386)
-#define EH_ENTRY(ec, title)                         \
-    extern "C" void title##_asm_entry();            \
-    extern "C" void title##_handler(TrapFrame*) __attribute__((used)); \
-    asm(                                            \
-        ".globl " #title "_asm_entry\n"             \
-        "" #title "_asm_entry: \n"                  \
-        "    pusha\n"                               \
-        "    pushl %ds\n"                           \
-        "    pushl %es\n"                           \
-        "    pushl %fs\n"                           \
-        "    pushl %gs\n"                           \
-        "    pushl %ss\n"                           \
-        "    mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n" \
-        "    mov %ax, %ds\n"                        \
-        "    mov %ax, %es\n"                        \
-        "    mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \
-        "    mov %ax, %gs\n"                        \
-        "    pushl %esp \n" /* set TrapFrame::regs */ \
-        "    subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \
-        "    pushl %esp \n"                         \
-        "    cld\n"                                 \
-        "    call enter_trap_no_irq \n"             \
-        "    call " #title "_handler\n"             \
-        "    jmp common_trap_exit \n");
-
-#define EH_ENTRY_NO_CODE(ec, title)                 \
-    extern "C" void title##_asm_entry();	    \
-    extern "C" void title##_handler(TrapFrame*) __attribute__((used)); \
-    asm(                                            \
-        ".globl " #title "_asm_entry\n"             \
-        "" #title "_asm_entry: \n"                  \
-        "    pushl $0x0\n"                          \
-        "    pusha\n"                               \
-        "    pushl %ds\n"                           \
-        "    pushl %es\n"                           \
-        "    pushl %fs\n"                           \
-        "    pushl %gs\n"                           \
-        "    pushl %ss\n"                           \
-        "    mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n" \
-        "    mov %ax, %ds\n"                        \
-        "    mov %ax, %es\n"                        \
-        "    mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \
-        "    mov %ax, %gs\n"                        \
-        "    pushl %esp \n" /* set TrapFrame::regs */ \
-        "    subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \
-        "    pushl %esp \n"                         \
-        "    cld\n"                                 \
-        "    call enter_trap_no_irq \n"             \
-        "    call " #title "_handler\n"             \
-        "    jmp common_trap_exit \n");
+#define EH_ENTRY(ec, title)                                                    \
+    extern "C" void title##_asm_entry();                                       \
+    extern "C" void title##_handler(TrapFrame*) __attribute__((used));         \
+    NAKED void title##_asm_entry(){                                            \
+        asm(                                                                   \
+            "    pusha\n"                                                      \
+            "    pushl %ds\n"                                                  \
+            "    pushl %es\n"                                                  \
+            "    pushl %fs\n"                                                  \
+            "    pushl %gs\n"                                                  \
+            "    pushl %ss\n"                                                  \
+            "    mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n"              \
+            "    mov %ax, %ds\n"                                               \
+            "    mov %ax, %es\n"                                               \
+            "    mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n"               \
+            "    mov %ax, %gs\n"                                               \
+            "    pushl %esp \n" /* set TrapFrame::regs */                      \
+            "    subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n"          \
+            "    pushl %esp \n"                                                \
+            "    cld\n"                                                        \
+            "    call enter_trap_no_irq \n"                                    \
+            "    call " #title "_handler\n"                                    \
+            "    jmp common_trap_exit \n");                                    \
+    }
+
+#define EH_ENTRY_NO_CODE(ec, title)                                            \
+    extern "C" void title##_asm_entry();	                                   \
+    extern "C" void title##_handler(TrapFrame*) __attribute__((used));         \
+    NAKED void title##_asm_entry(){                                            \
+        asm(                                                                   \
+            "    pushl $0x0\n"                                                 \
+            "    pusha\n"                                                      \
+            "    pushl %ds\n"                                                  \
+            "    pushl %es\n"                                                  \
+            "    pushl %fs\n"                                                  \
+            "    pushl %gs\n"                                                  \
+            "    pushl %ss\n"                                                  \
+            "    mov $" __STRINGIFY(GDT_SELECTOR_DATA0) ", %ax\n"              \
+            "    mov %ax, %ds\n"                                               \
+            "    mov %ax, %es\n"                                               \
+            "    mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n"               \
+            "    mov %ax, %gs\n"                                               \
+            "    pushl %esp \n" /* set TrapFrame::regs */                      \
+            "    subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n"          \
+            "    pushl %esp \n"                                                \
+            "    cld\n"                                                        \
+            "    call enter_trap_no_irq \n"                                    \
+            "    call " #title "_handler\n"                                    \
+            "    jmp common_trap_exit \n");                                    \
+    }
 
 #elif ARCH(X86_64)
-#define EH_ENTRY(ec, title)                                               \
-    extern "C" void title##_asm_entry();                                  \
-    extern "C" void title##_handler(TrapFrame*) __attribute__((used));    \
-    asm(                                                                  \
-        ".globl " #title "_asm_entry\n"                                   \
-        "" #title "_asm_entry: \n"                                        \
-        "    pushq %r15\n"                                                \
-        "    pushq %r14\n"                                                \
-        "    pushq %r13\n"                                                \
-        "    pushq %r12\n"                                                \
-        "    pushq %r11\n"                                                \
-        "    pushq %r10\n"                                                \
-        "    pushq %r9\n"                                                 \
-        "    pushq %r8\n"                                                 \
-        "    pushq %rax\n"                                                \
-        "    pushq %rcx\n"                                                \
-        "    pushq %rdx\n"                                                \
-        "    pushq %rbx\n"                                                \
-        "    pushq %rsp\n"                                                \
-        "    pushq %rbp\n"                                                \
-        "    pushq %rsi\n"                                                \
-        "    pushq %rdi\n"                                                \
-        "    pushq %rsp \n" /* set TrapFrame::regs */                     \
-        "    subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n"         \
-        "    subq $0x8, %rsp\n" /* align stack */                         \
-        "    lea 0x8(%rsp), %rdi \n"                                      \
-        "    cld\n"                                                       \
-        "    call enter_trap_no_irq \n"                                   \
-        "    lea 0x8(%rsp), %rdi \n"                                      \
-        "    call " #title "_handler\n"                                   \
-        "    addq $0x8, %rsp\n" /* undo alignment */                      \
-        "    jmp common_trap_exit \n");
-
-#define EH_ENTRY_NO_CODE(ec, title)                                       \
-    extern "C" void title##_handler(TrapFrame*) __attribute__((used));    \
-    extern "C" void title##_asm_entry();                                  \
-asm(                                                                      \
-        ".globl " #title "_asm_entry\n"                                   \
-        "" #title "_asm_entry: \n"                                        \
-        "    pushq $0x0\n"                                                \
-        "    pushq %r15\n"                                                \
-        "    pushq %r14\n"                                                \
-        "    pushq %r13\n"                                                \
-        "    pushq %r12\n"                                                \
-        "    pushq %r11\n"                                                \
-        "    pushq %r10\n"                                                \
-        "    pushq %r9\n"                                                 \
-        "    pushq %r8\n"                                                 \
-        "    pushq %rax\n"                                                \
-        "    pushq %rcx\n"                                                \
-        "    pushq %rdx\n"                                                \
-        "    pushq %rbx\n"                                                \
-        "    pushq %rsp\n"                                                \
-        "    pushq %rbp\n"                                                \
-        "    pushq %rsi\n"                                                \
-        "    pushq %rdi\n"                                                \
-        "    pushq %rsp \n" /* set TrapFrame::regs */                     \
-        "    subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n"         \
-        "    movq %rsp, %rdi \n"                                          \
-        "    cld\n"                                                       \
-        "    call enter_trap_no_irq \n"                                   \
-        "    movq %rsp, %rdi \n"                                          \
-        "    call " #title "_handler\n"                                   \
-        "    jmp common_trap_exit \n");
+#define EH_ENTRY(ec, title)                                                    \
+    extern "C" void title##_asm_entry();                                       \
+    extern "C" void title##_handler(TrapFrame*) __attribute__((used));         \
+    NAKED void title##_asm_entry(){                                            \
+        asm(                                                                   \
+            "    pushq %r15\n"                                                 \
+            "    pushq %r14\n"                                                 \
+            "    pushq %r13\n"                                                 \
+            "    pushq %r12\n"                                                 \
+            "    pushq %r11\n"                                                 \
+            "    pushq %r10\n"                                                 \
+            "    pushq %r9\n"                                                  \
+            "    pushq %r8\n"                                                  \
+            "    pushq %rax\n"                                                 \
+            "    pushq %rcx\n"                                                 \
+            "    pushq %rdx\n"                                                 \
+            "    pushq %rbx\n"                                                 \
+            "    pushq %rsp\n"                                                 \
+            "    pushq %rbp\n"                                                 \
+            "    pushq %rsi\n"                                                 \
+            "    pushq %rdi\n"                                                 \
+            "    pushq %rsp \n" /* set TrapFrame::regs */                      \
+            "    subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n"          \
+            "    subq $0x8, %rsp\n" /* align stack */                          \
+            "    lea 0x8(%rsp), %rdi \n"                                       \
+            "    cld\n"                                                        \
+            "    call enter_trap_no_irq \n"                                    \
+            "    lea 0x8(%rsp), %rdi \n"                                       \
+            "    call " #title "_handler\n"                                    \
+            "    addq $0x8, %rsp\n" /* undo alignment */                       \
+            "    jmp common_trap_exit \n");                                    \
+    }
+
+#define EH_ENTRY_NO_CODE(ec, title)                                            \
+    extern "C" void title##_handler(TrapFrame*) __attribute__((used));         \
+    extern "C" void title##_asm_entry();                                       \
+    NAKED void title##_asm_entry(){                                            \
+        asm(                                                                   \
+            "    pushq $0x0\n"                                                 \
+            "    pushq %r15\n"                                                 \
+            "    pushq %r14\n"                                                 \
+            "    pushq %r13\n"                                                 \
+            "    pushq %r12\n"                                                 \
+            "    pushq %r11\n"                                                 \
+            "    pushq %r10\n"                                                 \
+            "    pushq %r9\n"                                                  \
+            "    pushq %r8\n"                                                  \
+            "    pushq %rax\n"                                                 \
+            "    pushq %rcx\n"                                                 \
+            "    pushq %rdx\n"                                                 \
+            "    pushq %rbx\n"                                                 \
+            "    pushq %rsp\n"                                                 \
+            "    pushq %rbp\n"                                                 \
+            "    pushq %rsi\n"                                                 \
+            "    pushq %rdi\n"                                                 \
+            "    pushq %rsp \n" /* set TrapFrame::regs */                      \
+            "    subq $" __STRINGIFY(TRAP_FRAME_SIZE - 8) ", %rsp \n"          \
+            "    movq %rsp, %rdi \n"                                           \
+            "    cld\n"                                                        \
+            "    call enter_trap_no_irq \n"                                    \
+            "    movq %rsp, %rdi \n"                                           \
+            "    call " #title "_handler\n"                                    \
+            "    jmp common_trap_exit \n");                                    \
+    }
 #endif
 
 // clang-format on

+ 0 - 4
Kernel/Arch/x86/common/Processor.cpp

@@ -37,10 +37,6 @@ static volatile bool s_smp_enabled;
 static Atomic<ProcessorMessage*> s_message_pool;
 Atomic<u32> Processor::s_idle_cpu_mask { 0 };
 
-extern "C" void thread_context_first_enter(void);
-extern "C" void exit_kernel_thread(void);
-extern "C" void do_assume_context(Thread* thread, u32 flags);
-
 // The compiler can't see the calls to these functions inside assembly.
 // Declare them, to avoid dead code warnings.
 extern "C" void context_first_init(Thread* from_thread, Thread* to_thread, TrapFrame* trap) __attribute__((used));

+ 39 - 40
Kernel/Arch/x86/i386/Processor.cpp

@@ -16,47 +16,47 @@
 namespace Kernel {
 
 #define ENTER_THREAD_CONTEXT_ARGS_SIZE (2 * 4) //  to_thread, from_thread
-extern "C" void thread_context_first_enter(void);
-extern "C" void exit_kernel_thread(void);
 
-// clang-format off
-asm(
-// enter_thread_context returns to here first time a thread is executing
-".globl thread_context_first_enter \n"
-"thread_context_first_enter: \n"
-// switch_context will have pushed from_thread and to_thread to our new
-// stack prior to thread_context_first_enter() being called, and the
-// pointer to TrapFrame was the top of the stack before that
-"    movl 8(%esp), %ebx \n" // save pointer to TrapFrame
-"    cld \n"
-"    call context_first_init \n"
-"    addl $" __STRINGIFY(ENTER_THREAD_CONTEXT_ARGS_SIZE) ", %esp \n"
-"    movl %ebx, 0(%esp) \n" // push pointer to TrapFrame
-"    jmp common_trap_exit \n"
-);
-// clang-format on
+NAKED void thread_context_first_enter(void)
+{
+    // clang-format off
+    // enter_thread_context returns to here first time a thread is executing
+    asm(
+    // switch_context will have pushed from_thread and to_thread to our new
+    // stack prior to thread_context_first_enter() being called, and the
+    // pointer to TrapFrame was the top of the stack before that
+    "    movl 8(%esp), %ebx \n" // save pointer to TrapFrame
+    "    cld \n"
+    "    call context_first_init \n"
+    "    addl $" __STRINGIFY(ENTER_THREAD_CONTEXT_ARGS_SIZE) ", %esp \n"
+    "    movl %ebx, 0(%esp) \n" // push pointer to TrapFrame
+    "    jmp common_trap_exit \n");
+    // clang-format on
+}
 
-// clang-format off
-asm(
-".global do_assume_context \n"
-"do_assume_context: \n"
-"    movl 4(%esp), %ebx \n"
-"    movl 8(%esp), %esi \n"
-// We're going to call Processor::init_context, so just make sure
-// we have enough stack space so we don't stomp over it
-"    subl $(" __STRINGIFY(4 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 4) "), %esp \n"
-"    pushl %esi \n"
-"    pushl %ebx \n"
-"    cld \n"
-"    call do_init_context \n"
-"    addl $8, %esp \n"
-"    movl %eax, %esp \n" // move stack pointer to what Processor::init_context set up for us
-"    pushl %ebx \n" // push to_thread
-"    pushl %ebx \n" // push from_thread
-"    pushl $thread_context_first_enter \n" // should be same as regs.eip
-"    jmp enter_thread_context \n"
-);
-// clang-format on
+NAKED void do_assume_context(Thread*, u32)
+{
+    // clang-format off
+    // FIXME: I hope (Thread* thread, u32 flags) aren't compiled away
+    asm(
+    "    movl 4(%esp), %ebx \n"
+    "    movl 8(%esp), %esi \n"
+    // We're going to call Processor::init_context, so just make sure
+    // we have enough stack space so we don't stomp over it
+    "    subl $(" __STRINGIFY(4 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 4) "), %esp \n"
+    "    pushl %esi \n"
+    "    pushl %ebx \n"
+    "    cld \n"
+    "    call do_init_context \n"
+    "    addl $8, %esp \n"
+    "    movl %eax, %esp \n" // move stack pointer to what Processor::init_context set up for us
+    "    pushl %ebx \n" // push to_thread
+    "    pushl %ebx \n" // push from_thread
+    "    pushl $thread_context_first_enter \n" // should be same as regs.eip
+    "    jmp enter_thread_context \n"
+    );
+    // clang-format on
+}
 
 String Processor::platform_string() const
 {
@@ -273,5 +273,4 @@ UNMAP_AFTER_INIT void Processor::initialize_context_switching(Thread& initial_th
 
     VERIFY_NOT_REACHED();
 }
-
 }

+ 36 - 40
Kernel/Arch/x86/x86_64/Processor.cpp

@@ -15,47 +15,43 @@
 
 namespace Kernel {
 
-extern "C" void thread_context_first_enter(void);
-extern "C" void exit_kernel_thread(void);
-
-// clang-format off
-asm(
-// enter_thread_context returns to here first time a thread is executing
-".globl thread_context_first_enter \n"
-"thread_context_first_enter: \n"
-// switch_context will have pushed from_thread and to_thread to our new
-// stack prior to thread_context_first_enter() being called, and the
-// pointer to TrapFrame was the top of the stack before that
-"    popq %rdi \n" // from_thread (argument 0)
-"    popq %rsi \n" // to_thread (argument 1)
-"    popq %rdx \n" // pointer to TrapFrame (argument 2)
-"    cld \n"
-"    call context_first_init \n"
-"    jmp common_trap_exit \n"
-);
-// clang-format on
+NAKED void thread_context_first_enter(void)
+{
+    // enter_thread_context returns to here first time a thread is executing
+    asm(
+        // switch_context will have pushed from_thread and to_thread to our news
+        // stack prior to thread_context_first_enter() being called, and the
+        // pointer to TrapFrame was the top of the stack before that
+        "    popq %rdi \n" // from_thread (argument 0)
+        "    popq %rsi \n" // to_thread (argument 1)
+        "    popq %rdx \n" // pointer to TrapFrame (argument 2)
+        "    cld \n"
+        "    call context_first_init \n"
+        "    jmp common_trap_exit \n");
+};
 
-// clang-format off
-asm(
-".global do_assume_context \n"
-"do_assume_context: \n"
-"    movq %rdi, %r12 \n" // save thread ptr
-"    movq %rsi, %r13 \n" // save flags
-// We're going to call Processor::init_context, so just make sure
-// we have enough stack space so we don't stomp over it
-"    subq $(" __STRINGIFY(16 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 8) "), %rsp \n"
-"    cld \n"
-"    call do_init_context \n"
-"    movq %rax, %rsp \n" // move stack pointer to what Processor::init_context set up for us
-"    movq %r12, %rdi \n" // to_thread
-"    movq %r12, %rsi \n" // from_thread
-"    pushq %r12 \n" // to_thread (for thread_context_first_enter)
-"    pushq %r12 \n" // from_thread (for thread_context_first_enter)
-"    movabs $thread_context_first_enter, %r12 \n" // should be same as regs.rip
-"    pushq %r12 \n"
-"    jmp enter_thread_context \n"
-);
-// clang-format on
+NAKED void do_assume_context(Thread*, u32)
+{
+    // clang-format off
+    // FIXME: I hope (Thread* thread, u32 flags) aren't compiled away
+    asm(
+        "    movq %rdi, %r12 \n" // save thread ptr
+        "    movq %rsi, %r13 \n" // save flags
+        // We're going to call Processor::init_context, so just make sure
+        // we have enough stack space so we don't stomp over it
+        "    subq $(" __STRINGIFY(16 + REGISTER_STATE_SIZE + TRAP_FRAME_SIZE + 8) "), %rsp \n"
+        "    cld \n"
+        "    call do_init_context \n"
+        "    movq %rax, %rsp \n"                          // move stack pointer to what Processor::init_context set up for us
+        "    movq %r12, %rdi \n"                          // to_thread
+        "    movq %r12, %rsi \n"                          // from_thread
+        "    pushq %r12 \n"                               // to_thread (for thread_context_first_enter)
+        "    pushq %r12 \n"                               // from_thread (for thread_context_first_enter)
+        "    movabs $thread_context_first_enter, %r12 \n" // should be same as regs.rip
+        "    pushq %r12 \n"
+        "    jmp enter_thread_context \n");
+    // clang-format on
+}
 
 String Processor::platform_string() const
 {

+ 1 - 6
Kernel/Syscall.cpp

@@ -19,14 +19,11 @@ namespace Kernel {
 extern "C" void syscall_handler(TrapFrame*) __attribute__((used));
 extern "C" void syscall_asm_entry();
 
-static void syscall_asm_entry_dummy() __attribute__((used));
-NEVER_INLINE void syscall_asm_entry_dummy()
+NEVER_INLINE NAKED void syscall_asm_entry()
 {
     // clang-format off
 #if ARCH(I386)
     asm(
-        ".globl syscall_asm_entry\n"
-        "syscall_asm_entry:\n"
         "    pushl $0x0\n"
         "    pusha\n"
         "    pushl %ds\n"
@@ -53,8 +50,6 @@ NEVER_INLINE void syscall_asm_entry_dummy()
         "    jmp common_trap_exit \n");
 #elif ARCH(X86_64)
     asm(
-        ".globl syscall_asm_entry\n"
-        "syscall_asm_entry:\n"
         "    pushq $0x0\n"
         "    pushq %r15\n"
         "    pushq %r14\n"