Kaynağa Gözat

修复内存分配器中,由于指针地址计算错误导致的越界访问问题. & 增加fcntl & 增加realloc (#17)

1.修复内存分配器中,由于指针地址计算错误导致的越界访问问题. 
2.增加fcntl
3.增加realloc
LoGin 1 yıl önce
ebeveyn
işleme
38083c0db5

+ 1 - 1
Cargo.toml

@@ -42,7 +42,7 @@ sc = "0.2.3"
 
 [target.'cfg(target_os = "dragonos")'.dependencies]
 # Development
-dragonos-dsc = { git = "https://github.com/DragonOS-Community/dsc.git", rev = "b7ebf35" }
+dragonos-dsc = { git = "https://github.com/DragonOS-Community/dsc.git", rev = "d6e4fd8" }
 
 [target.'cfg(target_os = "redox")'.dependencies]
 redox_syscall = "0.3"

+ 19 - 2
src/c/dragonos_malloc.c

@@ -37,6 +37,7 @@
 #define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
 
 #define ALIGN_UP16(x) (((x) + 15) & ~15)
+#define PAGE_ALIGN_UP(x) (((x) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
 
 // 将addr按照x的上边界对齐
 // #define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
@@ -161,7 +162,7 @@ static int malloc_enlarge(int64_t size)
     // printf("size=%ld\tfree_space=%ld\n", size, free_space);
     if (free_space < size) // 现有堆空间不足
     {
-        if (sbrk(size - free_space) != (void *)(-1))
+        if (sbrk(PAGE_ALIGN_UP(size - free_space)) != (void *)(-1))
             brk_max_addr = sbrk((0));
         else
         {
@@ -294,7 +295,10 @@ void *_dragonos_malloc(ssize_t size)
     // 计算需要分配的块的大小
     if (size < sizeof(malloc_mem_chunk_t) - 16)
         size = sizeof(malloc_mem_chunk_t);
-
+    else
+    {
+        size += 16;
+    }
     // 16字节对齐
     size = ALIGN_UP16(size);
 
@@ -410,4 +414,17 @@ void _dragonos_free(void *ptr)
         malloc_merge_free_chunk();
         release_brk();
     }
+}
+
+/**
+ * @brief 根据分配出去的指针获取堆内存块的长度
+ * 
+ * @param ptr 分配出去的指针
+ * 
+ * @return 堆内存块的长度
+*/
+uint64_t _dragonos_chunk_length(void *ptr)
+{
+    malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - 2 * sizeof(uint64_t));
+    return ck->length;
 }

+ 24 - 1
src/platform/allocator/dragonos_malloc.rs

@@ -10,6 +10,7 @@ use super::types::*;
 extern "C" {
     fn _dragonos_free(ptr: *mut c_void) -> *mut c_void;
     fn _dragonos_malloc(size: usize) -> *mut c_void;
+    fn _dragonos_chunk_length(ptr: *mut c_void) -> usize;
 }
 
 pub struct Allocator {
@@ -59,7 +60,29 @@ pub unsafe fn alloc_align(mut size: usize, alignment: usize) -> *mut c_void {
 }
 
 pub unsafe fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
-    todo!()
+    if ptr.is_null() {
+        return alloc(size);
+    }
+    if size == 0 {
+        free(ptr);
+        return null_mut();
+    }
+
+    let old_len = _dragonos_chunk_length(ptr);
+
+    // 暴力实现
+
+    let new_ptr = alloc(size);
+    if new_ptr.is_null() {
+        return null_mut();
+    }
+
+    let copy_len = if old_len < size { old_len } else { size };
+    core::ptr::copy_nonoverlapping(ptr, new_ptr, copy_len);
+
+    free(ptr);
+
+    return new_ptr;
 }
 
 pub unsafe fn free(ptr: *mut c_void) {

+ 12 - 3
src/platform/dragonos/mod.rs

@@ -198,8 +198,9 @@ impl Pal for Sys {
     }
 
     fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
-        // e(unsafe { syscall!(FCNTL, fildes, cmd, arg) }) as c_int
-        unimplemented!()
+        let rc = e(unsafe { syscall!(SYS_FCNTL, fildes, cmd, arg) }) as c_int;
+        // println!("fcntl: fildes: {}, cmd: {}, arg: {}, rc: {}", fildes, cmd, arg, rc);
+        return rc;
     }
 
     fn fork() -> pid_t {
@@ -247,7 +248,15 @@ impl Pal for Sys {
         // } else {
         //     buf
         // }
-        unimplemented!()
+        // 临时实现,设置所有的cwd为根目录
+        if size > 2 {
+            unsafe {
+                *buf = b'/' as c_char;
+                *buf.add(1) = b'\0' as c_char;
+            }
+        }
+
+        return buf;
     }
 
     fn getdents(fd: c_int, dirents: *mut dirent, bytes: usize) -> c_int {