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..7a2f612aab3a8b2eb9dbbd41b63178201a6b4d2c 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) @@ -45,7 +42,7 @@ int arch_user_space_init(struct rt_lwp *lwp) void *arch_kernel_mmu_table_get(void) { - return (void*)MMUTable + PV_OFFSET; + return (void*)((char*)MMUTable + PV_OFFSET); } void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors) @@ -55,12 +52,12 @@ void arch_kuser_init(rt_mmu_info *mmu_info, void *vectors) rt_hw_mmu_map_auto(mmu_info, vectors, 0x1000, MMU_MAP_U_RO); - rt_memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); + rt_memcpy((void*)((char*)vectors + 0x1000 - kuser_sz), __kuser_helper_start, kuser_sz); /* * vectors + 0xfe0 = __kuser_get_tls * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 */ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, vectors + 0x1000 - kuser_sz, kuser_sz); - rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, vectors + 0x1000 - kuser_sz, kuser_sz); + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz); + rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void*)((char*)vectors + 0x1000 - kuser_sz), kuser_sz); } #endif 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..e90ed650f3f7d5db63da0995183990e4350caefc --- /dev/null +++ b/components/lwp/arch/arm/cortex-a/arch_user_stack.c @@ -0,0 +1,39 @@ +/* + * 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..481d510017a177779b5ab2a3f1fe3379ca64ef98 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -78,15 +78,21 @@ static void kmem_put(void *kptr) static void sockaddr_tolwip(const struct musl_sockaddr *std, struct sockaddr *lwip) { - lwip->sa_len = sizeof(*lwip); - lwip->sa_family = (sa_family_t) std->sa_family; - memcpy(lwip->sa_data, std->sa_data, sizeof(lwip->sa_data)); + if (std && lwip) + { + lwip->sa_len = sizeof(*lwip); + lwip->sa_family = (sa_family_t) std->sa_family; + memcpy(lwip->sa_data, std->sa_data, sizeof(lwip->sa_data)); + } } static void sockaddr_tomusl(const struct sockaddr *lwip, struct musl_sockaddr *std) { - std->sa_family = (uint16_t) lwip->sa_family; - memcpy(std->sa_data, lwip->sa_data, sizeof(std->sa_data)); + if (std && lwip) + { + std->sa_family = (uint16_t) lwip->sa_family; + memcpy(std->sa_data, lwip->sa_data, sizeof(std->sa_data)); + } } static void lwp_user_thread(void *parameter) @@ -972,13 +978,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 = 0; #ifdef RT_USING_USERSPACE - int ret; - void *kmem; + int ret = -1; + void *kmem = RT_NULL; +#endif + flgs = netflags_muslc_2_lwip(flags); +#ifdef RT_USING_USERSPACE if (!len) return -1; @@ -989,14 +1022,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 +1046,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 +1055,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 = 0; + + 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 = 0; #ifdef RT_USING_USERSPACE - int ret; - void *kmem; + int ret = -1; + void *kmem = RT_NULL; +#endif + flgs = netflags_muslc_2_lwip(flags); +#ifdef RT_USING_USERSPACE if (!size) return -1; @@ -1045,10 +1089,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 +1102,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 = 0; + + 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..7bdf5a846ec4024d8043cd778c2aad890f34b597 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 = RT_NULL; + + 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);