summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrans Kaashoek <[email protected]>2022-08-23 10:54:40 -0400
committerFrans Kaashoek <[email protected]>2022-08-23 10:54:40 -0400
commit4cd4d194b8827af4971a81ad28968499925f884f (patch)
tree49eae2e3938a4e6676895a10253b419d729f3bcd
parentcef1b57d4a97f15e9858804e368f7928b579b88e (diff)
downloadxv6-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--Makefile2
-rw-r--r--kernel/exec.c14
-rw-r--r--user/user.ld36
3 files changed, 43 insertions, 9 deletions
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 = .);
+}