userspace: Rewrite everything

Everything.

Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
2025-01-04 06:27:54 +02:00
parent dea36a0228
commit 6dae34debd
135 changed files with 11707 additions and 5286 deletions

View File

@@ -0,0 +1,10 @@
This code is released into the public domain. Use this code at your own
risk. Feel free to use it for whatever purpose you want. I take no responsibilty or
whatever if anything goes wrong. Use it at your own risk.
If you have any fixes or patches, please email me.
Durand Miller <clutter@djm.co.za>

View File

@@ -1,30 +0,0 @@
#include <types.h>
#include "../lock.hpp"
#include "../../../../Kernel/syscalls.h"
NewLock(liballocLock);
extern "C" int liballoc_lock()
{
return liballocLock.Lock(__FUNCTION__);
}
extern "C" int liballoc_unlock()
{
return liballocLock.Unlock();
}
extern "C" void *liballoc_alloc(size_t Pages)
{
return (void *)syscall6(sc_mmap, NULL,
Pages * 0x1000,
sc_PROT_READ | sc_PROT_WRITE,
sc_MAP_ANONYMOUS | sc_MAP_PRIVATE,
-1, 0);
}
extern "C" int liballoc_free(void *Address, size_t Pages)
{
return syscall2(sc_munmap, (uintptr_t)Address, Pages * 0x1000);
}

View File

@@ -0,0 +1,78 @@
/*
This file is part of Fennix C Library.
Fennix C Library is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
*/
/* Taken directly from https://github.com/blanham/liballoc/blob/master/linux.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/mman.h>
#include <unistd.h>
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
#if !defined(MAP_FAILED)
#define MAP_FAILED ((char *)-1)
#endif
#ifndef MAP_NORESERVE
#ifdef MAP_AUTORESRV
#define MAP_NORESERVE MAP_AUTORESRV
#else
#define MAP_NORESERVE 0
#endif
#endif
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int page_size = -1;
int liballoc_lock()
{
pthread_mutex_lock(&mutex);
return 0;
}
int liballoc_unlock()
{
pthread_mutex_unlock(&mutex);
return 0;
}
void *liballoc_alloc(int pages)
{
if (page_size < 0)
page_size = getpagesize();
unsigned int size = pages * page_size;
char *p2 = (char *)mmap(0, size, PROT_NONE, MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, -1, 0);
if (p2 == MAP_FAILED)
return NULL;
if (mprotect(p2, size, PROT_READ | PROT_WRITE) != 0)
{
munmap(p2, size);
return NULL;
}
return p2;
}
int liballoc_free(void *ptr, int pages)
{
return munmap(ptr, pages * page_size);
}

View File

@@ -43,17 +43,11 @@
#define LIBALLOC_MAGIC 0xc001c0de
#define LIBALLOC_DEAD 0xdeaddead
// #define LIBALLOCDEBUG 1
#define LIBALLOCINFO 1
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
#include <stdio.h>
#include <stdlib.h>
// #include <debug.h>
#define FLUSH() fflush(stdout)
#define atexit(x) atexit(x)
// #define printf(m, ...) trace(m, ##__VA_ARGS__)
#endif
@@ -131,10 +125,10 @@ static void *liballoc_memcpy(void *s1, const void *s2, size_t n)
return s1;
}
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
static void liballoc_dump()
{
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
struct liballoc_major *maj = l_memRoot;
struct liballoc_minor *min = NULL;
#endif
@@ -146,7 +140,7 @@ static void liballoc_dump()
printf("liballoc: Error count: %i\n", l_errorCount);
printf("liballoc: Possible overruns: %i\n", l_possibleOverruns);
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
while (maj != NULL)
{
printf("liballoc: %x: total = %i, used = %i\n",
@@ -198,7 +192,7 @@ static struct liballoc_major *allocate_new_page(unsigned int size)
if (maj == NULL)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: WARNING: liballoc_alloc( %i ) return NULL\n", st);
FLUSH();
#endif
@@ -214,7 +208,7 @@ static struct liballoc_major *allocate_new_page(unsigned int size)
l_allocated += maj->size;
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("liballoc: Resource allocated %x of %i pages (%i bytes) for %i size.\n", maj, st, maj->size, size);
printf("liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024))));
@@ -248,7 +242,7 @@ void *PREFIX(malloc)(size_t req_size)
if (size == 0)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: WARNING: alloc( 0 ) called from %x\n",
__builtin_return_address(0));
FLUSH();
@@ -259,8 +253,8 @@ void *PREFIX(malloc)(size_t req_size)
if (l_memRoot == NULL)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#ifdef LIBALLOCDEBUG
#if defined DEBUG || defined INFO
#ifdef DEBUG
printf("liballoc: initialization of liballoc " VERSION "\n");
#endif
atexit(liballoc_dump);
@@ -272,20 +266,20 @@ void *PREFIX(malloc)(size_t req_size)
if (l_memRoot == NULL)
{
liballoc_unlock();
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("liballoc: initial l_memRoot initialization failed\n", p);
FLUSH();
#endif
return NULL;
}
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("liballoc: set up first memory major %x\n", l_memRoot);
FLUSH();
#endif
}
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("liballoc: %x PREFIX(malloc)( %i ): ",
__builtin_return_address(0),
size);
@@ -326,7 +320,7 @@ void *PREFIX(malloc)(size_t req_size)
// CASE 1: There is not enough space in this major block.
if (diff < (size + sizeof(struct liballoc_minor)))
{
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 1: Insufficient space in block %x\n", maj);
FLUSH();
#endif
@@ -378,7 +372,7 @@ void *PREFIX(malloc)(size_t req_size)
ALIGN(p);
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 2: returning %x\n", p);
FLUSH();
#endif
@@ -414,7 +408,7 @@ void *PREFIX(malloc)(size_t req_size)
p = (void *)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 3: returning %x\n", p);
FLUSH();
#endif
@@ -460,7 +454,7 @@ void *PREFIX(malloc)(size_t req_size)
p = (void *)((uintptr_t)min + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 4.1: returning %x\n", p);
FLUSH();
#endif
@@ -499,7 +493,7 @@ void *PREFIX(malloc)(size_t req_size)
p = (void *)((uintptr_t)new_min + sizeof(struct liballoc_minor));
ALIGN(p);
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 4.2: returning %x\n", p);
FLUSH();
#endif
@@ -519,7 +513,7 @@ void *PREFIX(malloc)(size_t req_size)
// CASE 5: Block full! Ensure next block and loop.
if (maj->next == NULL)
{
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("CASE 5: block full\n");
FLUSH();
#endif
@@ -545,11 +539,11 @@ void *PREFIX(malloc)(size_t req_size)
liballoc_unlock(); // release the lock
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("All cases exhausted. No memory available.\n");
FLUSH();
#endif
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: WARNING: PREFIX(malloc)( %i ) returning NULL.\n", size);
liballoc_dump();
FLUSH();
@@ -565,7 +559,7 @@ void PREFIX(free)(void *ptr)
if (ptr == NULL)
{
l_warningCount += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: WARNING: PREFIX(free)( NULL ) called from %x\n",
__builtin_return_address(0));
FLUSH();
@@ -590,7 +584,7 @@ void PREFIX(free)(void *ptr)
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF)))
{
l_possibleOverruns += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n",
min->magic,
LIBALLOC_MAGIC);
@@ -600,7 +594,7 @@ void PREFIX(free)(void *ptr)
if (min->magic == LIBALLOC_DEAD)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n",
ptr,
__builtin_return_address(0));
@@ -609,7 +603,7 @@ void PREFIX(free)(void *ptr)
}
else
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n",
ptr,
__builtin_return_address(0));
@@ -622,7 +616,7 @@ void PREFIX(free)(void *ptr)
return;
}
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("liballoc: %x PREFIX(free)( %x ): ",
__builtin_return_address(0),
ptr);
@@ -674,7 +668,7 @@ void PREFIX(free)(void *ptr)
}
}
#ifdef LIBALLOCDEBUG
#ifdef DEBUG
printf("OK\n");
FLUSH();
#endif
@@ -734,7 +728,7 @@ void *PREFIX(realloc)(void *p, size_t size)
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF)))
{
l_possibleOverruns += 1;
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n",
min->magic,
LIBALLOC_MAGIC);
@@ -744,7 +738,7 @@ void *PREFIX(realloc)(void *p, size_t size)
if (min->magic == LIBALLOC_DEAD)
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n",
ptr,
__builtin_return_address(0));
@@ -753,7 +747,7 @@ void *PREFIX(realloc)(void *p, size_t size)
}
else
{
#if defined LIBALLOCDEBUG || defined LIBALLOCINFO
#if defined DEBUG || defined INFO
printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n",
ptr,
__builtin_return_address(0));

View File

@@ -1,7 +1,9 @@
#ifndef _LIBALLOC_H
#define _LIBALLOC_H
#include <types.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
/** \defgroup ALLOCHOOKS liballoc hooks
*
@@ -17,6 +19,7 @@
// typedef unsigned long uintptr_t;
// This lets you prefix malloc and friends
// #define PREFIX(func) k##func
#define PREFIX(func) __##func
#ifdef __cplusplus