optimized some syscalls
This commit is contained in:
@@ -10,11 +10,7 @@
|
|||||||
|
|
||||||
# fatal error reporting function
|
# fatal error reporting function
|
||||||
function trapout(msg, fd) {
|
function trapout(msg, fd) {
|
||||||
for(fd in FD_PATH) {
|
for(fd in FD_PATH) if(FD_DIRTY[fd]) write_fd_to_file(fd)
|
||||||
if(FD_DIRTY[fd]) {
|
|
||||||
write_fd_to_file(fd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmd = "cat 1>&2"
|
cmd = "cat 1>&2"
|
||||||
printf("Fatal: %s\n", msg) | cmd
|
printf("Fatal: %s\n", msg) | cmd
|
||||||
close(cmd)
|
close(cmd)
|
||||||
@@ -114,9 +110,7 @@ function hex_to_dec(hex, dec, i, len, c, val) {
|
|||||||
function read_str(addr, c, s) {
|
function read_str(addr, c, s) {
|
||||||
s = ""
|
s = ""
|
||||||
addr = uint32(addr)
|
addr = uint32(addr)
|
||||||
while ((c = MEM[addr++]) != 0) {
|
while((c = MEM[addr++]) != 0) s = s sprintf("%c", c)
|
||||||
s = s sprintf("%c", c)
|
|
||||||
}
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,21 +120,13 @@ function path_exists(path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Checks if path is a directory using POSIX test -d
|
# Checks if path is a directory using POSIX test -d
|
||||||
function is_dir(path) {
|
function is_dir(path) {return (system("test -d " qquote(path)) == 0)}
|
||||||
return (system("test -d " qquote(path)) == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Resolves relative path against dfd directory
|
# Resolves relative path against dfd directory
|
||||||
function resolve_path(dfd, pathname, path) {
|
function resolve_path(dfd, pathname, path) {
|
||||||
if (substr(pathname, 1, 1) == "/") {
|
if(substr(pathname, 1, 1) == "/") return pathname
|
||||||
return pathname
|
if(dfd == -100) return pathname
|
||||||
}
|
if(dfd in FD_PATH) return FD_PATH[dfd] "/" pathname
|
||||||
if (dfd == -100) { # AT_FDCWD
|
|
||||||
return pathname
|
|
||||||
}
|
|
||||||
if (dfd in FD_PATH) {
|
|
||||||
return FD_PATH[dfd] "/" pathname
|
|
||||||
}
|
|
||||||
return pathname
|
return pathname
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +148,8 @@ function get_system_time(time_arr, cmd, line) {
|
|||||||
cmd = "date +%s"
|
cmd = "date +%s"
|
||||||
if((cmd | getline line) > 0) {
|
if((cmd | getline line) > 0) {
|
||||||
time_arr["sec"] = int(line)
|
time_arr["sec"] = int(line)
|
||||||
} else {
|
} else time_arr["sec"] = 0
|
||||||
time_arr["sec"] = 0
|
|
||||||
}
|
|
||||||
close(cmd)
|
close(cmd)
|
||||||
|
|
||||||
if(time_arr["sec"] == LAST_SEC) {
|
if(time_arr["sec"] == LAST_SEC) {
|
||||||
VIRT_NSEC += 500000
|
VIRT_NSEC += 500000
|
||||||
if(VIRT_NSEC >= 1000000000) {
|
if(VIRT_NSEC >= 1000000000) {
|
||||||
@@ -191,12 +174,9 @@ function fill_stat_struct(path, addr, follow, cmd, line, parts, opt, mode_hex,
|
|||||||
atime = int(parts[3])
|
atime = int(parts[3])
|
||||||
mtime = int(parts[4])
|
mtime = int(parts[4])
|
||||||
ctime = int(parts[5])
|
ctime = int(parts[5])
|
||||||
|
|
||||||
close(cmd)
|
close(cmd)
|
||||||
|
|
||||||
for (i = 0; i < 104; i++) {
|
for(i = 0; i < 104; i++) MEM[addr + i] = 0
|
||||||
MEM[addr + i] = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
write_mem(addr + 0, 1, 8)
|
write_mem(addr + 0, 1, 8)
|
||||||
write_mem(addr + 8, 1, 8)
|
write_mem(addr + 8, 1, 8)
|
||||||
@@ -233,18 +213,12 @@ function write_fd_to_file(fd, path, chunk, i, size) {
|
|||||||
chunk = ""
|
chunk = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (length(chunk) > 0) {
|
if(length(chunk) > 0) printf("%s", chunk) >> path
|
||||||
printf("%s", chunk) >> path
|
|
||||||
}
|
|
||||||
close(path)
|
close(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
function amach_exit(code, fd) {
|
function amach_exit(code, fd) {
|
||||||
for (fd in FD_PATH) {
|
for(fd in FD_PATH) if(FD_DIRTY[fd]) write_fd_to_file(fd)
|
||||||
if (FD_DIRTY[fd]) {
|
|
||||||
write_fd_to_file(fd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit(code)
|
exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,33 +228,28 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
if(callnum == 34) { # sys_mkdirat
|
if(callnum == 34) { # sys_mkdirat
|
||||||
pathname = read_str(a1)
|
pathname = read_str(a1)
|
||||||
path = resolve_path(a0, pathname)
|
path = resolve_path(a0, pathname)
|
||||||
if (path_exists(path)) {
|
if(path_exists(path)) setreg(10, -17) # -EEXIST
|
||||||
setreg(10, -17) # -EEXIST
|
else {
|
||||||
} else {
|
|
||||||
status = system("mkdir " qquote(path))
|
status = system("mkdir " qquote(path))
|
||||||
setreg(10, (status == 0) ? 0 : -2)
|
setreg(10, (status == 0) ? 0 : -2)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(callnum == 35) { # sys_unlinkat
|
} else if(callnum == 35) { # sys_unlinkat
|
||||||
pathname = read_str(a1)
|
pathname = read_str(a1)
|
||||||
path = resolve_path(a0, pathname)
|
path = resolve_path(a0, pathname)
|
||||||
if(!path_exists(path)) {
|
if(!path_exists(path)) {
|
||||||
setreg(10, -2) # -ENOENT
|
setreg(10, -2) # -ENOENT
|
||||||
} else {
|
} else {
|
||||||
if (bw_and(a2, 512)) { # AT_REMOVEDIR (0x200)
|
if(bw_and(a2, 512)) # AT_REMOVEDIR (0x200)
|
||||||
status = system("rmdir " qquote(path))
|
status = system("rmdir " qquote(path))
|
||||||
} else {
|
else
|
||||||
status = system("rm " qquote(path))
|
status = system("rm " qquote(path))
|
||||||
}
|
|
||||||
setreg(10, (status == 0) ? 0 : -1)
|
setreg(10, (status == 0) ? 0 : -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(callnum == 38 || callnum == 276) { # sys_renameat / sys_renameat2
|
} else if(callnum == 38 || callnum == 276) { # sys_renameat / sys_renameat2
|
||||||
oldpath = resolve_path(a0, read_str(a1))
|
oldpath = resolve_path(a0, read_str(a1))
|
||||||
newpath = resolve_path(a2, read_str(a3))
|
newpath = resolve_path(a2, read_str(a3))
|
||||||
status = system("mv " qquote(oldpath) " " qquote(newpath))
|
status = system("mv " qquote(oldpath) " " qquote(newpath))
|
||||||
setreg(10, (status == 0) ? 0 : -1)
|
setreg(10, (status == 0) ? 0 : -1)
|
||||||
|
|
||||||
} else if(callnum == 56) { # sys_openat
|
} else if(callnum == 56) { # sys_openat
|
||||||
pathname = read_str(a1)
|
pathname = read_str(a1)
|
||||||
path = resolve_path(a0, pathname)
|
path = resolve_path(a0, pathname)
|
||||||
@@ -300,22 +269,17 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = NEXT_FD++
|
fd = NEXT_FD++
|
||||||
FD_PATH[fd] = path
|
FD_PATH[fd] = path
|
||||||
FD_FLAGS[fd] = flags
|
FD_FLAGS[fd] = flags
|
||||||
FD_OFFSET[fd] = 0
|
FD_OFFSET[fd] = 0
|
||||||
FD_SIZE[fd] = 0
|
FD_SIZE[fd] = 0
|
||||||
FD_DIRTY[fd] = 0
|
FD_DIRTY[fd] = 0
|
||||||
|
|
||||||
if(is_dir(path)) {
|
if(is_dir(path)) {
|
||||||
cmd = "ls -a1 " qquote(path)
|
cmd = "ls -a1 " qquote(path)
|
||||||
count = 0
|
count = 0
|
||||||
while ((cmd | getline line) > 0) {
|
while((cmd | getline line) > 0)
|
||||||
if (line != "") {
|
if(line != "") FD_DIRENTS[fd, count++] = line
|
||||||
FD_DIRENTS[fd, count++] = line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(cmd)
|
close(cmd)
|
||||||
FD_DIRENT_COUNT[fd] = count
|
FD_DIRENT_COUNT[fd] = count
|
||||||
} else {
|
} else {
|
||||||
@@ -329,10 +293,9 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
size = 0
|
size = 0
|
||||||
while((cmd | getline line) > 0) {
|
while((cmd | getline line) > 0) {
|
||||||
split(line, arr)
|
split(line, arr)
|
||||||
for (i = 1; i in arr; i++) {
|
for(i = 1; i in arr; i++)
|
||||||
FD_DATA[fd, size++] = arr[i]
|
FD_DATA[fd, size++] = arr[i]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
close(cmd)
|
close(cmd)
|
||||||
FD_SIZE[fd] = size
|
FD_SIZE[fd] = size
|
||||||
} else if(do_trunc) {
|
} else if(do_trunc) {
|
||||||
@@ -345,34 +308,22 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
} else if(callnum == 57) { # sys_close
|
} else if(callnum == 57) { # sys_close
|
||||||
fd = a0
|
fd = a0
|
||||||
if(fd >= 3 && (fd in FD_PATH)) {
|
if(fd >= 3 && (fd in FD_PATH)) {
|
||||||
if (FD_DIRTY[fd]) {
|
if(FD_DIRTY[fd]) write_fd_to_file(fd)
|
||||||
write_fd_to_file(fd)
|
|
||||||
}
|
|
||||||
delete FD_PATH[fd]
|
delete FD_PATH[fd]
|
||||||
delete FD_FLAGS[fd]
|
delete FD_FLAGS[fd]
|
||||||
delete FD_OFFSET[fd]
|
delete FD_OFFSET[fd]
|
||||||
delete FD_SIZE[fd]
|
delete FD_SIZE[fd]
|
||||||
delete FD_DIRTY[fd]
|
delete FD_DIRTY[fd]
|
||||||
if(fd in FD_DIRENT_COUNT) {
|
if(fd in FD_DIRENT_COUNT) {
|
||||||
for (i = 0; i < FD_DIRENT_COUNT[fd]; i++) {
|
for(i = 0; i < FD_DIRENT_COUNT[fd]; i++) delete FD_DIRENTS[fd, i]
|
||||||
delete FD_DIRENTS[fd, i]
|
|
||||||
}
|
|
||||||
delete FD_DIRENT_COUNT[fd]
|
delete FD_DIRENT_COUNT[fd]
|
||||||
} else {
|
} else for(i = 0; i < FD_SIZE[fd]; i++) delete FD_DATA[fd, i]
|
||||||
for (i = 0; i < FD_SIZE[fd]; i++) {
|
|
||||||
delete FD_DATA[fd, i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setreg(10, 0)
|
setreg(10, 0)
|
||||||
} else {
|
} else setreg(10, -9) # -EBADF
|
||||||
setreg(10, -9) # -EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(callnum == 61) { # sys_getdents64
|
} else if(callnum == 61) { # sys_getdents64
|
||||||
fd = a0
|
fd = a0
|
||||||
if (!(fd in FD_DIRENT_COUNT)) {
|
if(!(fd in FD_DIRENT_COUNT)) setreg(10, -9) # -EBADF
|
||||||
setreg(10, -9) # -EBADF
|
else {
|
||||||
} else {
|
|
||||||
bytes_written = 0
|
bytes_written = 0
|
||||||
idx = FD_OFFSET[fd]
|
idx = FD_OFFSET[fd]
|
||||||
count_limit = a2
|
count_limit = a2
|
||||||
@@ -393,20 +344,17 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
full_path = FD_PATH[fd] "/" name
|
full_path = FD_PATH[fd] "/" name
|
||||||
dtype = is_dir(full_path) ? 4 : 8
|
dtype = is_dir(full_path) ? 4 : 8
|
||||||
write_mem(buf_addr + bytes_written + 18, dtype, 1)
|
write_mem(buf_addr + bytes_written + 18, dtype, 1)
|
||||||
for (i = 0; i < length(name); i++) {
|
for(i = 0; i < length(name); i++)
|
||||||
MEM[buf_addr + bytes_written + 19 + i] = ord(substr(name, i + 1, 1))
|
MEM[buf_addr + bytes_written + 19 + i] = ord(substr(name, i + 1, 1))
|
||||||
}
|
|
||||||
MEM[buf_addr + bytes_written + 19 + length(name)] = 0
|
MEM[buf_addr + bytes_written + 19 + length(name)] = 0
|
||||||
for (i = 19 + length(name) + 1; i < reclen; i++) {
|
for(i = 19 + length(name) + 1; i < reclen; i++)
|
||||||
MEM[buf_addr + bytes_written + i] = 0
|
MEM[buf_addr + bytes_written + i] = 0
|
||||||
}
|
|
||||||
bytes_written += reclen
|
bytes_written += reclen
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
FD_OFFSET[fd] = idx
|
FD_OFFSET[fd] = idx
|
||||||
setreg(10, bytes_written)
|
setreg(10, bytes_written)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(callnum == 62) { # sys_lseek
|
} else if(callnum == 62) { # sys_lseek
|
||||||
fd = a0
|
fd = a0
|
||||||
if(fd >= 3 && (fd in FD_PATH) && !(fd in FD_DIRENT_COUNT)) {
|
if(fd >= 3 && (fd in FD_PATH) && !(fd in FD_DIRENT_COUNT)) {
|
||||||
@@ -419,16 +367,12 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
setreg(10, -22) # -EINVAL
|
setreg(10, -22) # -EINVAL
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (idx < 0) {
|
if(idx < 0) setreg(10, -22) # -EINVAL
|
||||||
setreg(10, -22) # -EINVAL
|
else {
|
||||||
} else {
|
|
||||||
FD_OFFSET[fd] = idx
|
FD_OFFSET[fd] = idx
|
||||||
setreg(10, idx)
|
setreg(10, idx)
|
||||||
}
|
}
|
||||||
} else {
|
} else setreg(10, -9) # -EBADF
|
||||||
setreg(10, -9) # -EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(callnum == 63) { # sys_read
|
} else if(callnum == 63) { # sys_read
|
||||||
fd = a0
|
fd = a0
|
||||||
if(fd == 0) {
|
if(fd == 0) {
|
||||||
@@ -440,20 +384,15 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
idx = FD_OFFSET[fd]
|
idx = FD_OFFSET[fd]
|
||||||
size = FD_SIZE[fd]
|
size = FD_SIZE[fd]
|
||||||
count = a2
|
count = a2
|
||||||
if (idx >= size) {
|
if(idx >= size) setreg(10, 0)
|
||||||
setreg(10, 0)
|
else {
|
||||||
} else {
|
|
||||||
if(idx + count > size) count = size - idx
|
if(idx + count > size) count = size - idx
|
||||||
for (i = 0; i < count; i++) {
|
for(i = 0; i < count; i++)
|
||||||
MEM[uint32(a1 + i)] = FD_DATA[fd, idx + i]
|
MEM[uint32(a1 + i)] = FD_DATA[fd, idx + i]
|
||||||
}
|
|
||||||
FD_OFFSET[fd] = idx + count
|
FD_OFFSET[fd] = idx + count
|
||||||
setreg(10, count)
|
setreg(10, count)
|
||||||
}
|
}
|
||||||
} else {
|
} else setreg(10, -9) # -EBADF
|
||||||
setreg(10, -9) # -EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(callnum == 64) { # sys_write
|
} else if(callnum == 64) { # sys_write
|
||||||
fd = a0
|
fd = a0
|
||||||
if(fd == 1 || fd == 2) {
|
if(fd == 1 || fd == 2) {
|
||||||
@@ -462,22 +401,14 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
} else if(fd >= 3 && (fd in FD_PATH) && !(fd in FD_DIRENT_COUNT)) {
|
} else if(fd >= 3 && (fd in FD_PATH) && !(fd in FD_DIRENT_COUNT)) {
|
||||||
idx = FD_OFFSET[fd]
|
idx = FD_OFFSET[fd]
|
||||||
count = a2
|
count = a2
|
||||||
if (bw_and(FD_FLAGS[fd], 1024)) { # O_APPEND (0x400)
|
if(bw_and(FD_FLAGS[fd], 1024)) idx = FD_SIZE[fd] # O_APPEND (0x400)
|
||||||
idx = FD_SIZE[fd]
|
for(i = 0; i < count; i++)
|
||||||
}
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
FD_DATA[fd, idx + i] = MEM[uint32(a1 + i)]
|
FD_DATA[fd, idx + i] = MEM[uint32(a1 + i)]
|
||||||
}
|
|
||||||
FD_OFFSET[fd] = idx + count
|
FD_OFFSET[fd] = idx + count
|
||||||
if (FD_OFFSET[fd] > FD_SIZE[fd]) {
|
if(FD_OFFSET[fd] > FD_SIZE[fd]) FD_SIZE[fd] = FD_OFFSET[fd]
|
||||||
FD_SIZE[fd] = FD_OFFSET[fd]
|
|
||||||
}
|
|
||||||
FD_DIRTY[fd] = 1
|
FD_DIRTY[fd] = 1
|
||||||
setreg(10, count)
|
setreg(10, count)
|
||||||
} else {
|
} else setreg(10, -9) # -EBADF
|
||||||
setreg(10, -9) # -EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(callnum == 78) { # sys_readlinkat
|
} else if(callnum == 78) { # sys_readlinkat
|
||||||
path = resolve_path(a0, read_str(a1))
|
path = resolve_path(a0, read_str(a1))
|
||||||
cmd = "readlink " qquote(path)
|
cmd = "readlink " qquote(path)
|
||||||
@@ -485,15 +416,13 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
close(cmd)
|
close(cmd)
|
||||||
l = length(line)
|
l = length(line)
|
||||||
if(l > a3) l = a3
|
if(l > a3) l = a3
|
||||||
for (i = 0; i < l; i++) {
|
for(i = 0; i < l; i++)
|
||||||
MEM[uint32(a2 + i)] = ord(substr(line, i + 1, 1))
|
MEM[uint32(a2 + i)] = ord(substr(line, i + 1, 1))
|
||||||
}
|
|
||||||
setreg(10, l)
|
setreg(10, l)
|
||||||
} else {
|
} else {
|
||||||
close(cmd)
|
close(cmd)
|
||||||
setreg(10, -22) # -EINVAL
|
setreg(10, -22) # -EINVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(callnum == 79) { # sys_newfstatat
|
} else if(callnum == 79) { # sys_newfstatat
|
||||||
pathname = read_str(a1)
|
pathname = read_str(a1)
|
||||||
flags = a3
|
flags = a3
|
||||||
@@ -504,13 +433,10 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
setreg(10, -9) # -EBADF
|
setreg(10, -9) # -EBADF
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else path = resolve_path(a0, pathname)
|
||||||
path = resolve_path(a0, pathname)
|
|
||||||
}
|
|
||||||
follow = (bw_and(flags, 256) == 0) # follow link if AT_SYMLINK_NOFOLLOW (0x100) is NOT set
|
follow = (bw_and(flags, 256) == 0) # follow link if AT_SYMLINK_NOFOLLOW (0x100) is NOT set
|
||||||
status = fill_stat_struct(path, a2, follow)
|
status = fill_stat_struct(path, a2, follow)
|
||||||
setreg(10, status)
|
setreg(10, status)
|
||||||
|
|
||||||
} else if(callnum == 80) { # sys_fstat
|
} else if(callnum == 80) { # sys_fstat
|
||||||
fd = a0
|
fd = a0
|
||||||
if(fd == 0) path = "/dev/stdin"
|
if(fd == 0) path = "/dev/stdin"
|
||||||
@@ -523,10 +449,8 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
}
|
}
|
||||||
status = fill_stat_struct(path, a1, 1)
|
status = fill_stat_struct(path, a1, 1)
|
||||||
setreg(10, status)
|
setreg(10, status)
|
||||||
|
|
||||||
} else if(callnum == 93 || callnum == 94) { # sys_exit / sys_exit_group
|
} else if(callnum == 93 || callnum == 94) { # sys_exit / sys_exit_group
|
||||||
amach_exit(a0)
|
amach_exit(a0)
|
||||||
|
|
||||||
} else if(callnum == 113 || callnum == 403) { # sys_clock_gettime / sys_clock_gettime64
|
} else if(callnum == 113 || callnum == 403) { # sys_clock_gettime / sys_clock_gettime64
|
||||||
get_system_time(now_time)
|
get_system_time(now_time)
|
||||||
if(callnum == 113) {
|
if(callnum == 113) {
|
||||||
@@ -537,24 +461,18 @@ function handle_ecall(callnum, a0, a1, a2, a3, a4, a5, i, l, buf, path, pathnam
|
|||||||
write_mem(a1 + 8, now_time["nsec"], 4)
|
write_mem(a1 + 8, now_time["nsec"], 4)
|
||||||
}
|
}
|
||||||
setreg(10, 0)
|
setreg(10, 0)
|
||||||
|
|
||||||
} else if(callnum == 169) { # sys_gettimeofday
|
} else if(callnum == 169) { # sys_gettimeofday
|
||||||
get_system_time(now_time)
|
get_system_time(now_time)
|
||||||
write_mem(a0, now_time["sec"], 4)
|
write_mem(a0, now_time["sec"], 4)
|
||||||
write_mem(a0 + 4, int(now_time["nsec"] / 1000), 4)
|
write_mem(a0 + 4, int(now_time["nsec"] / 1000), 4)
|
||||||
setreg(10, 0)
|
setreg(10, 0)
|
||||||
|
|
||||||
} else if(callnum == 278) { # sys_getrandom
|
} else if(callnum == 278) { # sys_getrandom
|
||||||
buf_addr = a0
|
buf_addr = a0
|
||||||
buflen = a1
|
buflen = a1
|
||||||
for (i = 0; i < buflen; i++) {
|
for(i = 0; i < buflen; i++)
|
||||||
MEM[uint32(buf_addr + i)] = int(rand() * 256)
|
MEM[uint32(buf_addr + i)] = int(rand() * 256)
|
||||||
}
|
|
||||||
setreg(10, buflen)
|
setreg(10, buflen)
|
||||||
|
} else trapout(sprintf("Unimplemented environment call %d at 0x%X", callnum, pc - 4))
|
||||||
} else {
|
|
||||||
trapout(sprintf("Unimplemented environment call %d at 0x%X", callnum, pc - 4))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# instruction type executors
|
# instruction type executors
|
||||||
@@ -861,9 +779,5 @@ END {
|
|||||||
instr += 65536 * MEM[pc++] + 16777216 * MEM[pc++]
|
instr += 65536 * MEM[pc++] + 16777216 * MEM[pc++]
|
||||||
amach_exec(instr) # decode and execute
|
amach_exec(instr) # decode and execute
|
||||||
}
|
}
|
||||||
for(fd in FD_PATH) {
|
for(fd in FD_PATH) if(FD_DIRTY[fd]) write_fd_to_file(fd)
|
||||||
if(FD_DIRTY[fd]) {
|
|
||||||
write_fd_to_file(fd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,302 @@
|
|||||||
|
.section .text
|
||||||
|
.option norvc
|
||||||
|
.global _start
|
||||||
|
|
||||||
|
# Helper macro to exit with code if condition fails
|
||||||
|
# Example: ASSERT_EQ a0, 0, 4 (if a0 != 0, exit with code 4)
|
||||||
|
.macro ASSERT_EQ reg, val, error_code
|
||||||
|
li t4, \val
|
||||||
|
beq \reg, t4, .L_ok_\@
|
||||||
|
li a0, \error_code
|
||||||
|
li a7, 93
|
||||||
|
ecall
|
||||||
|
.L_ok_\@:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# Helper macro to exit with code if registers are not equal
|
||||||
|
.macro ASSERT_REG_EQ reg1, reg2, error_code
|
||||||
|
beq \reg1, \reg2, .L_ok_reg_\@
|
||||||
|
li a0, \error_code
|
||||||
|
li a7, 93
|
||||||
|
ecall
|
||||||
|
.L_ok_reg_\@:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
# Helper macro to exit with code if a register is negative
|
||||||
|
.macro ASSERT_GEZ reg, error_code
|
||||||
|
bgez \reg, .L_ok_gez_\@
|
||||||
|
li a0, \error_code
|
||||||
|
li a7, 93
|
||||||
|
ecall
|
||||||
|
.L_ok_gez_\@:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
_start:
|
||||||
|
# 1. Write welcome message to stdout
|
||||||
|
li a7, 64 # sys_write
|
||||||
|
li a0, 1 # stdout
|
||||||
|
la a1, msg_welcome
|
||||||
|
li a2, 29 # welcome message length
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 29, 1
|
||||||
|
|
||||||
|
# 2. Test clock_gettime
|
||||||
|
li a7, 113 # sys_clock_gettime
|
||||||
|
li a0, 0 # CLOCK_REALTIME
|
||||||
|
la a1, timespec_buf
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 2
|
||||||
|
# verify we wrote something non-zero to seconds
|
||||||
|
lw t0, timespec_buf
|
||||||
|
ASSERT_GEZ t0, 3
|
||||||
|
|
||||||
|
# 3. Test gettimeofday
|
||||||
|
li a7, 169 # sys_gettimeofday
|
||||||
|
la a0, timeval_buf
|
||||||
|
li a1, 0 # NULL timezone
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 4
|
||||||
|
lw t0, timeval_buf
|
||||||
|
ASSERT_GEZ t0, 5
|
||||||
|
|
||||||
|
# 4. Test openat to create file
|
||||||
|
li a7, 56 # sys_openat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name
|
||||||
|
li a2, 577 # O_CREAT | O_WRONLY | O_TRUNC (64 | 1 | 512 = 577)
|
||||||
|
li a3, 0644 # permissions
|
||||||
|
ecall
|
||||||
|
ASSERT_GEZ a0, 6
|
||||||
|
mv s2, a0 # save fd in s2
|
||||||
|
|
||||||
|
# 5. Write to the new file
|
||||||
|
li a7, 64 # sys_write
|
||||||
|
mv a0, s2 # fd
|
||||||
|
la a1, msg_to_file
|
||||||
|
li a2, 29 # length
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 29, 7
|
||||||
|
|
||||||
|
# 6. Close the file
|
||||||
|
li a7, 57 # sys_close
|
||||||
|
mv a0, s2 # fd
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 8
|
||||||
|
|
||||||
|
# 7. Open file O_RDONLY
|
||||||
|
li a7, 56 # sys_openat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name
|
||||||
|
li a2, 0 # O_RDONLY
|
||||||
|
li a3, 0
|
||||||
|
ecall
|
||||||
|
ASSERT_GEZ a0, 9
|
||||||
|
mv s2, a0 # save fd in s2
|
||||||
|
|
||||||
|
# 7b. Test fstat
|
||||||
|
li a7, 80 # sys_fstat
|
||||||
|
mv a0, s2 # fd
|
||||||
|
la a1, stat_buf
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 20
|
||||||
|
lw t0, stat_buf + 48
|
||||||
|
ASSERT_EQ t0, 29, 21
|
||||||
|
|
||||||
|
# 7c. Test newfstatat
|
||||||
|
li a7, 79 # sys_newfstatat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name
|
||||||
|
la a2, stat_buf
|
||||||
|
li a3, 0 # flags
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 22
|
||||||
|
lw t0, stat_buf + 48
|
||||||
|
ASSERT_EQ t0, 29, 23
|
||||||
|
|
||||||
|
|
||||||
|
# 8. Read from the file
|
||||||
|
li a7, 63 # sys_read
|
||||||
|
mv a0, s2 # fd
|
||||||
|
la a1, read_buf
|
||||||
|
li a2, 50 # buffer size
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 29, 10 # should read 29 bytes
|
||||||
|
|
||||||
|
# verify read content matches
|
||||||
|
la t0, msg_to_file
|
||||||
|
la t1, read_buf
|
||||||
|
li t2, 0 # index
|
||||||
|
.L_loop:
|
||||||
|
add t3, t0, t2
|
||||||
|
lb t3, 0(t3)
|
||||||
|
add t5, t1, t2
|
||||||
|
lb t5, 0(t5)
|
||||||
|
ASSERT_REG_EQ t3, t5, 11
|
||||||
|
addi t2, t2, 1
|
||||||
|
li t6, 29
|
||||||
|
blt t2, t6, .L_loop
|
||||||
|
|
||||||
|
# 9. Close the file
|
||||||
|
li a7, 57 # sys_close
|
||||||
|
mv a0, s2 # fd
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 12
|
||||||
|
|
||||||
|
# 9b. Test renameat (rename test_output.txt to test_output_new.txt)
|
||||||
|
li a7, 38 # sys_renameat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name
|
||||||
|
li a2, -100 # AT_FDCWD
|
||||||
|
la a3, file_name_new
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 24
|
||||||
|
|
||||||
|
# 9c. Verify renamed file can be opened O_RDONLY
|
||||||
|
li a7, 56 # sys_openat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name_new
|
||||||
|
li a2, 0 # O_RDONLY
|
||||||
|
li a3, 0
|
||||||
|
ecall
|
||||||
|
ASSERT_GEZ a0, 25
|
||||||
|
mv s3, a0
|
||||||
|
|
||||||
|
# 9d. Close renamed file
|
||||||
|
li a7, 57 # sys_close
|
||||||
|
mv a0, s3
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 26
|
||||||
|
|
||||||
|
|
||||||
|
# 10. Test mkdirat
|
||||||
|
li a7, 34 # sys_mkdirat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, dir_name
|
||||||
|
li a2, 0755
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 13
|
||||||
|
|
||||||
|
# 11. Open directory fd
|
||||||
|
li a7, 56 # sys_openat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, dir_name
|
||||||
|
li a2, 0 # O_RDONLY
|
||||||
|
li a3, 0
|
||||||
|
ecall
|
||||||
|
ASSERT_GEZ a0, 14
|
||||||
|
mv s2, a0 # save fd in s2
|
||||||
|
|
||||||
|
# 12. Test getdents64
|
||||||
|
li a7, 61 # sys_getdents64
|
||||||
|
mv a0, s2 # fd
|
||||||
|
la a1, dirents_buf
|
||||||
|
li a2, 512 # buffer size
|
||||||
|
ecall
|
||||||
|
ASSERT_GEZ a0, 15
|
||||||
|
|
||||||
|
# 13. Close directory fd
|
||||||
|
li a7, 57 # sys_close
|
||||||
|
mv a0, s2 # fd
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 16
|
||||||
|
|
||||||
|
# 13b. Test readlinkat
|
||||||
|
li a7, 78 # sys_readlinkat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, link_name
|
||||||
|
la a2, read_buf
|
||||||
|
li a3, 50 # buffer size
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 19, 27
|
||||||
|
|
||||||
|
# verify symlink target string
|
||||||
|
la t0, file_name_new
|
||||||
|
la t1, read_buf
|
||||||
|
li t2, 0
|
||||||
|
.L_loop_link:
|
||||||
|
add t3, t0, t2
|
||||||
|
lb t3, 0(t3)
|
||||||
|
add t5, t1, t2
|
||||||
|
lb t5, 0(t5)
|
||||||
|
ASSERT_REG_EQ t3, t5, 28
|
||||||
|
addi t2, t2, 1
|
||||||
|
li t6, 19
|
||||||
|
blt t2, t6, .L_loop_link
|
||||||
|
|
||||||
|
# 14. Test unlinkat for renamed file
|
||||||
|
li a7, 35 # sys_unlinkat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, file_name_new
|
||||||
|
li a2, 0
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 17
|
||||||
|
|
||||||
|
# 14b. Test unlinkat for symlink
|
||||||
|
li a7, 35 # sys_unlinkat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, link_name
|
||||||
|
li a2, 0
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 29
|
||||||
|
|
||||||
|
# 15. Test unlinkat with AT_REMOVEDIR for directory
|
||||||
|
li a7, 35 # sys_unlinkat
|
||||||
|
li a0, -100 # AT_FDCWD
|
||||||
|
la a1, dir_name
|
||||||
|
li a2, 512 # AT_REMOVEDIR
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 0, 18
|
||||||
|
|
||||||
|
|
||||||
|
# 15b. Test getrandom
|
||||||
|
li a7, 278 # sys_getrandom
|
||||||
|
la a0, random_buf
|
||||||
|
li a1, 16 # 16 bytes
|
||||||
|
li a2, 0 # no flags
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 16, 185
|
||||||
|
|
||||||
|
# 16. Write success message
|
||||||
|
li a7, 64 # sys_write
|
||||||
|
li a0, 1 # stdout
|
||||||
|
la a1, msg_success
|
||||||
|
li a2, 33 # success message length
|
||||||
|
ecall
|
||||||
|
ASSERT_EQ a0, 33, 19
|
||||||
|
|
||||||
|
# 17. Exit with 0
|
||||||
|
li a7, 93 # sys_exit
|
||||||
|
li a0, 0 # status 0
|
||||||
|
ecall
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
msg_welcome:
|
||||||
|
.string "Running Syscall Verification\n"
|
||||||
|
msg_to_file:
|
||||||
|
.string "Hello from RISC-V A-Machine!\n"
|
||||||
|
msg_success:
|
||||||
|
.string "All Extended Syscall Tests PASS!\n"
|
||||||
|
file_name:
|
||||||
|
.string "test_output.txt"
|
||||||
|
file_name_new:
|
||||||
|
.string "test_output_new.txt"
|
||||||
|
link_name:
|
||||||
|
.string "test_link.txt"
|
||||||
|
dir_name:
|
||||||
|
.string "test_dir"
|
||||||
|
|
||||||
|
.section .bss
|
||||||
|
.align 4
|
||||||
|
timespec_buf:
|
||||||
|
.space 16
|
||||||
|
timeval_buf:
|
||||||
|
.space 8
|
||||||
|
read_buf:
|
||||||
|
.space 64
|
||||||
|
dirents_buf:
|
||||||
|
.space 512
|
||||||
|
random_buf:
|
||||||
|
.space 16
|
||||||
|
stat_buf:
|
||||||
|
.space 104
|
||||||
|
|
||||||
Binary file not shown.
Reference in New Issue
Block a user