diff --git a/components/finsh/msh.c b/components/finsh/msh.c index 833bb28ccdaca511b633f9341bc57166ab4afc76..4405d9ca74283de341aed93e76ee995ff8dd0ea3 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -391,6 +391,9 @@ static int _msh_exec_lwp(char *cmd, rt_size_t length) close(fd); exec(pg_name, argc, argv); + if (pg_name != argv[0]) + rt_free(pg_name); + return 0; } #endif diff --git a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c b/components/lwp/arch/arm/cortex-a/arch_user_space_init.c index be2b52cbfe38133d9b46fd0f4039c4cb7289aa62..ec1fe622accbd7908da189ee54bfeb5d1e9a2f9b 100644 --- a/components/lwp/arch/arm/cortex-a/arch_user_space_init.c +++ b/components/lwp/arch/arm/cortex-a/arch_user_space_init.c @@ -19,9 +19,6 @@ #include #include -#define USER_HEAP_VADDR 0x80000000 -#define USER_VADDR_START 0x00100000 - extern size_t MMUTable[]; int arch_user_space_init(struct rt_lwp *lwp) diff --git a/components/lwp/arch/arm/cortex-a/arch_user_stack.c b/components/lwp/arch/arm/cortex-a/arch_user_stack.c new file mode 100644 index 0000000000000000000000000000000000000000..3a514016c15bb06f5a264a7ed2e2795b15d88414 --- /dev/null +++ b/components/lwp/arch/arm/cortex-a/arch_user_stack.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-11-18 Jesven first version + */ + +#include +#include + +#ifdef RT_USING_USERSPACE + +#include +#include +#include +#include +#include + +int arch_expand_user_stack(void *addr) +{ + int ret = 0; + size_t stack_addr = (size_t)addr; + + stack_addr &= ~ARCH_PAGE_MASK; + if ((stack_addr >= (size_t)USER_STACK_VSTART) && (stack_addr < (size_t)USER_STACK_VEND)) + { + void *map = lwp_map_user(lwp_self(), (void*)stack_addr, ARCH_PAGE_SIZE); + + if (map || lwp_data_access_ok(&lwp_self()->mmu_info, addr, 1)) + ret = 1; + } + return ret; +} +#endif diff --git a/components/lwp/arch/arm/cortex-a/lwp_arch.h b/components/lwp/arch/arm/cortex-a/lwp_arch.h index d642edc18396ed2d3eb992b492b300f20046326e..716e2ce26f4f3f38bd5720635e5989a2de4aba30 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_arch.h +++ b/components/lwp/arch/arm/cortex-a/lwp_arch.h @@ -14,6 +14,11 @@ #ifdef RT_USING_USERSPACE +#define USER_HEAP_VADDR 0x80000000 +#define USER_STACK_VSTART 0x70000000 +#define USER_STACK_VEND USER_HEAP_VADDR +#define USER_VADDR_START 0x00100000 + #ifdef __cplusplus extern "C" { #endif @@ -21,6 +26,7 @@ extern "C" { int arch_user_space_init(struct rt_lwp *lwp); void *arch_kernel_mmu_table_get(void); void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors); +int arch_expand_user_stack(void *addr); #ifdef __cplusplus } diff --git a/components/lwp/arch/arm/cortex-a/lwp_gcc.S b/components/lwp/arch/arm/cortex-a/lwp_gcc.S index 21007585c464dff9ae08bf1263ca81dee812a636..cad967fa04cd5dbdf6f3f22bfe3e3f5b3e88cfea 100644 --- a/components/lwp/arch/arm/cortex-a/lwp_gcc.S +++ b/components/lwp/arch/arm/cortex-a/lwp_gcc.S @@ -40,6 +40,7 @@ lwp_user_entry: cpsid i msr spsr, r9 + ldr r3, =0x80000000 ;/* user stack top */ /* set data address. */ movs pc, r1 diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index bf602a3100d3266754f1f4ba8eb280891a42e8d8..b23052acacd594fbfb48b4b868a372c0ef9c56a7 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -972,13 +972,40 @@ int sys_listen(int socket, int backlog) return listen(socket, backlog); } +#define MUSLC_MSG_OOB 0x0001 +#define MUSLC_MSG_PEEK 0x0002 +#define MUSLC_MSG_DONTWAIT 0x0040 +#define MUSLC_MSG_WAITALL 0x0100 +#define MUSLC_MSG_MORE 0x8000 + +static int netflags_muslc_2_lwip(int flags) +{ + int flgs = 0; + + if (flags & MUSLC_MSG_PEEK) + flgs |= MSG_PEEK; + if (flags & MUSLC_MSG_WAITALL) + flgs |= MSG_WAITALL; + if (flags & MUSLC_MSG_OOB) + flgs |= MSG_OOB; + if (flags & MUSLC_MSG_DONTWAIT) + flgs |= MSG_DONTWAIT; + if (flags & MUSLC_MSG_MORE) + flgs |= MSG_MORE; + return flgs; +} + int sys_recvfrom(int socket, void *mem, size_t len, int flags, struct musl_sockaddr *from, socklen_t *fromlen) { + int flgs; #ifdef RT_USING_USERSPACE int ret; void *kmem; +#endif + flgs = netflags_muslc_2_lwip(flags); +#ifdef RT_USING_USERSPACE if (!len) return -1; @@ -989,14 +1016,18 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags, if (!kmem) return -1; + if (flags == 0x2) { + flags = 0x1; + } + if (from) { struct sockaddr sa; sockaddr_tolwip(from, &sa); - ret = recvfrom(socket, kmem, len, flags, &sa, fromlen); + ret = recvfrom(socket, kmem, len, flgs, &sa, fromlen); } else - ret = recvfrom(socket, kmem, len, flags, NULL, NULL); + ret = recvfrom(socket, kmem, len, flgs, NULL, NULL); if (ret > 0) lwp_data_put(&lwp_self()->mmu_info, mem, kmem, len); @@ -1009,7 +1040,7 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr sa; sockaddr_tolwip(from, &sa); - return recvfrom(socket, mem, len, flags, &sa, fromlen); + return recvfrom(socket, mem, len, flgs, &sa, fromlen); } return recvfrom(socket, mem, len, flags, NULL, NULL); @@ -1018,16 +1049,23 @@ int sys_recvfrom(int socket, void *mem, size_t len, int flags, int sys_recv(int socket, void *mem, size_t len, int flags) { - return recvfrom(socket, mem, len, flags, NULL, NULL); + int flgs; + + flgs = netflags_muslc_2_lwip(flags); + return recvfrom(socket, mem, len, flgs, NULL, NULL); } int sys_sendto(int socket, const void *dataptr, size_t size, int flags, const struct musl_sockaddr *to, socklen_t tolen) { + int flgs; #ifdef RT_USING_USERSPACE int ret; void *kmem; +#endif + flgs = netflags_muslc_2_lwip(flags); +#ifdef RT_USING_USERSPACE if (!size) return -1; @@ -1045,10 +1083,10 @@ int sys_sendto(int socket, const void *dataptr, size_t size, int flags, struct sockaddr sa; sockaddr_tolwip(to, &sa); - ret = sendto(socket, kmem, size, flags, &sa, tolen); + ret = sendto(socket, kmem, size, flgs, &sa, tolen); } else - ret = sendto(socket, kmem, size, flags, NULL, tolen); + ret = sendto(socket, kmem, size, flgs, NULL, tolen); kmem_put(kmem); return ret; @@ -1058,15 +1096,18 @@ int sys_sendto(int socket, const void *dataptr, size_t size, int flags, struct sockaddr sa; sockaddr_tolwip(to, &sa); - return sendto(socket, dataptr, size, flags, &sa, tolen); + return sendto(socket, dataptr, size, flgs, &sa, tolen); } - return sendto(socket, dataptr, size, flags, NULL, tolen); + return sendto(socket, dataptr, size, flgs, NULL, tolen); #endif } int sys_send(int socket, const void *dataptr, size_t size, int flags) { - return sendto(socket, dataptr, size, flags, NULL, 0); + int flgs; + + flgs = netflags_muslc_2_lwip(flags); + return sendto(socket, dataptr, size, flgs, NULL, 0); } int sys_socket(int domain, int type, int protocol) diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index 3e525a99e1d206e98528914f150fffa7e4696273..b998bff3932f3be73d3b6df3cf2bf1bfe4a2f1fa 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -22,6 +22,7 @@ extern long list_thread(void); #ifdef RT_USING_LWP #include +#include #ifdef LWP_USING_CORE_DUMP #include @@ -131,6 +132,19 @@ void check_user_fault(struct rt_hw_exp_stack *regs, uint32_t pc_adj, char *info) sys_exit(-1); } } + +int check_user_stack(struct rt_hw_exp_stack *regs) +{ + void* dfar; + + asm volatile ("MRC p15, 0, %0, c6, c0, 0":"=r"(dfar)); + if (arch_expand_user_stack(dfar)) + { + regs->pc -= 8; + return 1; + } + return 0; +} #endif /** @@ -281,6 +295,10 @@ void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) return; } #endif + if (check_user_stack(regs)) + { + return; + } check_user_fault(regs, 8, "User data abort"); #endif rt_unwind(regs, 8);