diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 074419dc..3bb07226 100755 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -7,7 +7,8 @@ include_directories("${CMAKE_SOURCE_DIR}/apps/include/c") include_directories("${CMAKE_SOURCE_DIR}/apps/include/c++") link_directories("${CMAKE_SOURCE_DIR}/apps/lib") -add_exe_link_flag("-static -Wl,-Ttext=0x80000000 -e __libc_start_main") +add_exe_link_flag("-Wl,--export-dynamic-symbol=main") +add_exe_link_flag("-Wl,-Ttext=0x80000000 -e __libc_start_main") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12) add_exe_link_flag("-Wl,--image-base=0x78000000") @@ -23,11 +24,10 @@ file( "${CMAKE_SOURCE_DIR}/apps/*") list(REMOVE_ITEM SUBDIRS "include" "lib") foreach(SUBDIR ${SUBDIRS}) - if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/apps/${SUBDIR}") - if(EXISTS "${CMAKE_SOURCE_DIR}/apps/${SUBDIR}/CMakeLists.txt") - add_subdirectory(${SUBDIR}) - set(TARGETS ${TARGETS} ${SUBDIR}) - endif() + if(EXISTS "${CMAKE_SOURCE_DIR}/apps/${SUBDIR}/CMakeLists.txt") + add_subdirectory(${SUBDIR}) + target_sources(${SUBDIR} PRIVATE "${CMAKE_SOURCE_DIR}/apps/crt0.asm") + set(TARGETS ${TARGETS} ${SUBDIR}) elseif(EXISTS "${CMAKE_SOURCE_DIR}/apps/${SUBDIR}/Makefile") add_custom_target( ${SUBDIR} diff --git a/apps/crt0.asm b/apps/crt0.asm new file mode 100644 index 00000000..4437acd6 --- /dev/null +++ b/apps/crt0.asm @@ -0,0 +1,15 @@ + [bits 32] + extern main, __libc_start_main + section .text +_start: + push main + push edx + push esi + push edi + call __libc_start_main + mov ebx, 0xffff + mov eax, 0 + int 0x36 + ud2 + int 3 + jmp $ diff --git a/apps/file/CMakeLists.txt b/apps/file/CMakeLists.txt index e2c8e189..d4c90d10 100755 --- a/apps/file/CMakeLists.txt +++ b/apps/file/CMakeLists.txt @@ -1,2 +1,2 @@ -add_binary(app-file) -target_link_libraries(app-file misc magic) +add_binary(file) +target_link_libraries(file misc magic) diff --git a/cmake/mklib b/cmake/mklib index aa096bfe..9107b410 100755 --- a/cmake/mklib +++ b/cmake/mklib @@ -1,18 +1,22 @@ macro(addlib arg1) - # add_library(${arg1} SHARED ${ARGN}) - # add_library(${arg1}-s STATIC ${ARGN}) - add_library(${arg1} STATIC ${ARGN}) - # set_target_properties(${arg1}-s PROPERTIES OUTPUT_NAME ${arg1}) + add_library(${arg1} SHARED ${ARGN}) + add_library(${arg1}-s STATIC ${ARGN}) + set_target_properties(${arg1}-s PROPERTIES OUTPUT_NAME ${arg1}) + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + target_link_options(${arg1} PRIVATE -Wl,-z,notext) + endif() endmacro(addlib) macro(tgtlib arg1) - # target_link_libraries(${arg1} ${ARGN}) - # target_link_libraries(${arg1}-s ${ARGN}) target_link_libraries(${arg1} ${ARGN}) + set(ARGN_S ${ARGN}) + list(TRANSFORM ARGN_S REPLACE "(.+)" "\\1-s") + target_link_libraries(${arg1}-s ${ARGN_S}) endmacro(tgtlib) macro(libdef arg1) target_compile_definitions(${arg1} PRIVATE ${ARGN}) + target_compile_definitions(${arg1}-s PRIVATE ${ARGN}) endmacro(libdef) macro(testexec arg1) diff --git a/include/define/config/plos.h b/include/define/config/plos.h index 67028af2..6e28b430 100644 --- a/include/define/config/plos.h +++ b/include/define/config/plos.h @@ -1,7 +1,7 @@ #define SYSCALL_USE_INTERRPUT 0 -#define PLOS_LOGGING 0 +#define PLOS_LOGGING 2 #define PLOS_LOGGING_PRINTS 0 diff --git a/include/elf.h b/include/elf.h index c1ad7a6b..6f2cc8d4 100755 --- a/include/elf.h +++ b/include/elf.h @@ -164,7 +164,7 @@ typedef struct Elf32ProgramHeader { u32 type; u32 offset; u32 vaddr; - u32 paddr; + u32 paddr; // (ignored) u32 filesz; u32 memsz; u32 flags; @@ -177,26 +177,182 @@ typedef struct Elf64ProgramHeader { u32 flags; u64 offset; u64 vaddr; - u64 paddr; + u64 paddr; // (ignored) u64 filesz; u64 memsz; u64 align; } Elf64ProgramHeader; #endif -#define ELF_PROGRAM_TYPE_NULL 0 // Program header table entry unused. -#define ELF_PROGRAM_TYPE_LOAD 1 // Loadable segment. -#define ELF_PROGRAM_TYPE_DYNAMIC 2 // Dynamic linking information. -#define ELF_PROGRAM_TYPE_INTERP 3 // Interpreter information. -#define ELF_PROGRAM_TYPE_NOTE 4 // Auxiliary information. -#define ELF_PROGRAM_TYPE_SHLIB 5 // Reserved. -#define ELF_PROGRAM_TYPE_PHDR 6 // Segment containing program header table itself. -#define ELF_PROGRAM_TYPE_TLS 7 // Thread-Local Storage template. -#define ELF_PROGRAM_TYPE_LOOS 0x60000000 -#define ELF_PROGRAM_TYPE_HIOS 0x6FFFFFFF -#define ELF_PROGRAM_TYPE_LOPROC 0x70000000 -#define ELF_PROGRAM_TYPE_HIPROC 0x7fffffff +#define ELF_PROGRAM_TYPE_NULL 0 // Program header table entry unused. +#define ELF_PROGRAM_TYPE_LOAD 1 // Loadable segment. +#define ELF_PROGRAM_TYPE_DYNAMIC 2 // Dynamic linking information. +#define ELF_PROGRAM_TYPE_INTERP 3 // Interpreter information. +#define ELF_PROGRAM_TYPE_NOTE 4 // Auxiliary information. +#define ELF_PROGRAM_TYPE_SHLIB 5 // Reserved. +#define ELF_PROGRAM_TYPE_PHDR 6 // Segment containing program header table itself. +#define ELF_PROGRAM_TYPE_TLS 7 // Thread-Local Storage template. +#define ELF_PROGRAM_TYPE_LOOS 0x60000000 +#define ELF_PROGRAM_TYPE_HIOS 0x6FFFFFFF +#define ELF_PROGRAM_TYPE_LOPROC 0x70000000 +#define ELF_PROGRAM_TYPE_HIPROC 0x7fffffff +#define ELF_PROGRAM_TYPE_GNU_STACK 0x6474e551 #define ELF_PROGRAM_FLAG_EXEC MASK(0) #define ELF_PROGRAM_FLAG_WRITE MASK(1) #define ELF_PROGRAM_FLAG_READ MASK(2) + +// -------------------------------------------------- +//; Dynamic Section + +typedef struct Elf32Dynamic { + u32 tag; + u32 value; +} Elf32Dynamic; + +#ifdef __x86_64__ +typedef struct Elf64Dynamic { + u64 tag; + u64 value; +} Elf64Dynamic; +#endif + +#define ELF_DYNAMIC_NULL 0 // 结束标记 +#define ELF_DYNAMIC_NEEDED 1 // 依赖库 +#define ELF_DYNAMIC_PLTRELSZ 2 // 重定位表大小 +#define ELF_DYNAMIC_PLTGOT 3 // 重定位表地址 +#define ELF_DYNAMIC_HASH 4 // 符号哈希表地址 +#define ELF_DYNAMIC_STRTAB 5 // 字符串表地址 +#define ELF_DYNAMIC_SYMTAB 6 // 符号表地址 +#define ELF_DYNAMIC_RELA 7 +#define ELF_DYNAMIC_RELASZ 8 +#define ELF_DYNAMIC_RELAENT 9 +#define ELF_DYNAMIC_STRSZ 10 +#define ELF_DYNAMIC_SYMENT 11 +#define ELF_DYNAMIC_INIT 12 // 初始化函数地址 +#define ELF_DYNAMIC_FINI 13 // 结束函数地址 +#define ELF_DYNAMIC_SONAME 14 +#define ELF_DYNAMIC_RPATH 15 +#define ELF_DYNAMIC_SYMBOLIC 16 +#define ELF_DYNAMIC_REL 17 +#define ELF_DYNAMIC_RELSZ 18 +#define ELF_DYNAMIC_RELENT 19 +#define ELF_DYNAMIC_PLTREL 20 +#define ELF_DYNAMIC_DEBUG 21 +#define ELF_DYNAMIC_TEXTREL 22 +#define ELF_DYNAMIC_JMPREL 23 +#define ELF_DYNAMIC_BIND_NOW 24 +#define ELF_DYNAMIC_INIT_ARRAY 25 +#define ELF_DYNAMIC_FINI_ARRAY 26 +#define ELF_DYNAMIC_INIT_ARRAYSZ 27 +#define ELF_DYNAMIC_FINI_ARRAYSZ 28 +#define ELF_DYNAMIC_RUNPATH 29 +#define ELF_DYNAMIC_FLAGS 30 +#define ELF_DYNAMIC_ENCODING 32 +#define ELF_DYNAMIC_PREINIT_ARRAY 32 +#define ELF_DYNAMIC_PREINIT_ARRAYSZ 33 +#define ELF_DYNAMIC_MAXPOSTAGS 34 +#define ELF_DYNAMIC_GNU_HASH 0x6ffffef5 + +// -------------------------------------------------- +//; Symbol Table + +typedef struct Elf32Symbol { + u32 name; + u32 value; + u32 size; + u8 info; + u8 other; + u16 shndx; +} Elf32Symbol; + +#ifdef __x86_64__ +typedef struct Elf64Symbol { + u32 name; + u8 info; + u8 other; + u16 shndx; + u64 value; + u64 size; +} Elf64Symbol; +#endif + +// -------------------------------------------------- +//; Hash Table + +typedef struct Elf32Hash { + u32 nbucket; + u32 nchain; + u32 bucket; + u32 chain; +} Elf32Hash; + +typedef struct Elf64Hash { + u32 nbucket; + u32 nchain; + u32 bucket; + u32 chain; +} Elf64Hash; + +finline u32 elf_hash(cstr name) { + u32 h = 0; + for (usize i = 0; name[i] != '\0'; i++) { + h <<= 4; + h += name[i]; + u32 g = h & 0xf0000000; + h ^= g; + h ^= g >> 24; + } + return h; +} + +typedef struct Elf32GnuHash { + u32 nbuckets; + u32 symndx; + u32 maskwords; + u32 shift2; + u32 bloom[1]; +} Elf32GnuHash; + +// -------------------------------------------------- +//; elf 加载时数据 + +typedef void (*ElfInitFunc)(); +typedef void (*ElfFiniFunc)(); + +typedef struct Elf { + cstr path; // 文件路径 (不属于结构体所有) + usize size; // 文件大小 + union { + const void *data; + const ElfIdent *ident; + const Elf32Header *header32; +#ifdef __x86_64__ + const Elf64Header *header64; +#endif + }; + i32 errcode; + + cstr strtab; + + union { + const Elf32Symbol *sym32; +#ifdef __x86_64__ + const Elf64Symbol *sym64; +#endif + }; + + union { + const Elf32Hash *hash32; +#ifdef __x86_64__ + const Elf32Hash *hash64; +#endif + }; + + ElfInitFunc init; + ElfFiniFunc fini; + const ElfInitFunc *init_array; + usize init_array_len; + const ElfFiniFunc *fini_array; + usize fini_array_len; +} Elf; diff --git a/include/kernel/cpu.h b/include/kernel/cpu.h index 9b030313..eec5ea43 100755 --- a/include/kernel/cpu.h +++ b/include/kernel/cpu.h @@ -20,14 +20,12 @@ typedef struct { u32 eip; } stack_frame; -#define SA_RPL_MASK 0xFFFC -#define SA_TI_MASK 0xFFFB -#define SA_TIL 4 // 设置此项,将从LDT中寻找 #define SA_RPL0 0 #define SA_RPL1 1 #define SA_RPL2 2 #define SA_RPL3 3 -#define GET_SEL(cs, rpl) ((cs & SA_RPL_MASK & SA_TI_MASK) | (rpl)) +#define SA_TIL 4 // 设置此项,将从LDT中寻找 +#define GET_SEL(cs, rpl) (((cs) & 0xfff8) | (rpl)) typedef struct __PACKED__ TSS32 { u32 backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3; diff --git a/include/libc-base.h b/include/libc-base.h index 65cf5256..274ecde2 100755 --- a/include/libc-base.h +++ b/include/libc-base.h @@ -13,6 +13,7 @@ extern "C" { #include "libc-base/asm/cpuid/ids.h" #include "libc-base/asm/cpuid/macros.h" #include "libc-base/asm/cr.h" +#include "libc-base/asm/flags.h" #include "libc-base/asm/io.h" #include "libc-base/asm/mem.h" #include "libc-base/asm/msr.h" diff --git a/include/libc-base/asm.h b/include/libc-base/asm.h index 2737cd36..d1c1dfcf 100644 --- a/include/libc-base/asm.h +++ b/include/libc-base/asm.h @@ -11,6 +11,7 @@ extern "C" { #include "asm/cpuid/ids.h" #include "asm/cpuid/macros.h" #include "asm/cr.h" +#include "asm/flags.h" #include "asm/io.h" #include "asm/mem.h" #include "asm/msr.h" diff --git a/include/libc-base/asm/flags.h b/include/libc-base/asm/flags.h new file mode 100644 index 00000000..bdea41f1 --- /dev/null +++ b/include/libc-base/asm/flags.h @@ -0,0 +1,63 @@ +#pragma once +#include + +#define asm_get_flags() \ + ({ \ + size_t flags; \ + asm volatile("pushf\n\t" \ + "pop %0\n\t" \ + : "=r"(flags) \ + :); \ + flags; \ + }) + +#define asm_set_flags(flags) \ + ({ \ + asm volatile("push %0\n\t" \ + "popf\n\t" \ + : \ + : "r"((size_t)(flags))); \ + }) + +#define asm_is_sti (asm_get_flags() & (1 << 9)) + +#define asm_is_cli (!asm_is_sti) + +#define FLAGS_CF MASK(0) // 进位标志 +#define FLAGS_PF MASK(2) // 奇偶标志 +#define FLAGS_AF MASK(4) // 辅助进位标志 +#define FLAGS_ZF MASK(6) // 零标志 +#define FLAGS_SF MASK(7) // 符号标志 +#define FLAGS_TF MASK(8) // 跟踪标志 +#define FLAGS_IF MASK(9) // 中断允许标志 +#define FLAGS_DF MASK(10) // 方向标志 +#define FLAGS_OF MASK(11) // 溢出标志 +#define FLAGS_IOPL_0 ((usize)0 << 12) +#define FLAGS_IOPL_1 ((usize)1 << 12) +#define FLAGS_IOPL_2 ((usize)2 << 12) +#define FLAGS_IOPL_3 ((usize)3 << 12) + +typedef struct FLAGS { + usize cf : 1; + usize reserved_1 : 1; + usize pf : 1; + usize reserved_2 : 1; + usize af : 1; + usize reserved_3 : 1; + usize zf : 1; + usize sf : 1; + usize tf : 1; + usize if_ : 1; + usize df : 1; + usize of : 1; + usize iopl : 2; + usize nt : 1; + usize reserved_4 : 1; + usize rf : 1; + usize vm : 1; + usize ac : 1; + usize vif : 1; + usize vip : 1; + usize id : 1; + usize reserved_5 : 10; +} FLAGS; diff --git a/include/libc-base/asm/reg.h b/include/libc-base/asm/reg.h index df84c9f5..3e9dae52 100755 --- a/include/libc-base/asm/reg.h +++ b/include/libc-base/asm/reg.h @@ -1,28 +1,6 @@ #pragma once #include -#define asm_get_flags() \ - ({ \ - size_t flags; \ - asm volatile("pushf\n\t" \ - "pop %0\n\t" \ - : "=r"(flags) \ - :); \ - flags; \ - }) - -#define asm_set_flags(flags) \ - ({ \ - asm volatile("push %0\n\t" \ - "popf\n\t" \ - : \ - : "r"((size_t)(flags))); \ - }) - -#define asm_is_sti (asm_get_flags() & (1 << 9)) - -#define asm_is_cli (!asm_is_sti) - #define asm_get_sp() \ ({ \ size_t sp; \ diff --git a/src/data-structure/CMakeLists.txt b/src/data-structure/CMakeLists.txt index 4b9341e9..552b77f3 100755 --- a/src/data-structure/CMakeLists.txt +++ b/src/data-structure/CMakeLists.txt @@ -1,3 +1 @@ -file(GLOB_RECURSE c_files "*.c") -file(GLOB_RECURSE cpp_files "*.cpp") -add_library(data-structure STATIC ${c_files} ${cpp_files}) +mklib(data-structure) diff --git a/src/elf/CMakeLists.txt b/src/elf/CMakeLists.txt index ab35ae3d..4da848d7 100755 --- a/src/elf/CMakeLists.txt +++ b/src/elf/CMakeLists.txt @@ -1,3 +1 @@ -file(GLOB_RECURSE c_files "*.c") -file(GLOB_RECURSE cpp_files "*.cpp") -add_library(elf STATIC ${c_files} ${cpp_files}) +mklib(elf) diff --git a/src/font/CMakeLists.txt b/src/font/CMakeLists.txt index 9cf7dd50..c9870eb0 100755 --- a/src/font/CMakeLists.txt +++ b/src/font/CMakeLists.txt @@ -1,4 +1,2 @@ -file(GLOB_RECURSE c_files "*.c") -file(GLOB_RECURSE cpp_files "*.cpp") -add_library(font STATIC ${c_files} ${cpp_files}) -target_link_libraries(font c-base data-structure) +mklib(font) +tgtlib(font c-base data-structure) diff --git a/src/fs/CMakeLists.txt b/src/fs/CMakeLists.txt index 1e7116a5..04fd370a 100755 --- a/src/fs/CMakeLists.txt +++ b/src/fs/CMakeLists.txt @@ -1,5 +1,3 @@ -file(GLOB_RECURSE c_files "*.c") -file(GLOB_RECURSE cpp_files "*.cpp") -add_library(fs STATIC ${c_files} ${cpp_files}) -target_link_libraries(fs c-base) -target_compile_definitions(fs PRIVATE RING0=1) +mklib(fs) +tgtlib(fs c-base) +libdef(fs PRIVATE RING0=1) diff --git a/src/kernel/CMakeLists.txt b/src/kernel/CMakeLists.txt index 099844c3..b64ccd4e 100755 --- a/src/kernel/CMakeLists.txt +++ b/src/kernel/CMakeLists.txt @@ -9,15 +9,7 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_exe_link_flag("-Wl,--image-base=0x200000") endif() add_binary_exclude(kernel cpu/v86_service.asm) -target_link_libraries(kernel c-base data-structure fs elf) -target_link_libraries( - kernel - font - plty - audio - c-base - plreadln - sound - magic) +target_link_libraries(kernel c-base-s data-structure-s fs-s elf-s magic-s) +target_link_libraries(kernel font-s plty-s audio-s plreadln-s sound-s) target_compile_definitions(kernel PRIVATE RING0=1 KERNEL=1) add_binary_asm_no_elf(v86_service cpu/v86_service.asm) diff --git a/src/kernel/exec/elf.c b/src/kernel/exec/elf.c index 540fb98f..e3f2ac0d 100755 --- a/src/kernel/exec/elf.c +++ b/src/kernel/exec/elf.c @@ -18,7 +18,7 @@ void load_segment(const Elf32ProgramHeader *prog, const void *elf) { if (prog->memsz < prog->filesz) return; val hi = PADDING_UP(prog->vaddr + prog->memsz, PAGE_SIZE); val lo = PADDING_DOWN(prog->vaddr, PAGE_SIZE); - for (size_t i = lo; i < hi; i += PAGE_SIZE) { + for (usize i = lo; i < hi; i += PAGE_SIZE) { page_link(i); } memcpy((void *)prog->vaddr, elf + prog->offset, prog->filesz); diff --git a/src/kernel/exec/exec.c b/src/kernel/exec/exec.c index 73ea3d97..c1d419cf 100755 --- a/src/kernel/exec/exec.c +++ b/src/kernel/exec/exec.c @@ -13,22 +13,22 @@ extern PageInfo *pages; void task_app() { klogd("%s", current_task->command_line); - klogd("%08x", current_task->stack_bottom); - cir_queue8_t kfifo = malloc(sizeof(struct cir_queue8)); - cir_queue8_t mfifo = malloc(sizeof(struct cir_queue8)); + + cir_queue8_t kfifo = xmalloc(sizeof(struct cir_queue8)); + cir_queue8_t mfifo = xmalloc(sizeof(struct cir_queue8)); var kbuf = page_malloc_one(); var mbuf = page_malloc_one(); cir_queue8_init(kfifo, 4096, kbuf); cir_queue8_init(mfifo, 4096, mbuf); - task_set_fifo(current_task, kfifo, mfifo); + u32 pde = current_task->cr3; asm_cli; asm_set_cr3(PD_ADDRESS); current_task->cr3 = PD_ADDRESS; - klogd("P1 %08x", current_task->cr3); - for (int i = PDI(0x70000000) * 4; i < PAGE_SIZE; i += 4) { - u32 *pde_entry = (u32 *)(pde + i); + + for (int i = PDI(ADDR_TASK_CODE) * 4; i < PAGE_SIZE; i += 4) { + val pde_entry = (u32 *)(pde + i); if ((*pde_entry & PAGE_SHARED) || pages[PIDX(*pde_entry)].count > 1) { if (pages[PIDX(*pde_entry)].count > 1) { @@ -52,9 +52,10 @@ void task_app() { } } } + current_task->cr3 = pde; - asm_sti; asm_set_cr3(pde); + asm_sti; klogd("go to task_to_usermode_elf"); task_to_user_mode_elf(); infinite_loop; @@ -85,14 +86,14 @@ void task_to_user_mode_elf() { regs32 *iframe = (regs32 *)current_task->stack_bottom - 1; *iframe = (regs32){}; - iframe->edi = (size_t)args.argc; - iframe->esi = (size_t)args.argv; - iframe->edx = (size_t)args.envp; + iframe->edi = (usize)args.argc; + iframe->esi = (usize)args.argv; + iframe->edx = (usize)args.envp; iframe->fs = GET_SEL(RING3_DS, SA_RPL3); iframe->es = GET_SEL(RING3_DS, SA_RPL3); iframe->ds = GET_SEL(RING3_DS, SA_RPL3); iframe->cs = GET_SEL(RING3_CS, SA_RPL3); - iframe->flags = (0 << 12 | 0b10 | 1 << 9); + iframe->flags = FLAGS_IOPL_0 | FLAGS_IF | 0b10; iframe->ss = GET_SEL(RING3_DS, SA_RPL3); tss.eflags = iframe->flags; @@ -146,8 +147,6 @@ i32 os_execute(cstr filename, cstr line) { val status = waittid(t->tid); current_task->fifosleep = o; - klogd(); - if (backup) { mouse_ready(&mdec); mouse_use_task = backup; @@ -156,7 +155,5 @@ i32 os_execute(cstr filename, cstr line) { } current_task->sigint_up = old; - klogd(); - return status; } diff --git a/src/kernel/mm/vpage.c b/src/kernel/mm/vpage.c index 4ccb1937..6a32c557 100755 --- a/src/kernel/mm/vpage.c +++ b/src/kernel/mm/vpage.c @@ -49,7 +49,7 @@ void page_set_alloced(PageInfo *pg, u32 start, u32 end) { usize pd_clone(usize addr) { val pd = (PDE *)addr; - for (usize i = PDI(0x70000000); i < 1024; i++) { + for (usize i = PDI(ADDR_TASK_CODE); i < 1024; i++) { var pde = &pd[i]; pages[pde->addr].count++; pde->wrable = false; @@ -69,7 +69,7 @@ usize pd_clone(usize addr) { } static void pd_reset(u32 addr) { - for (usize i = PDI(0x70000000) * 4; i < PAGE_SIZE; i += 4) { + for (usize i = PDI(ADDR_TASK_CODE) * 4; i < PAGE_SIZE; i += 4) { var pde = (PDE *)(addr + i); pde->wrable = true; } @@ -77,7 +77,7 @@ static void pd_reset(u32 addr) { void pd_free(usize addr) { if (addr == PD_ADDRESS) return; - for (usize i = PDI(0x70000000); i < 1024; i++) { + for (usize i = PDI(ADDR_TASK_CODE); i < 1024; i++) { val pde = (PDE *)addr + i; if (!pde->present || !pde->user) continue; for (usize j = 0; j < 1024; j++) { diff --git a/src/kernel/syscall/mmap.c b/src/kernel/syscall/mmap.c index 6cfde964..f82b526f 100755 --- a/src/kernel/syscall/mmap.c +++ b/src/kernel/syscall/mmap.c @@ -16,20 +16,20 @@ void *syscall_mmap(void *start, usize length) { if (start != null) { for (usize i = 0; i < page_count; i++) { - if (page_get_attr((u32)start + i * PAGE_SIZE, cr3) & PAGE_WRABLE) goto _0; + if (page_get_attr((usize)start + i * PAGE_SIZE) & PAGE_USER) goto _0; } line_addr_start = start; goto _1; } _0: - for (usize i = PDI(0x70000000), c = 0; i < 1024; i++) { - u32 *pde_entry = (u32 *)cr3 + i; - u32 p = *pde_entry & (0xfffff000); + for (usize i = PDI(ADDR_TASK_CODE), c = 0; i < 1024; i++) { + val pde_entry = (u32 *)cr3 + i; + u32 p = *pde_entry & 0xfffff000; for (usize j = 0; j < 1024; size_is_2M ? j += 512 : j++) { - u32 *pte_entry = (u32 *)p + j; - if (!(page_get_attr(mk_linear_addr(i, j, 0), cr3) & PAGE_WRABLE)) { - if (c == 0) line_addr_start = (void *)mk_linear_addr(i, j, 0); + val pte_entry = (u32 *)p + j; + if (!(page_get_attr(mk_linear_addr(i, j)) & PAGE_USER)) { + if (c == 0) line_addr_start = (void *)mk_linear_addr(i, j); c++; } else { c = 0; @@ -41,7 +41,7 @@ void *syscall_mmap(void *start, usize length) { klogd("找到了一段空闲的没有被映射的线性地址%p-%p", line_addr_start, line_addr_start + page_count * PAGE_SIZE); for (usize i = 0; i < page_count; i++) { - page_link_share((size_t)line_addr_start + i * PAGE_SIZE); + page_link_share((usize)line_addr_start + i * PAGE_SIZE); } return line_addr_start; } diff --git a/src/kernel/task/shell.c b/src/kernel/task/shell.c index b861f3c3..8450fbe4 100644 --- a/src/kernel/task/shell.c +++ b/src/kernel/task/shell.c @@ -175,7 +175,7 @@ static int print_file(cstr path) { return 0; } -int shell_exec(char *path, cstr comand) { +static int shell_exec(char *path, cstr comand) { if (!strlen(comand)) return 0; int retcode = 0; if (strneq(comand, "echo ", 5)) { diff --git a/src/ld-plos/CMakeLists.txt b/src/ld-plos/CMakeLists.txt index 7f84ae6a..ad7b3f37 100755 --- a/src/ld-plos/CMakeLists.txt +++ b/src/ld-plos/CMakeLists.txt @@ -9,4 +9,4 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_exe_link_flag("-Wl,--image-base=0x70000000") endif() add_binary(ld-plos) -target_link_libraries(ld-plos c-base) +target_link_libraries(ld-plos c-base-s) diff --git a/src/ld-plos/ld-plos.c b/src/ld-plos/ld-plos.c index 80c705bb..652eb349 100644 --- a/src/ld-plos/ld-plos.c +++ b/src/ld-plos/ld-plos.c @@ -10,6 +10,13 @@ static int argc; static char **argv; static char **envp; +finline void println(cstr text) { + syscall(SYSCALL_PRINT, text); + syscall(SYSCALL_PRINT, "\n"); +} + +static i32 load_elf(cstr path, bool run); + // 加载完毕后运行应用程序 static __attr(noreturn) void run(usize entry) { asm("mov %0, %%edi\n\t" ::"r"(argc)); @@ -19,73 +26,140 @@ static __attr(noreturn) void run(usize entry) { __builtin_unreachable(); } -#ifdef __x86_64__ - -static int load_elf32(const Elf32Header *elf) { - return 0; +static void elf32_init(const Elf *file) { + if (file->init != null) file->init(); + if (file->init_array != null) { + for (usize i = 0; i < file->init_array_len; i++) { + file->init_array[i](); + } + } } -static int load_elf64(const Elf64Header *elf) { - return 0; +static void elf32_fini(const Elf *file) { + if (file->fini_array != null) { + for (isize i = file->fini_array_len - 1; i >= 0; i--) { + file->fini_array[i](); + } + } + if (file->fini != null) file->fini(); } -#else - -static int load_segment(const Elf32ProgramHeader *prog, const void *elf) { - if (prog->type != ELF_PROGRAM_TYPE_LOAD) return 0; +static int load_segment_load(const Elf *file, const Elf32ProgramHeader *prog) { usize hi = PADDING_UP(prog->vaddr + prog->memsz, PAGE_SIZE); usize lo = PADDING_DOWN(prog->vaddr, PAGE_SIZE); usize addr = syscall(SYSCALL_MMAP, lo, hi - lo); - if (addr != lo) syscall(SYSCALL_EXIT, 666); - memcpy((void *)prog->vaddr, elf + prog->offset, prog->filesz); + if (addr != lo) return -1; + memcpy((void *)prog->vaddr, file->data + prog->offset, prog->filesz); + return 0; +} + +static int load_segment_dynamic(Elf *file, const Elf32ProgramHeader *prog) { + val dyn = (const Elf32Dynamic *)prog->offset; + for (usize i = 0; dyn[i].tag != ELF_DYNAMIC_NULL; i++) { + val tag = dyn[i].tag; + val value = dyn[i].value; + val ptr = file->data + dyn[i].value; + if (tag == ELF_DYNAMIC_NEEDED) load_elf(ptr, false); + if (tag == ELF_DYNAMIC_HASH) file->hash32 = ptr; + if (tag == ELF_DYNAMIC_GNU_HASH) file->hash32 = ptr; + if (tag == ELF_DYNAMIC_STRTAB) file->strtab = ptr; + if (tag == ELF_DYNAMIC_SYMTAB) file->sym32 = ptr; + if (tag == ELF_DYNAMIC_INIT) file->init = ptr; + if (tag == ELF_DYNAMIC_FINI) file->fini = ptr; + if (tag == ELF_DYNAMIC_INIT_ARRAY) file->init_array = ptr; + if (tag == ELF_DYNAMIC_INIT_ARRAYSZ) file->init_array_len = value / 4; + if (tag == ELF_DYNAMIC_FINI_ARRAY) file->fini_array = ptr; + if (tag == ELF_DYNAMIC_FINI_ARRAYSZ) file->fini_array_len = value / 4; + } return 0; } -static int load_elf32(const Elf32Header *elf) { - var prog = (const Elf32ProgramHeader *)((usize)elf + elf->phoff); - for (usize i = 0; i < elf->phnum; i++) { - if (load_segment(prog + i, elf) < 0) return LDE_FILE_UNPARSABLE; +static int load_segment(Elf *file, const Elf32ProgramHeader *prog) { + if (prog->type == ELF_PROGRAM_TYPE_NULL) return 0; + if (prog->type == ELF_PROGRAM_TYPE_LOAD) return load_segment_load(file, prog); + if (prog->type == ELF_PROGRAM_TYPE_DYNAMIC) return load_segment_dynamic(file, prog); + if (prog->type == ELF_PROGRAM_TYPE_NOTE) return 0; + if (prog->type == ELF_PROGRAM_TYPE_TLS) return load_segment_load(file, prog); + if (prog->type == ELF_PROGRAM_TYPE_PHDR) return 0; + if (prog->type == ELF_PROGRAM_TYPE_GNU_STACK) return 0; + return -1; +} + +static int load_elf32(Elf *file, const Elf32Header *header) { + var prog = (const Elf32ProgramHeader *)((usize)header + header->phoff); + for (usize i = 0; i < header->phnum; i++) { + if (load_segment(file, prog + i) < 0) return LDE_FILE_UNPARSABLE; } - run(elf->entry); + elf32_init(file); + val entry = header->entry; + syscall(SYSCALL_MUNMAP, file->data, file->size); + syscall(SYSCALL_MUNMAP, file, sizeof(Elf)); + run(entry); } -static int load_elf64(const void *elf) { - // Can't load 64-bit ELF in 32-bit system. - return LDE_ARCH_MISSMATCH; +#ifdef __x86_64__ + +static int load_elf64(Elf *elf, const Elf64Header *header) { + syscall(SYSCALL_MUNMAP, elf, elf->size); + return 0; } #endif -static int __linker_main(int argc, char **argv, char **envp) { - if (argc <= 0 || argv == null || envp == null || argv[0] == null) return LDE_INVALID_INPUT; +static usize elf_file_map_addr = 0xb0000000; - isize size = syscall(SYSCALL_FILE_SIZE, argv[0]); +static i32 load_elf(cstr path, bool run) { + const isize size = syscall(SYSCALL_FILE_SIZE, path); if (size < 0) return LDE_FILE_NOT_FOUND; - void *file = (void *)syscall(SYSCALL_MMAP, null, size); + + Elf *file = (void *)syscall(SYSCALL_MMAP, elf_file_map_addr, sizeof(Elf)); if (file == null) return LDE_OUT_OF_MEMORY; - if (syscall(SYSCALL_LOAD_FILE, argv[0], file, size) < 0) return LDE_FILE_UNREADABLE; + elf_file_map_addr += PADDING_UP(sizeof(Elf), PAGE_SIZE); + + file->data = (void *)syscall(SYSCALL_MMAP, elf_file_map_addr, size); + if (file->data == null) return LDE_OUT_OF_MEMORY; + elf_file_map_addr += PADDING_UP(size, PAGE_SIZE); + + if (syscall(SYSCALL_LOAD_FILE, path, file->data, size) < 0) return LDE_FILE_UNREADABLE; - const Elf32Header *elf = (Elf32Header *)file; - const ElfIdent *ident = (ElfIdent *)file; - if (ident->magic != ELF_MAGIC) return 1; + val ident = file->ident; + if (ident->magic != ELF_MAGIC) return LDE_FILE_UNPARSABLE; if (ident->class == ELF_CLASS_32) { - if (elf->machine != ELF_MACHINE_IA32) return LDE_ARCH_MISSMATCH; - return load_elf32(file); + val header = file->header32; + if (header->machine != ELF_MACHINE_IA32) return LDE_ARCH_MISSMATCH; + return load_elf32(file, header); } if (ident->class == ELF_CLASS_64) { - if (elf->machine != ELF_MACHINE_AMD64) return LDE_ARCH_MISSMATCH; - return load_elf64(file); +#ifdef __x86_64__ + val header = file->header64; + if (header->machine != ELF_MACHINE_AMD64) return LDE_ARCH_MISSMATCH; + return load_elf64(file, header); +#else + // Can't load 64-bit ELF in 32-bit system. + syscall(SYSCALL_MUNMAP, file->data, file->size); + syscall(SYSCALL_MUNMAP, file, sizeof(Elf)); + return LDE_ARCH_MISSMATCH; +#endif } return LDE_FILE_UNPARSABLE; } +static i32 __linker_main(int argc, char **argv, char **envp) { + if (argc <= 0 || argv == null || envp == null || argv[0] == null) return LDE_INVALID_INPUT; + return load_elf(argv[0], true); +} + void __linker_start() { asm("mov %%edi, %0\n\t" : "=r"(argc)); asm("mov %%esi, %0\n\t" : "=r"(argv)); asm("mov %%edx, %0\n\t" : "=r"(envp)); - int errcode = __linker_main(argc, argv, envp); + val errcode = __linker_main(argc, argv, envp); syscall(SYSCALL_EXIT, MASK(30) | MASK(29) | (errcode << 16)); } + +void __linker_handler() { + // +} diff --git a/src/libc-base/stdio/stbsp.c b/src/libc-base/stdio/stbsp.c index 9a6d2ad7..1a83a4e6 100755 --- a/src/libc-base/stdio/stbsp.c +++ b/src/libc-base/stdio/stbsp.c @@ -9,7 +9,7 @@ # define STB_SPRINTF_IMPLEMENTATION # include "stb_sprintf.h" -int vsprintf(char *buf, const char *fmt, va_list args) { +dlexport int vsprintf(char *buf, const char *fmt, va_list args) { return stbsp_vsprintf(buf, fmt, args); } diff --git a/src/libc/alloc.c b/src/libc/alloc.c index f20b3361..024e0449 100755 --- a/src/libc/alloc.c +++ b/src/libc/alloc.c @@ -4,59 +4,59 @@ static struct mman mman; -void *malloc(size_t size) { +dlexport void *malloc(size_t size) { return mman_alloc(&mman, size); } -void *xmalloc(size_t size) { +dlexport void *xmalloc(size_t size) { void *ptr = malloc(size); if (ptr == null) exit(1); return ptr; } -void free(void *ptr) { +dlexport void free(void *ptr) { mman_free(&mman, ptr); } -void *calloc(size_t n, size_t size) { +dlexport void *calloc(size_t n, size_t size) { void *ptr = malloc(n * size); if (ptr == null) return null; memset(ptr, 0, n * size); return ptr; } -void *realloc(void *ptr, size_t newsize) { +dlexport void *realloc(void *ptr, size_t newsize) { return mman_realloc(&mman, ptr, newsize); } -void *reallocarray(void *ptr, size_t n, size_t size) { +dlexport void *reallocarray(void *ptr, size_t n, size_t size) { return realloc(ptr, n * size); } -void *aligned_alloc(size_t align, size_t size) { +dlexport void *aligned_alloc(size_t align, size_t size) { return mman_aligned_alloc(&mman, size, align); } -size_t malloc_usable_size(void *ptr) { +dlexport size_t malloc_usable_size(void *ptr) { return mman_msize(&mman, ptr); } -void *memalign(size_t align, size_t size) { +dlexport void *memalign(size_t align, size_t size) { return mman_aligned_alloc(&mman, size, align); } -int posix_memalign(void **memptr, size_t alignment, size_t size) { +dlexport int posix_memalign(void **memptr, size_t alignment, size_t size) { void *ptr = mman_aligned_alloc(&mman, size, alignment); if (ptr == null) return 1; *memptr = ptr; return 0; } -void *pvalloc(size_t size) { +dlexport void *pvalloc(size_t size) { return aligned_alloc(4096, size); } -void *valloc(size_t size) { +dlexport void *valloc(size_t size) { return aligned_alloc(4096, size); } diff --git a/src/libc/main.c b/src/libc/main.c index b05a4d45..aca30ba0 100755 --- a/src/libc/main.c +++ b/src/libc/main.c @@ -4,19 +4,11 @@ dlimport bool __libc_init_mman(); -dlimport int main(int argc, char **argv, char **envp); // lto 时如果在这边报 warning 别管 - -void __libc_start_main() { - int volatile argc; - char **volatile argv; - char **volatile envp; - asm("mov %%edi, %0\n\t" : "=r"(argc)); - asm("mov %%esi, %0\n\t" : "=r"(argv)); - asm("mov %%edx, %0\n\t" : "=r"(envp)); - +dlexport void __libc_start_main(int argc, char **argv, char **envp, + int (*main)(int argc, char **argv, char **envp)) { __libc_init_mman(); - int ret = main(argc, argv, envp); + val ret = main(argc, argv, envp); exit(ret); } diff --git a/src/libc/print.c b/src/libc/print.c index 4e43bfab..bcabacee 100755 --- a/src/libc/print.c +++ b/src/libc/print.c @@ -2,7 +2,7 @@ #include -int printf(cstr _rest fmt, ...) { +dlexport int printf(cstr _rest fmt, ...) { static char buf[4096]; va_list va; va_start(va, fmt); @@ -12,13 +12,13 @@ int printf(cstr _rest fmt, ...) { return rets; } -int puts(cstr s) { +dlexport int puts(cstr s) { print(s); print("\n"); return 0; } -int putchar(int c) { +dlexport int putchar(int c) { char ch[2] = {c, '\0'}; print(ch); return c; diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index 4b56cccb..bbe1b39d 100755 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -1,5 +1,5 @@ add_exe_link_flag("-static -Wl,-Ttext=0x100000 -e _start") add_compile_flag("-mno-sse -mno-sse2 -mno-sse3") add_binary(loader) -target_link_libraries(loader c-base data-structure) +target_link_libraries(loader c-base-s data-structure-s) target_compile_definitions(loader PRIVATE RING0=1 LOADER=1) diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt index 178be24d..a4ecfe9a 100755 --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -1,9 +1,4 @@ include(../../cmake/use-ubscan) - -add_compile_flag("-fvisibility=hidden") # 防止过多的导出条目 (动态链接) - -file(GLOB_RECURSE c_files "*.c") -file(GLOB_RECURSE cpp_files "*.cpp") -add_library(misc STATIC ${c_files} ${cpp_files}) -target_link_libraries(misc c++ c sys c-base) -target_compile_definitions(misc PRIVATE RING3=1) +mklib(misc) +tgtlib(misc c++ c sys c-base) +libdef(misc PRIVATE RING3=1) diff --git a/src/pl_readline/plreadln.c b/src/pl_readline/plreadln.c index cad4ff22..0c531605 100755 --- a/src/pl_readline/plreadln.c +++ b/src/pl_readline/plreadln.c @@ -58,13 +58,13 @@ void pl_readline_uninit(_self) { } void pl_readline_insert_char(char *str, char ch, int idx) { - int len = strlen(str); + val len = strlen(str) + 1; if (len) memmove(str + idx + 1, str + idx, len - idx); str[idx] = ch; } static void pl_readline_delete_char(char *str, int idx) { - int len = strlen(str); + val len = strlen(str); if (len) memmove(str + idx, str + idx + 1, len - idx); str[len] = '\0'; } diff --git a/src/sys/CMakeLists.txt b/src/sys/CMakeLists.txt index 56b33d60..b051429f 100755 --- a/src/sys/CMakeLists.txt +++ b/src/sys/CMakeLists.txt @@ -1,3 +1,3 @@ add_compile_flag("-ffreestanding") mklib(sys) -target_compile_definitions(sys PRIVATE RING3=1) +libdef(sys PRIVATE RING3=1)