Quellcode durchsuchen

- 用户态进程主栈改为动态映射
- 网络函数加入标志转换
- 修正msh_exec的内存泄漏问题

shaojinchun vor 5 Jahren
Ursprung
Commit
0473c348c7

+ 3 - 0
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

+ 4 - 7
components/lwp/arch/arm/cortex-a/arch_user_space_init.c

@@ -19,9 +19,6 @@
 #include <lwp_user_mm.h>
 #include <lwp_arch.h>
 
-#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

+ 39 - 0
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 <rtthread.h>
+#include <rthw.h>
+
+#ifdef RT_USING_USERSPACE
+
+#include <mmu.h>
+#include <page.h>
+#include <lwp_mm_area.h>
+#include <lwp_user_mm.h>
+#include <lwp_arch.h>
+
+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

+ 6 - 0
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
 }

+ 1 - 0
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
 

+ 65 - 18
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)

+ 18 - 0
libcpu/arm/cortex-a/trap.c

@@ -22,6 +22,7 @@ extern long list_thread(void);
 
 #ifdef RT_USING_LWP
 #include <lwp.h>
+#include <lwp_arch.h>
 
 #ifdef LWP_USING_CORE_DUMP
 #include <lwp_core_dump.h>
@@ -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);