.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