]> git.corax.cc Git - corax/commitdiff
kernel: Remove brk() and sbrk() syscalls and related functions
authorMatthias Kruk <m@m10k.eu>
Sat, 8 Aug 2020 08:30:42 +0000 (17:30 +0900)
committerMatthias Kruk <m@m10k.eu>
Sat, 8 Aug 2020 08:30:42 +0000 (17:30 +0900)
kernel/arch/paging.c
kernel/core/posixcall.c
kernel/include/arch.h
kernel/klibc/posixcall.S

index 08fafef71804e41489a25b7de1367ef99b8c09d1..ede675df7e311859c15f3d9fd42cecb721cbc111 100644 (file)
@@ -64,7 +64,6 @@ static int _pg_dir_add_region(pg_dir_t*, void*, u32_t, region_type_t,
                              page_attrs_t, region_opts_t);
 int _pg_dir_pagesize(pg_dir_t*, u32_t, u32_t*);
 int _pg_dir_xfer(pg_dir_t*, void*, pg_dir_t*, void*, u32_t);
-static int _pg_dir_heap_map(pg_dir_t*, u32_t);
 
 /*
  * _phys_alloc() - Dynamic memory allocator for linear memory
@@ -1566,201 +1565,6 @@ cleanup:
        return(ret_val);
 }
 
-/*
- * _pg_dir_heap_start() - Get the start address of page directory's heap
- *
- * SYNOPSIS
- *  static void *_pg_dir_heap_start(pg_dir_t *pd);
- *
- * DESCRIPTION
- *  The _pg_dir_heap_start() function returns the start address of the heap within the page
- *  directory pointed to by `pd'. If there is no heap mapped into the page directory, the end of
- *  the last memory section that is not a stack is returned instead (which is the address where
- *  the heap will be, once it has been mapped).
- *
- * RETURN VALUE
- *  Upon success, the virtual address of the heap will be returned (the heap may in fact not be
- *  mapped yet, though). If the position of the heap could not be determined, (void*)-1 will be
- *  returned instead.
- *
- * ERRORS
- *  This function does not return further information in case of an error.
- */
-static void* _pg_dir_heap_start(pg_dir_t *pd)
-{
-       u32_t ret_val;
-       int i;
-
-       for(i = 0, ret_val = (u32_t)-1; i < CONFIG_PAGING_DIR_MAXREGIONS; i++) {
-               struct region *reg;
-               u32_t limit;
-
-               reg = pd->pd_regions[i];
-
-               switch(reg->reg_type) {
-               case REGION_TYPE_HEAP:
-                       ret_val = (u32_t)reg->reg_base;
-                       i = CONFIG_PAGING_DIR_MAXREGIONS;
-
-                       break;
-
-               case REGION_TYPE_MMAP:
-               case REGION_TYPE_TEXT:
-               case REGION_TYPE_BSS:
-               case REGION_TYPE_DATA:
-               case REGION_TYPE_RODATA:
-                       limit = ALIGN((u32_t)reg->reg_base + reg->reg_size,
-                                     reg->reg_pgsize);
-
-                       if(limit > ret_val) {
-                               ret_val = limit;
-                       }
-
-                       break;
-
-               default:
-               case REGION_TYPE_STACK:
-               case REGION_TYPE_KSTACK:
-                       break;
-               }
-       }
-
-       return((void*)ret_val);
-}
-
-/*
- * _pg_dir_heap_map() - Map a heap into a page directory
- *
- * SYNOPSIS
- *  static int _pg_dir_heap_map(pg_dir_t *pd, u32_t heap_size);
- *
- * DESCRIPTION
- *  The _pg_dir_heap_map() function will map a heap of size `heap_size' into the page directory
- *  pointed to by `pd'. The heap will be mapped non-executable if supported by the processor and
- *  configured to do so. The heap will be placed after the last memory region that is not a stack.
- *
- * RETURN VALUE
- *  Upon success, zero is returned. Otherwise, a negative error number is returned and the page
- *  directory is returned to its previous state.
- *
- * ERRORS
- *  -EINVAL   `pd' does not reference a valid page directory
- *  -EALREADY The page directory already has a heap
- *  -ENOMEM   Ran out of memory trying to allocate the heap
- *  -EBADFD   The page directory is in an unusable state
- */
-static int _pg_dir_heap_map(pg_dir_t *pd, u32_t heap_size)
-{
-       /*
-        * The pg_dir_heap_map() function is used to add a heap segment
-        * to a page dir that does not already have one.
-        *
-        * It should work as follows:
-        *  1. Make sure the page dir doesn't already have a heap
-        *  2. Find the highest segment that is not a stack segment
-        *  3. Add the heap segment right after the segement located in 2
-        */
-
-       u32_t heap_start;
-       int ret_val;
-       int i;
-
-       /* FIXME: Make sure heap_size is aligned to the page directory's page size */
-       /* FIXME: Set heap_size to the page directory's page size if set to zero */
-
-       if(!pd) {
-               ret_val = -EINVAL;
-               goto gtfo;
-       }
-
-       /* FIXME: Lock the page directory */
-
-       for(i = 0, heap_start = 0, ret_val = 0;
-           i < CONFIG_PAGING_DIR_MAXREGIONS && ret_val > 0;
-           i++) {
-               struct region *reg;
-               u32_t limit;
-
-               reg = pd->pd_regions[i];
-
-               dbg_printf("Found a region at 0x%08x:%08x\n",
-                          reg->reg_base, reg->reg_size);
-
-               switch(reg->reg_type) {
-               case REGION_TYPE_HEAP:
-                       /* the page directory apparently already contains a heap */
-                       ret_val = -EALREADY;
-                       break;
-
-               case REGION_TYPE_STACK:
-               case REGION_TYPE_KSTACK:
-                       /*
-                        * Ignore stack segments in the calculation because they are supposed to
-                        * be at the end of the address space, and not in front of the heap.
-                        */
-                       break;
-
-               case REGION_TYPE_MMAP:
-               case REGION_TYPE_TEXT:
-               case REGION_TYPE_BSS:
-               case REGION_TYPE_DATA:
-               case REGION_TYPE_RODATA:
-                       /*
-                        * Calculate the address of the first byte after this region. It *should*
-                        * already be aligned, but nevertheless align it again. 念の為.
-                        */
-                       limit = ALIGN((u32_t)reg->reg_base + reg->reg_size,
-                                     reg->reg_pgsize);
-
-                       if(limit > heap_start) {
-                               heap_start = limit;
-                       }
-                       break;
-
-               default:
-                       /* this should absolutely not have happened */
-                       ret_val = -EBADFD;
-                       break;
-               }
-       }
-
-       if(!ret_val) {
-               /* we found a place to allocate the heap segment */
-
-               if(heap_start) {
-                       page_attrs_t attrs;
-
-                       /* the heap shouldn't be executable, right? */
-                       attrs = PAGE_ATTR_PRESENT | PAGE_ATTR_WRITABLE |
-                               PAGE_ATTR_USER | PAGE_ATTR_NO_EXEC;
-
-                       /* allocate page frames from wherever */
-                       ret_val = pg_dir_map(pd, NULL, (void*)heap_start,
-                                            heap_size, attrs);
-
-                       if(!ret_val) {
-                               /* add a struct region so the memory is accounted for */
-                               ret_val = _pg_dir_add_region(pd, (void*)heap_start, heap_size,
-                                                            REGION_TYPE_HEAP, attrs, REGION_OPT_PRIV);
-
-                               if(ret_val < 0) {
-                                       /* oops - ran out of kernel heap space */
-                                       pg_dir_unmap(pd, (void*)heap_start, heap_size);
-                               }
-                       } else {
-                               /* Failed to map the heap. Wat do? */
-                               ret_val = -ENOMEM;
-                       }
-               } else {
-                       /* the page directory doesn't appear to contain any regions? */
-                       ret_val = -EBADFD;
-               }
-       }
-
-gtfo:
-       return(ret_val);
-}
-
 /*
  * _clone_kernel_region() - Clone a memory region from the kernel page directory
  *
@@ -2595,117 +2399,6 @@ void* pg_dir_get_heap(pg_dir_t *pd)
        return(ret_val);
 }
 
-/*
- * pg_dir_sbrk() - Change the size of a page directory's heap
- *
- * SYNOPSIS
- *  void *pg_dir_sbrk(pg_dir_t *pd, u32_t increment);
- *
- * DESCRIPTION
- *  The pg_dir_sbrk() function manipulates the size of the heap that is mapped into the page
- *  directory pointed to by `pd'. If `increment' is positive, the size of the heap will be
- *  increased by `increment' bytes by increasing the limit of the heap. If `increment' is
- *  negative, the limit of the size will be decreased by `-increment', shrinking the heap.
- *  If the value of `increment' is zero, The end of the heap will be returned without modifying
- *  its position.
- *  If there is no heap mapped into the page directory, this function will return the address
- *  where the heap will be mapped if this function is called with a positive `increment' value.
- *
- * RETURN VALUE
- *  Upon success, the address of the end of the heap (that is, the address right behind the heap)
- *  is returned.
- *
- * ERRORS
- *  This function does not signal information about errors.
- */
-void* pg_dir_sbrk(pg_dir_t *pd, i32_t increment)
-{
-       struct region *heap;
-       void *ret_val;
-       int i;
-
-       /* special case where the heap is not touched */
-       if(!increment) {
-               for(i = 0, ret_val = NULL; i < CONFIG_PAGING_DIR_MAXREGIONS; i++) {
-                       if(pd->pd_regions[i]->reg_type == REGION_TYPE_HEAP) {
-                               ret_val = pd->pd_regions[i]->reg_base +
-                                       pd->pd_regions[i]->reg_size;
-                               break;
-                       }
-               }
-
-               /*
-                * If we're still here, we should return the address where
-                * the program break would have been if there was a heap.
-                */
-               ret_val = _pg_dir_heap_start(pd);
-
-               return(ret_val);
-       }
-
-       for(heap = NULL, i = 0; i < CONFIG_PAGING_DIR_MAXREGIONS; i++) {
-               if(pd->pd_regions[i]->reg_type == REGION_TYPE_HEAP) {
-                       heap = pd->pd_regions[i];
-                       break;
-               }
-       }
-
-       if(!heap) {
-               u32_t heap_size;
-               int err;
-
-               heap_size = ALIGN(increment, PAGE_SIZE);
-
-               err = _pg_dir_heap_map(pd, heap_size);
-
-               if(!err) {
-                       /* the new heap has been created with the correct size */
-                       return(pg_dir_sbrk(pd, 0));
-               } else {
-                       /* could not map a heap - how do we get the error to the caller? */
-                       dbg_printf("Kernel says no. (_pg_dir_heap_map() says %u)\n", -err);
-                       return(NULL);
-               }
-       } else {
-               u32_t nbytes;
-               int err;
-
-               if(increment > 0) {
-                       /* round up to the page size */
-                       nbytes = ALIGN(increment, heap->reg_pgsize);
-
-                       err = pg_dir_map(pd, 0, heap->reg_base + heap->reg_size,
-                                        nbytes, heap->reg_attrs);
-
-                       if(!err) {
-                               /* successfully mapped pages - keep track of the increased heap size */
-                               heap->reg_size += nbytes;
-                       }
-               } else { /* increment < 0 */
-                       /* request to reduce the heap size, round down */
-                       nbytes = (u32_t)-increment & ~(heap->reg_pgsize - 1);
-
-                       /* value may be zero, e.g. if the caller wants to free less than a page */
-                       if(nbytes) {
-                               /* remove nbytes of space at the end of the region */
-                               err = pg_dir_unmap(pd, heap->reg_base + heap->reg_size - nbytes,
-                                                  nbytes);
-
-                               if(!err) {
-                                       heap->reg_size -= nbytes;
-                               }
-                       }
-               }
-
-               /* FIXME: We need to somehow set errno if the mapping failed */
-       }
-
-       /* either way return the new/current sbrk value */
-       ret_val = heap->reg_base + heap->reg_size;
-
-       return(ret_val);
-}
-
 /*
  * pg_fault_debug() - Print page table entries for an address
  *
index 38ebfffebfd25d4a1750983810b2ac88129c5051..c234ee259c0d37d1213969772012136982bd29ad 100644 (file)
@@ -55,37 +55,6 @@ int sys_fork(stack_frame_t *stk)
        return(ret_val);
 }
 
-int sys_sbrk(stack_frame_t *stk)
-{
-       process_t *cproc;
-       pg_dir_t *pgdir;
-       int ret_val;
-
-       cproc = process_get_current();
-
-       process_lock(cproc);
-
-       ret_val = process_get_pagedir(cproc, &pgdir);
-
-       if(!ret_val) {
-               void *brk;
-
-               brk = pg_dir_sbrk(pgdir, (ssize_t)stk->ebx);
-
-               if(brk) {
-                       stk->eax = (u32_t)brk;
-                       ret_val = 0;
-               } else {
-                       stk->eax = (u32_t)-1;
-                       ret_val = -ENOMEM;
-               }
-       }
-
-       process_unlock(cproc);
-
-       return(ret_val);
-}
-
 #if FEATURE(ELF)
 int sys_execelf(stack_frame_t *stk)
 {
@@ -956,10 +925,6 @@ int sys_posixcall(stack_frame_t *stk)
                ret_val = sys_sleep((unsigned int)stk->ebx);
                break;
 
-       case SYS_SBRK:
-               ret_val = sys_sbrk(stk);
-               break;
-
        case SYS_EXECFVE:
                ret_val = sys_execfve(stk);
                break;
index d1f8a1f3068c23fb07d2b246e16e419f94b68bf0..9f828a7c0c10793c0f84bbe1c34a4cc4c971b978 100644 (file)
@@ -242,7 +242,6 @@ void*   pg_dir_get_kstack(pg_dir_t*);
 void*   pg_dir_get_ustack(pg_dir_t*);
 void*   pg_dir_get_ustack_top(pg_dir_t*);
 int     pg_dir_grow_ustack(pg_dir_t*, void*);
-void*   pg_dir_sbrk(pg_dir_t*, i32_t);
 int     pg_dir_foreach_region(pg_dir_t*, int(*)(pg_dir_t*, struct region*, void*), void*);
 int     pg_dir_memcpy(pg_dir_t*, void*, pg_dir_t*, void*, u32_t);
 int     pg_dir_memset(pg_dir_t*, void*, int, u32_t);
index 3180f8b7a90f91b084872e16a5ea9fab90d8369d..858c2d3d325a3f10c01f4f8134d1a75306a4bd74 100644 (file)
@@ -11,8 +11,6 @@
        .global fork
        .global execfve
        .global execeve
-       .global brk
-       .global sbrk
        .global mmap
        .global munmap
        .global sigaction
@@ -65,34 +63,6 @@ execeve:
        popl    %ebx
        ret
 
-brk:
-       pushl   $0
-       call    sbrk
-
-       /*
-        * The eax register contains the current sbrk, 8(%esp) the desired sbrk.
-        * We have to pass the difference to sbrk() to increase or decrease it.
-        */
-       movl    8(%esp), %edx
-       subl    %eax, %edx
-
-       /* sbrk(8(%esp) - sbrk(0)) */
-       movl    %edx, (%esp)
-       call    sbrk
-
-       addl    $4, %esp
-       ret
-
-sbrk:
-       pushl   %ebx
-
-       movl    $SYS_SBRK, %eax
-       movl    8(%esp), %ebx
-       int             $SYSCALL_POSIX
-
-       popl    %ebx
-       ret
-
 mmap:
        pushl   %ebx
        pushl   %ebp