-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_mmap.s
129 lines (97 loc) · 3.33 KB
/
test_mmap.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# mmap system call test in RISC-V assembler GNU/Spike
# Scot W. Stevenson <scot.stevenson@gmail.com>
# First version: 20. Oct 2019
# This version: 23. Oct 2019
# Using only Linux system calls, reserve on page of memory and then free it
# again. Requires RV64I arch.
# Fedora RISC-V in QEMU:
# - Assemble with gcc test_mmap.s -o test_mmap \
# -nostartfiles -nostdlib \
# - Execute resulting binary file normally
# This does NOT currently work with the Spike emulator. Commands should be:
# - Assemble with riscv64-unknown-elf-gcc test_mmap.s \
# -o test_mmap \
# -nostartfiles -nostdlib \
# - Execute with spike pk test_mmap
# To get the values for PROT_READ etc, follow the instructions at
# https://stackoverflow.com/questions/38602525/looking-for-mmap-flag-values,
# especially echo '#include <sys/mman.h>' | gcc -E - -dM | less
.option nopic
.equ SYS_MMAP, 222
.equ SYS_MUNMAP, 215
.equ SYS_WRITE, 64
.equ SYS_EXIT, 94
.equ PAGESIZE, 4096
.equ PROT_READ, 0x1
.equ PROT_WRITE, 0x2
.equ MAP_ANONYMOUS, 0x20
.equ MAP_PRIVATE, 0x02
.equ STDOUT, 1
# ==== READ-ONLY DATA ====
.section .rodata
.align 2
success: .ascii "Mapping successful\n"
l_success: .byte .-success
failure: .ascii "Could not map\n"
l_failure: .byte .-failure
unmap_ok: .ascii "Unmapping successful\n"
l_unmap_ok: .byte .-unmap_ok
unmap_fail: .ascii "Unmapping failed\n"
l_unmap_fail: .byte .-unmap_fail
# ==== PROGRAMM CODE ====
.section .text
.align 2
.global _start
_start:
# Setup mmap call
li a0, 0 # NULL, because we want anonymous mapping
li a1, PAGESIZE # Linux standard page is 4096
li a2, PROT_READ|PROT_WRITE # Read and write to page
li a3, MAP_ANONYMOUS|MAP_PRIVATE
li a4, -1 # File descriptor for anonymous
li a5, 0 # Offset
li a7, SYS_MMAP
ecall
# Save address we were returned for unmapping
mv s0, a0
# Print success or failure. Note that mmap returns the the
# address of the memory we reserved or -1 for a failure.
li t0, -1
bne a0, t0, itworked
# Failure
la a1, failure
la a2, l_failure
j print
itworked:
# Success
la a1, success
lbu a2, l_success # fall through to print
print:
li a0, STDOUT # String goes to stdout (screen)
li a7, SYS_WRITE
ecall
# Now we need to free the memory again with munmap. We saved
# the address in s0
mv a0, s0 # Address we were given
li a1, PAGESIZE
li a7, SYS_MUNMAP
ecall
# If all was well, we get a 0 in a0
beqz a0, unmap_worked
# Unmap failure
la a1, unmap_fail
lbu a2, l_unmap_fail
j print_end
unmap_worked:
la a1, unmap_ok
lbu a2, l_unmap_ok # fall through to print_end
print_end:
li a0, STDOUT # String goes to stdout (screen)
li a7, SYS_WRITE
ecall
all_done:
# All done, exit signalling all okay
li a0, 0
li a7, SYS_EXIT
ecall
.end