Make data sections not executable

This commit is contained in:
2025-07-25 23:44:33 +02:00
parent 51ea7ee453
commit 98010a17e3
3 changed files with 125 additions and 51 deletions

View File

@@ -3,7 +3,7 @@
# obtain one at https://mozilla.org/MPL/2.0/.
.global write_s, write_c
.global memcmp, memchr, memmem, memcpy
.global memcmp, memchr, memmem, memcpy, bzero
.section .text
@@ -211,3 +211,19 @@ memcpy:
.Lmemcpy_end:
mv a0, t0
ret
# Zeroes a chank of memory.
#
# Parameters:
# a0 - Memory pointer.
# a1 - Memory size.
bzero:
mv t0, a0
.Lbzero_loop:
bgt t0, a1, .Lbzero_end
sb zero, (t0)
addi t0, t0, 1
.Lbzero_end:
ret

View File

@@ -12,7 +12,9 @@ SECTIONS {
KEEP(*(.text.boot));
*(.text .text.*);
} :text
PROVIDE(estart = .);
. = ALIGN(CONSTANT(MAXPAGESIZE));
PROVIDE(etext = .);
.rodata : ALIGN(16) {
*(.rodata .rodata.*);
@@ -30,4 +32,8 @@ SECTIONS {
. = ALIGN(CONSTANT(MAXPAGESIZE));
PROVIDE(end = .);
/DISCARD/ : {
*(.eh_frame)
}
}

View File

@@ -7,24 +7,13 @@ panic_message: .asciz "\nPanic"
.section .text
bzero:
la t0, __bss
la t1, __bss_end
.Lbzero_loop:
bgt t0, t1, .Lbzero_end
sw zero, (t0)
addi t0, t0, 4
.Lbzero_end:
ret
# Maps a page of physical memory to the identical virtual memory.
#
# Parameters:
# a0 - Physical page address.
# a1 - Free memory page that can be used to create a leaf page table.
# a2 - Page table level. If a2 is 0 a superpage is allocated, otherwise a normal page.
# a3 - Flags.
#
# Returns virtual page address in a0.
.type imem_map_at, @function
@@ -32,43 +21,101 @@ imem_map_at:
csrr t0, satp
slli t0, t0, 12 # Root table address.
li t1, 0xffc # 10 bit * PTESIZE mask.
srli t4, a0, 2 # Physical page number.
li t4, 0xfffffc00
li t5, 0xffc # 10 bit * PTESIZE mask.
li t1, 20
# Multiply VPN[1] by 4 and add to the start address of the page table.
.Limem_map_at_loop:
# Multiply VPN[i] by 4 and add to the start address of the page table.
# This gives the physical address of the page table entry.
srli t2, a0, 20
and t2, t2, t1 # VPN[1] * PTESIZE.
add t2, t0, t2 # a + VPN[1] * PTESIZE.
srl t2, a0, t1
and t2, t2, t5 # VPN[i] * PTESIZE.
add t2, t0, t2 # a + VPN[i] * PTESIZE.
beqz a2, .Limem_map_at_super
beqz a2, .Limem_map_at_leaf
srli t3, a1, 2
lw t3, (t2)
andi t6, t3, 0b1
beqz t6, .Limem_map_at_create
and t0, t3, t4
slli t0, t0, 2
j .Limem_map_at_next
.Limem_map_at_create:
# Take a chunk of free memory and use it as the next page table.
# The beginning addres off the chunk is the base address (a) for the next level.
mv t0, a1
srli t3, t0, 2
ori t3, t3, 0b1
sw t3, (t2)
srli t2, a0, 10
and t2, t2, t1 # VPN[0] * PTESIZE.
add t2, a1, t2 # a + VPN[0] * PTESIZE.
.Limem_map_at_next:
# Calculate the next page table address for the next level.
addi t1, t1, -10
addi a2, a2, -1
j .Limem_map_at_leaf
.Limem_map_at_super:
# Calculate PPN[1] (10 most significant bits of the physical address
# and map it to 12 bits of the table page entry.
li t1, 0xfff00000
and t4, t4, t1
j .Limem_map_at_loop
.Limem_map_at_leaf:
ori t4, t4, 0b1111 # Execute, write, read and valid.
sw t4, (t2)
srli t3, a0, 2 # Physical page number mapped to 12 bits of the page table entry.
ori a3, a3, 0b1
or t3, t3, a3 # Execute, write, read and valid.
sw t3, (t2)
ret
# Maps multiple pages of physical memory to the identical virtual memory.
#
# Parameters:
# a0 - Start address.
# a1 - End address.
# a2 - Start of the free memory that can be used to create leaf page tables.
# a3 - Page table level. If a2 is 0 a superpage is allocated, otherwise a normal page.
# a4 - Flags.
.type imem_map_range, @function
imem_map_range:
# Prologue.
addi sp, sp, -32
sw ra, 28(sp)
sw s0, 24(sp)
addi s0, sp, 32
sw s1, 20(sp)
sw a2, 16(sp)
sw a3, 12(sp)
sw a4, 8(sp)
mv s1, a1
.Limem_map_range_loop:
bge a0, s1, .Limem_map_range_end
lw a1, 16(sp)
lw a2, 12(sp)
lw a3, 8(sp)
call imem_map_at
li t0, 4096
add a0, a0, t0
j .Limem_map_range_loop
.Limem_map_range_end:
lw s1, 20(sp)
# Epilogue.
lw ra, 28(sp)
lw s0, 24(sp)
addi sp, sp, 32
ret
# Activates paging and creates root page table.
# Allocates enough pages for the kernel and its stack.
#
# Parameters:
#
# a0 - Start (base) address of the kernel.
# a1 - Page aligned address following the kernel (kernel end).
.type imem_initialize, @function
@@ -79,31 +126,30 @@ imem_initialize:
sw s0, 24(sp)
addi s0, sp, 32
li t0, 64 * 1024
add t0, a1, t0
sw t0, 20(sp)
sw a0, 20(sp)
sw a1, 16(sp)
srli t0, a1, 12
csrw satp, t0
.Limem_initialize_loop:
lw t0, 20(sp)
la a0, .text.boot
la a1, etext
lw a2, 16(sp)
li t0, 4096
add a2, a2, t0
li a3, 1
li a4, 0b1010
call imem_map_range
la a0, etext
lw a1, 16(sp)
bge a0, t0, .Limem_initialize_activate
li t0, 4096
add a1, a1, t0
li a2, 1
call imem_map_at
add a2, a1, t0
li a3, 1
li a4, 0b0110
call imem_map_range
li t0, 4096
add a0, a0, t0
j .Limem_initialize_loop
.Limem_initialize_activate:
csrr t0, satp
li t1, 0x80000000
or t0, t0, t1
@@ -134,8 +180,11 @@ kernel_main:
# Map flat device tree to the virtual memory.
lw a0, 16(sp)
li t0, 0xffc00000
and a0, a0, t0
lw a1, 20(sp)
li a2, 0
li a3, 0b0010
call imem_map_at
lw a0, 16(sp)
@@ -309,7 +358,10 @@ _entry:
la t1, next_paddr
sw t0, (t1)
la a0, __bss
la a1, __bss_end
call bzero
mv a0, sp
mv a1, s1
j kernel_main