newlib: Impl sbrk() emulation for malloc/free
- Added malloc test; - Test sources are now in one dir. Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
This commit is contained in:
@@ -26,4 +26,16 @@ message(STATUS "SDK_SYSROOT_DIR=${KOS_PORTS_DIR}")
|
||||
|
||||
add_subdirectory(toolchain)
|
||||
add_subdirectory(libraries)
|
||||
add_subdirectory(tests)
|
||||
|
||||
ExternalProject_Add(
|
||||
tests
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_C_COMPILER=i586-kolibrios-gcc
|
||||
-DCMAKE_C_COMPILER_WORKS=1
|
||||
-DCMAKE_INSTALL_PREFIX=${KOS_PORTS_DIR}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
gcc
|
||||
newlib
|
||||
)
|
||||
|
||||
@@ -1,20 +1,67 @@
|
||||
/* Version of sbrk for no operating system. */
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
* Copyright (C) 2026 KolibriOS team
|
||||
* Author: Maxim Logaev <maxlogaev@proton.me>
|
||||
*/
|
||||
|
||||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <kolibrios/syscall.h>
|
||||
|
||||
static struct
|
||||
{
|
||||
char *start;
|
||||
unsigned long brk;
|
||||
// TODO: Add mutex
|
||||
} heap;
|
||||
|
||||
void *
|
||||
_sbrk (incr)
|
||||
int incr;
|
||||
_sbrk (long incr)
|
||||
{
|
||||
extern char end; /* Set by linker. */
|
||||
static char * heap_end;
|
||||
char * prev_heap_end;
|
||||
unsigned long new_brk = 0;
|
||||
void *brk_addr = (void *)-1;
|
||||
|
||||
if (heap_end == 0)
|
||||
heap_end = & end;
|
||||
#if 0
|
||||
fprintf(stderr, "sbrk: start=%p, brk=%lu, incr=%ld\n", heap.start, heap.brk, incr);
|
||||
#endif
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
heap_end += incr;
|
||||
// TODO: Mutex lock;
|
||||
|
||||
return (void *) prev_heap_end;
|
||||
if (incr == 0)
|
||||
{
|
||||
brk_addr = heap.start + heap.brk;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (incr < 0)
|
||||
{
|
||||
if (__builtin_usubl_overflow (heap.brk, (unsigned long)(-incr),
|
||||
&new_brk))
|
||||
new_brk = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__builtin_uaddl_overflow (heap.brk, (unsigned long)incr, &new_brk))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
char *const new_start = (char *)_ksys (SF_SYS_MISC, SSF_MEM_REALLOC, new_brk,
|
||||
(unsigned long)heap.start);
|
||||
|
||||
if (new_start == NULL && new_brk)
|
||||
goto fail;
|
||||
|
||||
brk_addr = new_start + heap.brk;
|
||||
heap.brk = new_brk;
|
||||
heap.start = new_start;
|
||||
|
||||
ok:
|
||||
// TODO: Mutex unlock
|
||||
return brk_addr;
|
||||
|
||||
fail:
|
||||
// TODO: Mutex unlock
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
# Rules for building tests
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
|
||||
ExternalProject_Add(
|
||||
test-hello
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/hello
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_C_COMPILER=i586-kolibrios-gcc
|
||||
-DCMAKE_C_COMPILER_WORKS=1
|
||||
-DCMAKE_INSTALL_PREFIX=${KOS_PORTS_DIR}
|
||||
BUILD_ALWAYS TRUE
|
||||
DEPENDS
|
||||
gcc
|
||||
newlib
|
||||
)
|
||||
project(tests)
|
||||
|
||||
add_executable(hello hello.c)
|
||||
add_executable(malloc malloc.c)
|
||||
|
||||
install(TARGETS hello DESTINATION tests)
|
||||
install(TARGETS malloc DESTINATION tests)
|
||||
|
||||
10
tests/hello.c
Normal file
10
tests/hello.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
errno = ENOSYS;
|
||||
puts ("I: Hello KolibriOS from GCC!");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
|
||||
project(hello)
|
||||
add_executable(hello hello.c)
|
||||
install(TARGETS hello DESTINATION tests)
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* Copyright (C) 2025 KolibriOS team
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
char *hello = "I: Hello KolibriOS from GCC!\n";
|
||||
while(*hello) {
|
||||
__asm__ __inline__("int $0x40" ::"a"(63), "b"(1), "c"(*hello));
|
||||
hello++;
|
||||
}
|
||||
}
|
||||
45
tests/malloc.c
Normal file
45
tests/malloc.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <kolibrios/syscall.h>
|
||||
|
||||
#define MAX_ALLOCS 10000
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
void *allocs[MAX_ALLOCS] = { 0 };
|
||||
|
||||
// Check zero param
|
||||
void *ptr = malloc (0);
|
||||
free (ptr);
|
||||
free (NULL);
|
||||
|
||||
// malloc() and free()
|
||||
for (size_t i = 0; i < 1000; i++)
|
||||
{
|
||||
void *ptr = malloc (9999);
|
||||
memset (ptr, 0xFF, 9999);
|
||||
assert (ptr != NULL);
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
// malloc()
|
||||
for (size_t i = 0; i < MAX_ALLOCS; i++)
|
||||
{
|
||||
allocs[i] = malloc (9999);
|
||||
assert (allocs[i] != NULL);
|
||||
memset (allocs[i], 0xFF, 9999);
|
||||
}
|
||||
|
||||
// free()
|
||||
for (size_t i = 0; i < MAX_ALLOCS; i++)
|
||||
{
|
||||
free(allocs[i]);
|
||||
}
|
||||
|
||||
_ksys_dbg_print("I: Malloc test: OK");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user