From 4cd4d194b8827af4971a81ad28968499925f884f Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 23 Aug 2022 10:54:40 -0400 Subject: [PATCH] Use simple linker script to force data segment to be page aligned --- Makefile | 2 +- kernel/exec.c | 14 ++++++-------- user/user.ld | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 user/user.ld diff --git a/Makefile b/Makefile index d7de428..39a99d7 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ tags: $(OBJS) _init ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o _%: %.o $(ULIB) - $(LD) $(LDFLAGS) -verbose -e _main -Ttext 0 -o $@ $^ + $(LD) $(LDFLAGS) -T $U/user.ld -o $@ $^ $(OBJDUMP) -S $@ > $*.asm $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym diff --git a/kernel/exec.c b/kernel/exec.c index aee9345..e18bbb6 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -7,7 +7,7 @@ #include "defs.h" #include "elf.h" -static int loadseg(pde_t *, uint64, uint, struct inode *, uint, uint); +static int loadseg(pde_t *, uint64, struct inode *, uint, uint); int flags2perm(int flags) { @@ -59,15 +59,13 @@ exec(char *path, char **argv) goto bad; if(ph.vaddr + ph.memsz < ph.vaddr) goto bad; - if(ph.align != PGSIZE) + if(ph.vaddr % PGSIZE != 0) goto bad; - uint64 e = PGROUNDUP(ph.vaddr + ph.memsz); uint64 sz1; - if((sz1 = uvmalloc(pagetable, sz, e, flags2perm(ph.flags))) == 0) + if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, flags2perm(ph.flags))) == 0) goto bad; sz = sz1; - uint64 s = PGROUNDDOWN(ph.vaddr); - if(loadseg(pagetable, s, ph.vaddr - s, ip, ph.off, ph.filesz) < 0) + if(loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0) goto bad; } iunlockput(ip); @@ -147,7 +145,7 @@ exec(char *path, char **argv) // and the pages from va to va+sz must already be mapped. // Returns 0 on success, -1 on failure. static int -loadseg(pagetable_t pagetable, uint64 va, uint poff, struct inode *ip, uint offset, uint sz) +loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz) { uint i, n; uint64 pa; @@ -160,7 +158,7 @@ loadseg(pagetable_t pagetable, uint64 va, uint poff, struct inode *ip, uint offs n = sz - i; else n = PGSIZE; - if(readi(ip, 0, (uint64)pa+poff, offset+i, n) != n) + if(readi(ip, 0, (uint64)pa, offset+i, n) != n) return -1; } diff --git a/user/user.ld b/user/user.ld new file mode 100644 index 0000000..0ca922b --- /dev/null +++ b/user/user.ld @@ -0,0 +1,36 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY( _main ) + + +SECTIONS +{ + . = 0x0; + + .text : { + *(.text .text.*) + } + + .rodata : { + . = ALIGN(16); + *(.srodata .srodata.*) /* do not need to distinguish this from .rodata */ + . = ALIGN(16); + *(.rodata .rodata.*) + . = ALIGN(0x1000); + } + + .data : { + . = ALIGN(16); + *(.sdata .sdata.*) /* do not need to distinguish this from .data */ + . = ALIGN(16); + *(.data .data.*) + } + + .bss : { + . = ALIGN(16); + *(.sbss .sbss.*) /* do not need to distinguish this from .bss */ + . = ALIGN(16); + *(.bss .bss.*) + } + + PROVIDE(end = .); +}