#include "assym.h"
#include <machine/asm.h>
#include <machine/param.h>
#include <machine/vmparam.h>
#include <machine/riscvreg.h>
#include <sys/errno.h>
.text
ENTRY(copyinstr)
RETGUARD_SETUP(copyiostr, a6)
beqz a2, .Lcopyiostrtoolong_early
la a4, .Lcopyiostrfault_user
SWAP_FAULT_HANDLER(a4, t0, t1)
ENTER_USER_ACCESS(t0)
mv a5, x0
li t1, VM_MAXUSER_ADDRESS
1: bgtu a0, t1, .Lcopyiostrfault_user
lb t0, 0(a0)
addi a0, a0, 1
sb t0, 0(a1)
addi a1, a1, 1
addi a2, a2, -1
addi a5, a5, 1
beqz t0, .Lcopyiostrsuccess_user
bnez a2, 1b
.Lcopyiostrtoolong_user:
EXIT_USER_ACCESS(t0)
.Lcopyiostrtoolong:
SET_FAULT_HANDLER(a4, t0)
.Lcopyiostrtoolong_early:
li a0, ENAMETOOLONG
j .Lcopyiostrcleanup
.Lcopyiostrfault_user:
EXIT_USER_ACCESS(t0)
.Lcopyiostrfault:
SET_FAULT_HANDLER(a4, t0)
li a0, EFAULT
j .Lcopyiostrcleanup
.Lcopyiostrsuccess_user:
EXIT_USER_ACCESS(t0)
.Lcopyiostrsuccess:
SET_FAULT_HANDLER(a4, t0)
mv a0, x0
.Lcopyiostrcleanup:
beqz a3, 2f
sd a5, 0(a3)
2:
RETGUARD_CHECK(copyiostr, a6)
ret
END(copyinstr)
ENTRY(copyoutstr)
RETGUARD_SETUP(copyiostr, a6)
beqz a2, .Lcopyiostrtoolong_early
la a4, .Lcopyiostrfault_user
SWAP_FAULT_HANDLER(a4, t0, t1)
ENTER_USER_ACCESS(t0)
mv a5, x0
li t1, VM_MAXUSER_ADDRESS
1: bgtu a1, t1, .Lcopyiostrfault_user
lb t0, 0(a0)
addi a0, a0, 1
sb t0, 0(a1)
addi a1, a1, 1
addi a2, a2, -1
addi a5, a5, 1
beqz t0, .Lcopyiostrsuccess_user
bnez a2, 1b
j .Lcopyiostrtoolong_user
END(copyoutstr)