Просмотр исходного кода

!150 修正load_elf没有根据section进行映射的问题,此修正需要用户态链接脚本同步修正
Merge pull request !150 from jesven/fix_load_elf

bernard 5 лет назад
Родитель
Сommit
1b0c06c86e
3 измененных файлов с 55 добавлено и 10 удалено
  1. 48 8
      components/lwp/lwp.c
  2. 5 0
      components/lwp/lwp_syscall.c
  3. 2 2
      components/lwp/lwp_user_mm.c

+ 48 - 8
components/lwp/lwp.c

@@ -373,6 +373,9 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
     size_t rel_dyn_size = 0;
     size_t rel_dyn_size = 0;
     size_t dynsym_off = 0;
     size_t dynsym_off = 0;
     size_t dynsym_size = 0;
     size_t dynsym_size = 0;
+#ifdef RT_USING_USERSPACE
+    void *pa, *va;
+#endif
 
 
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE
     rt_mmu_info *m_info = &lwp->mmu_info;
     rt_mmu_info *m_info = &lwp->mmu_info;
@@ -424,9 +427,6 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
     }
     }
 
 
     { /* load aux */
     { /* load aux */
-#ifdef RT_USING_USERSPACE
-        void *pa, *va;
-#endif
         uint8_t *process_header;
         uint8_t *process_header;
         size_t process_header_size;
         size_t process_header_size;
 
 
@@ -478,6 +478,50 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
 #endif
 #endif
     }
     }
 
 
+#ifdef RT_USING_USERSPACE
+    /* map user */
+    off = eheader.e_shoff;
+    for (i = 0; i < eheader.e_shnum; i++, off += sizeof sheader)
+    {
+        int need_map = 0;
+        int text = 0;
+
+        check_off(off, len);
+        lseek(fd, off, SEEK_SET);
+        read_len = load_fread(&sheader, 1, sizeof sheader, fd);
+        check_read(read_len, sizeof sheader);
+
+        if ((sheader.sh_flags & SHF_ALLOC) == 0)
+        {
+            continue;
+        }
+
+        switch (sheader.sh_type)
+        {
+            case SHT_PROGBITS:
+                if ((sheader.sh_flags & SHF_EXECINSTR) != 0)
+                {
+                    text = 1;
+                }
+            case SHT_NOBITS:
+                need_map = 1;
+                break;
+            default:
+                break;
+        }
+        if (need_map)
+        {
+            /* map user */
+            va = lwp_map_user(lwp, (void *)sheader.sh_addr, sheader.sh_size, text);
+            if (!va || (va != (void *)(size_t)sheader.sh_addr))
+            {
+                result = -RT_ERROR;
+                goto _exit;
+            }
+        }
+    }
+#endif
+
     off = eheader.e_phoff;
     off = eheader.e_phoff;
     for (i = 0; i < eheader.e_phnum; i++, off += sizeof pheader)
     for (i = 0; i < eheader.e_phnum; i++, off += sizeof pheader)
     {
     {
@@ -513,12 +557,8 @@ static int load_elf(int fd, int len, struct rt_lwp *lwp, uint8_t *load_addr, str
                         result = -RT_ERROR;
                         result = -RT_ERROR;
                         goto _exit;
                         goto _exit;
                     }
                     }
-                    va = lwp_map_user(lwp, (void *)pheader.p_vaddr, pheader.p_memsz, 1);
-                }
-                else
-                {
-                    va = lwp_map_user(lwp, 0, pheader.p_memsz, 0);
                 }
                 }
+                va = (void *)pheader.p_vaddr;
                 if (va)
                 if (va)
                 {
                 {
                     lwp->text_entry = va;
                     lwp->text_entry = va;

+ 5 - 0
components/lwp/lwp_syscall.c

@@ -2662,6 +2662,11 @@ int sys_access(const char *filename, int mode)
 
 
 int sys_pipe(int fd[2])
 int sys_pipe(int fd[2])
 {
 {
+    if (!lwp_user_accessable((void *)fd, sizeof(int[2])))
+    {
+        rt_set_errno(EINVAL);
+        return -1;
+    }
     return pipe(fd);
     return pipe(fd);
 }
 }
 
 

+ 2 - 2
components/lwp/lwp_user_mm.c

@@ -568,7 +568,7 @@ size_t lwp_data_get(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
         {
         {
             break;
             break;
         }
         }
-        tmp_src = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
+        tmp_src = (void *)((char *)tmp_src - PV_OFFSET);
         rt_memcpy(tmp_dst, tmp_src, len);
         rt_memcpy(tmp_dst, tmp_src, len);
         tmp_dst = (void *)((char *)tmp_dst + len);
         tmp_dst = (void *)((char *)tmp_dst + len);
         addr_start = (void *)((char *)addr_start + len);
         addr_start = (void *)((char *)addr_start + len);
@@ -607,7 +607,7 @@ size_t lwp_data_put(rt_mmu_info *mmu_info, void *dst, void *src, size_t size)
         {
         {
             break;
             break;
         }
         }
-        tmp_dst = (void *)((char *)rt_hw_mmu_v2p(mmu_info, addr_start) - PV_OFFSET);
+        tmp_dst = (void *)((char *)tmp_dst - PV_OFFSET);
         rt_memcpy(tmp_dst, tmp_src, len);
         rt_memcpy(tmp_dst, tmp_src, len);
         tmp_src = (void *)((char *)tmp_src + len);
         tmp_src = (void *)((char *)tmp_src + len);
         addr_start = (void *)((char *)addr_start + len);
         addr_start = (void *)((char *)addr_start + len);