kernel: experiment with static-pie
This commit is contained in:
parent
b724489609
commit
a8b506ad33
2
Makefile
2
Makefile
@ -79,7 +79,7 @@ LC = $(BASE)/lib/libc.so $(GCC_SHARED)
|
||||
.PHONY: all system clean run shell
|
||||
|
||||
$(BASE)/mod/%.ko: modules/%.c | dirs
|
||||
${CC} -c ${KERNEL_CFLAGS} -mcmodel=large -o $@ $<
|
||||
${CC} -c ${KERNEL_CFLAGS} -fno-pie -mcmodel=large -o $@ $<
|
||||
|
||||
ramdisk.igz: $(wildcard $(BASE)/* $(BASE)/*/* $(BASE)/*/*/* $(BASE)/*/*/*/* $(BASE)/*/*/*/*/*) $(APPS_X) $(LIBS_X) $(KRK_MODS_X) $(BASE)/bin/kuroko $(BASE)/lib/ld.so $(BASE)/lib/libm.so $(APPS_KRK_X) $(KRK_MODS) $(APPS_SH_X) $(MODULES)
|
||||
python3 util/createramdisk.py
|
||||
|
@ -63,12 +63,13 @@ uintptr_t _xmain = 0;
|
||||
static int load_aout(uint32_t * hdr) {
|
||||
uintptr_t base_offset = (uintptr_t)hdr - (uintptr_t)kernel_load_start;
|
||||
uintptr_t hdr_offset = hdr[3] - base_offset;
|
||||
size_t xtra = 0x100000;
|
||||
|
||||
memcpy((void*)(uintptr_t)hdr[4], kernel_load_start + (hdr[4] - hdr_offset), (hdr[5] - hdr[4]));
|
||||
memset((void*)(uintptr_t)hdr[5], 0, (hdr[6] - hdr[5]));
|
||||
_xmain = (uintptr_t)hdr[7];
|
||||
memcpy((void*)(uintptr_t)hdr[4] + xtra, kernel_load_start + (hdr[4] - hdr_offset), (hdr[5] - hdr[4]));
|
||||
memset((void*)(uintptr_t)hdr[5] + xtra, 0, (hdr[6] - hdr[5]));
|
||||
_xmain = (uintptr_t)hdr[7] + xtra;
|
||||
|
||||
if (hdr[6] > final_offset) final_offset = hdr[6];
|
||||
if (hdr[6] + xtra > final_offset) final_offset = hdr[6] + xtra;
|
||||
final_offset = (final_offset & ~(0xFFF)) + ((final_offset & 0xFFF) ? 0x1000 : 0);
|
||||
|
||||
return 1;
|
||||
|
@ -1,6 +1,6 @@
|
||||
ARCH=x86_64
|
||||
|
||||
ARCH_KERNEL_CFLAGS = -mno-red-zone -fno-omit-frame-pointer -mfsgsbase
|
||||
ARCH_KERNEL_CFLAGS = -mno-red-zone -fno-omit-frame-pointer -mfsgsbase -fPIE
|
||||
ARCH_KERNEL_CFLAGS += -mgeneral-regs-only -z max-page-size=0x1000 -nostdlib
|
||||
ARCH_USER_CFLAGS += -z max-page-size=0x1000
|
||||
|
||||
@ -66,15 +66,15 @@ shell: system
|
||||
-fw_cfg name=opt/org.toaruos.bootmode,string=headless
|
||||
|
||||
misaka-kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o
|
||||
${CC} -g -T kernel/arch/${ARCH}/link.ld ${KERNEL_CFLAGS} -o $@.64 ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o
|
||||
${OC} --strip-debug -I elf64-x86-64 -O elf32-i386 $@.64 $@
|
||||
${CC} -g -T kernel/arch/${ARCH}/link.ld ${KERNEL_CFLAGS} -Wl,-static,-pie,--no-dynamic-linker,-z,notext,-z,norelro -o $@.64 ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o
|
||||
cp $@.64 $@
|
||||
${STRIP} $@
|
||||
|
||||
# Loader stuff, legacy CDs
|
||||
fatbase/ramdisk.igz: ramdisk.igz
|
||||
cp $< $@
|
||||
fatbase/kernel: misaka-kernel
|
||||
cp $< $@
|
||||
strip $@
|
||||
|
||||
cdrom/fat.img: fatbase/ramdisk.igz fatbase/kernel fatbase/efi/boot/bootx64.efi util/mkdisk.sh | dirs
|
||||
util/mkdisk.sh $@ fatbase
|
||||
|
@ -75,7 +75,7 @@ mb2_tag_entry:
|
||||
.word 3
|
||||
.word 0
|
||||
.long 12
|
||||
.long start
|
||||
.long start_mbi2
|
||||
|
||||
/* Framebuffer tag */
|
||||
.align 8
|
||||
@ -99,6 +99,15 @@ mb2_tag_fb:
|
||||
.word 0
|
||||
.long 8
|
||||
|
||||
.align 8
|
||||
.word 10
|
||||
.word 0
|
||||
.long 24
|
||||
.long 0x200000
|
||||
.long 0x1000000
|
||||
.long 4096
|
||||
.long 1
|
||||
|
||||
/* End tag */
|
||||
.align 8
|
||||
.word 0
|
||||
@ -124,12 +133,34 @@ stack_top:
|
||||
.extern kmain
|
||||
.type kmain, @function
|
||||
|
||||
.global start_mbi2
|
||||
.type start_mbi2, @function
|
||||
|
||||
start_mbi2:
|
||||
/* Use reserved 0 space of boot information struct to thunk eip */
|
||||
movl %ebx, %ecx
|
||||
addl $8, %ecx
|
||||
jmp good_to_go
|
||||
|
||||
.global start
|
||||
.type start, @function
|
||||
|
||||
start:
|
||||
/* Use boot_drive as a temporary place to thunk eip */
|
||||
movl %ebx, %ecx
|
||||
addl $16, %ecx
|
||||
|
||||
good_to_go:
|
||||
mov %ecx, %esp
|
||||
|
||||
call _forward
|
||||
_forward:
|
||||
popl %ecx
|
||||
subl $_forward, %ecx
|
||||
|
||||
/* Setup our stack */
|
||||
mov $stack_top, %esp
|
||||
addl %ecx, %esp
|
||||
|
||||
/* Make sure our stack is 16-byte aligned */
|
||||
and $-16, %esp
|
||||
@ -151,6 +182,8 @@ jmp_to_long:
|
||||
|
||||
/* Set up initial page region, which was zero'd for us by the loader */
|
||||
mov $init_page_region, %edi
|
||||
addl %ecx, %edi
|
||||
pushl %ecx
|
||||
|
||||
/* PML4[0] = &PDP[0] | (PRESENT, WRITABLE, USER) */
|
||||
mov $0x1007, %eax
|
||||
@ -179,6 +212,9 @@ jmp_to_long:
|
||||
loop .set_entry
|
||||
|
||||
mov $init_page_region, %edi
|
||||
popl %ecx
|
||||
addl %ecx, %edi
|
||||
pushl %ecx
|
||||
mov %edi, %cr3
|
||||
|
||||
/* Enable PAE */
|
||||
@ -203,8 +239,31 @@ jmp_to_long:
|
||||
or $0x80000000, %eax
|
||||
mov %eax, %cr0
|
||||
|
||||
super_duper_bullshit:
|
||||
popl %ecx
|
||||
|
||||
lea (_lgdt_instr+3)(%ecx), %eax
|
||||
movl (%eax), %ebx
|
||||
addl %ecx, %ebx
|
||||
movl %ebx, (%eax)
|
||||
|
||||
lea (gdtr+2)(%ecx), %eax
|
||||
movl (%eax), %ebx
|
||||
addl %ecx, %ebx
|
||||
movl %ebx, (%eax)
|
||||
|
||||
lea (_ljmp_instr+1)(%ecx), %eax
|
||||
movl (%eax), %ebx
|
||||
addl %ecx, %ebx
|
||||
movl %ebx, (%eax)
|
||||
|
||||
pushl $0
|
||||
pushl %ecx
|
||||
|
||||
_lgdt_instr:
|
||||
lgdt gdtr
|
||||
|
||||
_ljmp_instr:
|
||||
ljmp $0x08,$realm64
|
||||
|
||||
.align 8
|
||||
@ -247,6 +306,7 @@ realm64:
|
||||
|
||||
.continue:
|
||||
cli
|
||||
pop %rcx
|
||||
pop %rdi
|
||||
pop %rsi
|
||||
pop %rdx
|
||||
|
@ -94,7 +94,7 @@ ISR_NOERR 127
|
||||
_isr123:
|
||||
/* Acknowledge IPI */
|
||||
pushq %r12
|
||||
mov (lapic_final), %r12
|
||||
mov (lapic_final)(%rip), %r12
|
||||
add $0xb0, %r12
|
||||
movl $0, (%r12)
|
||||
popq %r12
|
||||
@ -116,7 +116,7 @@ _isr124:
|
||||
pushq %r12
|
||||
mov %cr3, %r12
|
||||
mov %r12, %cr3
|
||||
mov (lapic_final), %r12
|
||||
mov (lapic_final)(%rip), %r12
|
||||
add $0xb0, %r12
|
||||
movl $0, (%r12)
|
||||
popq %r12
|
||||
@ -128,7 +128,7 @@ _isr124:
|
||||
.type _isr126, @function
|
||||
_isr126:
|
||||
pushq %r12
|
||||
mov (lapic_final), %r12
|
||||
mov (lapic_final)(%rip), %r12
|
||||
add $0xb0, %r12
|
||||
movl $0, (%r12)
|
||||
popq %r12
|
||||
|
@ -12,12 +12,30 @@ SECTIONS
|
||||
*(.bootstrap)
|
||||
code = .;
|
||||
*(.text)
|
||||
*(.shit)
|
||||
}
|
||||
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
.rela.dyn BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
_rela_start = .;
|
||||
*(.rela)
|
||||
*(.rela.text)
|
||||
*(.rela.got)
|
||||
*(.rela.plt)
|
||||
*(.rela.bss)
|
||||
*(.rela.ifunc)
|
||||
*(.rela.text.*)
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata*)
|
||||
*(.rela.dyn)
|
||||
_rela_end = .;
|
||||
}
|
||||
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
@ -26,11 +44,11 @@ SECTIONS
|
||||
*(.symbols)
|
||||
PROVIDE(kernel_symbols_start = .);
|
||||
PROVIDE(kernel_symbols_end = .);
|
||||
PROVIDE(bss_start = .);
|
||||
}
|
||||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
PROVIDE(bss_start = .);
|
||||
bss = .;
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <kernel/ksym.h>
|
||||
#include <kernel/misc.h>
|
||||
#include <kernel/version.h>
|
||||
#include <kernel/elf.h>
|
||||
|
||||
#include <kernel/arch/x86_64/ports.h>
|
||||
#include <kernel/arch/x86_64/cmos.h>
|
||||
@ -76,6 +77,7 @@ struct MB2_TagHeader {
|
||||
|
||||
void * mboot2_find_next(char * current, uint32_t type) {
|
||||
char * header = current;
|
||||
while ((uintptr_t)header & 7) header++;
|
||||
struct MB2_TagHeader * tag = (void*)header;
|
||||
while (1) {
|
||||
if (tag->type == 0) return NULL;
|
||||
@ -219,11 +221,11 @@ void mboot_unmark_valid_memory(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void symbols_install(void) {
|
||||
static void symbols_install(uint64_t base) {
|
||||
ksym_install();
|
||||
kernel_symbol_t * k = (kernel_symbol_t *)&kernel_symbols_start;
|
||||
while ((uintptr_t)k < (uintptr_t)&kernel_symbols_end) {
|
||||
ksym_bind(k->name, (void*)k->addr);
|
||||
ksym_bind(k->name, (void*)(k->addr + base));
|
||||
k = (kernel_symbol_t *)((uintptr_t)k + sizeof *k + strlen(k->name) + 1);
|
||||
}
|
||||
}
|
||||
@ -284,6 +286,7 @@ static void mount_ramdisk(uintptr_t addr, size_t len) {
|
||||
uint32_t decompressedSize = *(uint32_t*)mmu_map_from_physical(addr + len - sizeof(uint32_t));
|
||||
size_t pageCount = (((size_t)decompressedSize + 0xFFF) & ~(0xFFF)) >> 12;
|
||||
uintptr_t physicalAddress = mmu_allocate_n_frames(pageCount) << 12;
|
||||
|
||||
if (physicalAddress == (uintptr_t)-1) {
|
||||
dprintf("gzip: failed to allocate pages\n");
|
||||
return;
|
||||
@ -408,7 +411,16 @@ void arch_framebuffer_initialize(void) {
|
||||
*
|
||||
* Called by the x86-64 longmode bootstrap.
|
||||
*/
|
||||
int kmain(struct multiboot * mboot, uint32_t mboot_mag, void* esp) {
|
||||
int kmain(struct multiboot * mboot, uint32_t mboot_mag, void* esp, uint64_t base) {
|
||||
extern Elf64_Rela _rela_start[], _rela_end[];
|
||||
for (Elf64_Rela * rela = _rela_start; rela < _rela_end; ++rela) {
|
||||
switch (ELF64_R_TYPE(rela->r_info)) {
|
||||
case R_X86_64_RELATIVE:
|
||||
*(uint64_t*)(rela->r_offset + base) = base + rela->r_addend;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The debug log is over /dev/ttyS0, but skips the PTY interface; it's available
|
||||
* as soon as we can call printf(), which is as soon as we get to long mode. */
|
||||
early_log_initialize();
|
||||
@ -443,7 +455,7 @@ int kmain(struct multiboot * mboot, uint32_t mboot_mag, void* esp) {
|
||||
|
||||
/* With the MMU initialized, set up things required for the scheduler. */
|
||||
pat_initialize();
|
||||
symbols_install();
|
||||
symbols_install(base);
|
||||
gdt_install();
|
||||
idt_install();
|
||||
fpu_initialize();
|
||||
|
@ -24,6 +24,7 @@ __attribute__((used))
|
||||
__attribute__((naked))
|
||||
static void __ap_bootstrap(void) {
|
||||
asm volatile (
|
||||
".section .shit\n"
|
||||
".code16\n"
|
||||
".org 0x0\n"
|
||||
".global _ap_bootstrap_start\n"
|
||||
@ -34,8 +35,7 @@ static void __ap_bootstrap(void) {
|
||||
"mov %%eax, %%cr4\n"
|
||||
|
||||
/* Kernel base PML4 */
|
||||
".global init_page_region\n"
|
||||
"mov $init_page_region, %%edx\n"
|
||||
"mov $0x77777777, %%edx\n"
|
||||
"mov %%edx, %%cr3\n"
|
||||
|
||||
/* Set LME */
|
||||
@ -52,7 +52,7 @@ static void __ap_bootstrap(void) {
|
||||
"addr32 lgdtl %%cs:_ap_bootstrap_gdtp-_ap_bootstrap_start\n"
|
||||
|
||||
/* Jump... */
|
||||
"data32 jmp $0x08,$ap_premain\n"
|
||||
"data32 jmp $0x08,$0x5A5A5A5A\n"
|
||||
|
||||
".global _ap_bootstrap_gdtp\n"
|
||||
".align 16\n"
|
||||
@ -60,21 +60,30 @@ static void __ap_bootstrap(void) {
|
||||
".word 0\n"
|
||||
".quad 0\n"
|
||||
|
||||
".global _ap_bootstrap_end\n"
|
||||
"_ap_bootstrap_end:\n"
|
||||
".section .text\n"
|
||||
: : : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((used))
|
||||
__attribute__((naked))
|
||||
static void __ap_bootstrap_landing(void) {
|
||||
asm volatile (
|
||||
".code64\n"
|
||||
".align 16\n"
|
||||
"ap_premain:\n"
|
||||
".global _ap_premain\n"
|
||||
"_ap_premain:\n"
|
||||
"mov $0x10, %%ax\n"
|
||||
"mov %%ax, %%ds\n"
|
||||
"mov %%ax, %%ss\n"
|
||||
"mov $0x33, %%ax\n" /* TSS offset in gdt */
|
||||
"ltr %%ax\n"
|
||||
".extern _ap_stack_base\n"
|
||||
"mov _ap_stack_base,%%rsp\n"
|
||||
"mov _ap_stack_base(%%rip),%%rsp\n"
|
||||
".extern ap_main\n"
|
||||
"callq ap_main\n"
|
||||
|
||||
".global _ap_bootstrap_end\n"
|
||||
"_ap_bootstrap_end:\n"
|
||||
: : : "memory"
|
||||
);
|
||||
}
|
||||
@ -82,6 +91,7 @@ static void __ap_bootstrap(void) {
|
||||
extern char _ap_bootstrap_start[];
|
||||
extern char _ap_bootstrap_end[];
|
||||
extern char _ap_bootstrap_gdtp[];
|
||||
extern char _ap_premain[];
|
||||
extern size_t arch_cpu_mhz(void);
|
||||
extern void gdt_copy_to_trampoline(int ap, char * trampoline);
|
||||
extern void arch_set_core_base(uintptr_t base);
|
||||
@ -422,6 +432,9 @@ _toomany:
|
||||
uintptr_t tmp_space = mmu_allocate_a_frame() << 12;
|
||||
memcpy(mmu_map_from_physical(tmp_space), mmu_map_from_physical(0x1000), 0x1000);
|
||||
|
||||
*(uint32_t*)(&_ap_bootstrap_start[0xb]) = (void*)&init_page_region;
|
||||
*(uint32_t*)(&_ap_bootstrap_start[0x37]) = (void*)&_ap_premain;
|
||||
|
||||
/* Map the bootstrap code */
|
||||
memcpy(mmu_map_from_physical(0x1000), &_ap_bootstrap_start, (uintptr_t)&_ap_bootstrap_end - (uintptr_t)&_ap_bootstrap_start);
|
||||
|
||||
|
@ -14,7 +14,7 @@ def entry(sym):
|
||||
print(f'.{size} {sym}')
|
||||
print(f'.asciz "{sym}"')
|
||||
|
||||
let ignore = ['abs','kernel_symbols_start','kernel_symbols_end']
|
||||
let ignore = ['abs','kernel_symbols_start','kernel_symbols_end','_GLOBAL_OFFSET_TABLE_']
|
||||
let source = (x.strip() for x in fileio.stdin.readlines())
|
||||
let symbols = set(x.split()[0] for x in source if not x.endswith(':'))
|
||||
let lines = sorted(x for x in symbols if x not in ignore)
|
||||
|
Loading…
Reference in New Issue
Block a user