From: Matthias Kruk Date: Sat, 8 Aug 2020 08:30:42 +0000 (+0900) Subject: kernel: Remove brk() and sbrk() syscalls and related functions X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=1b8bb6bd4111dcb146d8945d675eed360084a9ed;p=corax kernel: Remove brk() and sbrk() syscalls and related functions --- diff --git a/kernel/arch/paging.c b/kernel/arch/paging.c index 08fafef..ede675d 100644 --- a/kernel/arch/paging.c +++ b/kernel/arch/paging.c @@ -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 * diff --git a/kernel/core/posixcall.c b/kernel/core/posixcall.c index 38ebfff..c234ee2 100644 --- a/kernel/core/posixcall.c +++ b/kernel/core/posixcall.c @@ -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; diff --git a/kernel/include/arch.h b/kernel/include/arch.h index d1f8a1f..9f828a7 100644 --- a/kernel/include/arch.h +++ b/kernel/include/arch.h @@ -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); diff --git a/kernel/klibc/posixcall.S b/kernel/klibc/posixcall.S index 3180f8b..858c2d3 100644 --- a/kernel/klibc/posixcall.S +++ b/kernel/klibc/posixcall.S @@ -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