diff options
| author | Frans Kaashoek <kaashoek@mit.edu> | 2022-08-23 10:54:40 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@mit.edu> | 2022-08-23 10:54:40 -0400 | 
| commit | 4cd4d194b8827af4971a81ad28968499925f884f (patch) | |
| tree | 49eae2e3938a4e6676895a10253b419d729f3bcd | |
| parent | cef1b57d4a97f15e9858804e368f7928b579b88e (diff) | |
| download | xv6-labs-4cd4d194b8827af4971a81ad28968499925f884f.tar.gz xv6-labs-4cd4d194b8827af4971a81ad28968499925f884f.tar.bz2 xv6-labs-4cd4d194b8827af4971a81ad28968499925f884f.zip | |
Use simple linker script to force data segment to be page aligned
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | kernel/exec.c | 14 | ||||
| -rw-r--r-- | user/user.ld | 36 | 
3 files changed, 43 insertions, 9 deletions
| @@ -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 = .); +} | 
