diff --git a/src/perror.asm b/src/perror.asm index d3bab51..08957ee 100644 --- a/src/perror.asm +++ b/src/perror.asm @@ -166,9 +166,11 @@ section .text ; rdi* (arg) Pointer to str[] or 0 (no custom message) ; rdx* Used for syscall NR_write ; r8* (Re)stores pointer to str[]// Stores address of errMsgUser for cmov -; r9* (Re)stores error code +; r9* (Re)stores positive error code ; r10* (Re)stores pointer to error msg perror: + sub rsp, SIZE_QWORD + push rax test rax, rax jz .quit js .negErr @@ -212,4 +214,6 @@ perror: syscall mov rax, r9 .quit: + pop rax + add rsp, SIZE_QWORD ret diff --git a/src/tests.asm b/src/tests.asm index eb88cda..dafadc5 100644 --- a/src/tests.asm +++ b/src/tests.asm @@ -94,6 +94,9 @@ section .rodata ;;; TESTS_PRINT_ALL_OUTPUTS equ 0 ;If set to 0, only print expected/got and FAIL if failed. Otherwise always print outputs. ;Note: when set to 0, tests are silent (ie it prints the current test and does not print any output, not even OK) + + ;perror.asm + TEST_perror equ 1 ;core.asm TEST_islower equ 1 TEST_isupper equ 1 @@ -142,6 +145,16 @@ section .rodata ;;; ;;; Specific test data ;;; + ;perror() + addTestHeader(_perror, "perror") + addTest(perror_noerr, "perror() ;rax=0") + addTest(perror_einval1, "perror() ;rax=EINVAL") + addTest(perror_einval2, "perror('Test') ;rax=EINVAL") + addTest(perror_einval3, "perror() ;rax=-EINVAL") + addTest(perror_einval4, "perror('Test') ;rax=-EINVAL") + addTest(perror_invalid1, "perror() ;rax=999") + addTest(perror_invalid2, "perror('Test') ;rax=-999") + perrorStr db "Test",EOS ;islower() addTestHeader(_islower, "islower") addTest(islower_d, "islower('d')") @@ -219,6 +232,8 @@ section .rodata printfStr1 db "H%ell%0 T\\%t\he%%%re%\n",EOS addTest(printf_hexpadd, "printf(''%x | %16x | %016x | %#16x | %#016x\n%X | %016X | %16X | %#016X | %#16X\n'', 80181775710, [... same arg 9 more times])") printfStr2 db "%x | %16x | %016x | %#16x | %#016x\n%X | %016X | %16X | %#016X | %#16X\n",EOS + addTest(printf_ppadd, "printf(''%p | %16p | %016p | %#16p | %#016p\n%p | %016p | %16p | %#016p | %#16p\n'', 80181775710, [... same arg 9 more times])") + printfStr3 db "%p | %16p | %016p | %#16p | %#016p\n%p | %016p | %16p | %#016p | %#16p\n",EOS section .data @@ -230,6 +245,60 @@ _start: xor r13, r13 ;total tests xor r14, r14 ;OK tests (assert => true) +;--- perror() +%if TEST_perror + printTestHeader(_perror) + + ; TEST 1: perror() ;rax=0 + printTest(perror_noerr) + xor rax, rax + xor rdi, rdi + call perror + assert_eq(0) + + ; TEST 2: perror() ;rax=EINVAL + printTest(perror_einval1) + mov rax, EINVAL + xor rdi, rdi + call perror + assert_eq(EINVAL) + + ; TEST 3: perror('Test') ;rax=EINVAL + printTest(perror_einval2) + mov rax, EINVAL + lea rdi, [rel perrorStr] + call perror + assert_eq(EINVAL) + + ; TEST 4: perror() ;rax=-EINVAL + printTest(perror_einval3) + mov rax, -EINVAL + xor rdi, rdi + call perror + assert_eq(-EINVAL) + + ; TEST 5: perror('Test') ;rax=-EINVAL + printTest(perror_einval4) + mov rax, -EINVAL + lea rdi, [rel perrorStr] + call perror + assert_eq(-EINVAL) + + ; TEST 6: perror() ;rax=999 + printTest(perror_invalid1) + mov rax, 999 + xor rdi, rdi + call perror + assert_eq(999) + + ; TEST 7: perror('Test') ;rax=-999 + printTest(perror_invalid2) + mov rax, -999 + xor rdi, rdi + call perror + assert_eq(-999) +%endif + ;--- islower() %if TEST_islower printTestHeader(_islower) @@ -590,6 +659,23 @@ _start: call printf add rsp, SIZE_QWORD * 5 assert_eq(174) ;8*16(%[#][0]16(x|X)) + (8*3( | ) + 20 (2x %x) + 2 (NL) => 174 + + ; TEST 3 (print hexadecimal numbers in multiple possible ways, but using %p) + printTest(printf_ppadd) + lea rdi, [rel printfStr3] + mov rsi, 80181775710 + mov rdx, rsi + mov rcx, rsi + mov r8, rsi + mov r9, rsi + push rsi + push rsi + push rsi + push rsi + push rsi + call printf + add rsp, SIZE_QWORD * 5 + assert_eq(178) ;Len of TEST 2 + 4 (since %p always uses prefix 0x, this test has that two times extra => 4 chars) %endif ;;;