From d9e933046e49221836cae35769c5d53ac721e715 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 23 Nov 2025 12:51:34 -0500 Subject: kern: lib: Add pointer box abstraction The pointer box allows RAII-like allocations within the rv7 kernel to reduce chances of leaks when juggling memory. Signed-off-by: Ian Moffett --- sys/inc/lib/ptrbox.h | 96 +++++++++++++++++++++++++++++++++++++++ sys/lib/ptrbox.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 sys/inc/lib/ptrbox.h create mode 100644 sys/lib/ptrbox.c diff --git a/sys/inc/lib/ptrbox.h b/sys/inc/lib/ptrbox.h new file mode 100644 index 0000000..94f718c --- /dev/null +++ b/sys/inc/lib/ptrbox.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LIB_PTRBOX_H_ +#define _LIB_PTRBOX_H_ + +#include +#include + +/* + * Represents allocation types in a pointerbox + * + * @PTRBOX_HEAP: kalloc() and friends + */ +typedef enum { + PTRBOX_HEAP +} ptrbox_altype_t; + +/* + * Pointer box allocation descriptor used to + * keep track of allocated memory + * + * @type: Allocation type + * @base: Base address of allocation + * @length: Length of allocation + * @link: Queue link descriptor + */ +struct ptrbox_aldes { + ptrbox_altype_t type; + void *base; + size_t length; + TAILQ_ENTRY(ptrbox_aldes) link; +}; + +/* + * A pointer box keeps references to a list of + * allocation descriptors. These references can + * be cleaned up with a single call after use + * + * @alcnt: Number of allocations made + * @allist: List of allocation descriptors + */ +struct ptrbox { + size_t alcnt; + TAILQ_HEAD(, ptrbox_aldes) allist; +}; + +/* + * Initialize a pointer box + */ +int ptrbox_init(struct ptrbox *pbox); + +/* + * Allocate memory using a pointer box + * + * @pbox: Pointer box to allocate to + * @len: Length of allocation to make + * @type: Allocation type + * + * Returns the base of the memory on success + */ +void *ptrbox_alloc(struct ptrbox *pbox, size_t len, ptrbox_altype_t type); + +/* + * Release a pointer box and associated resources + * from memory + */ +void ptrbox_free(struct ptrbox *pbox); + +#endif /* !_LIB_PTRBOX_H_ */ diff --git a/sys/lib/ptrbox.c b/sys/lib/ptrbox.c new file mode 100644 index 0000000..d2e9171 --- /dev/null +++ b/sys/lib/ptrbox.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +static void * +ptrbox_heapalloc(struct ptrbox *pbox, size_t len) +{ + struct ptrbox_aldes *aldes; + void *mem; + + if (pbox == NULL || len == 0) { + return NULL; + } + + mem = kalloc(len); + if (mem == NULL) { + return NULL; + } + + /* Allocate a descriptor */ + aldes = kalloc(sizeof(*aldes)); + if (aldes == NULL) { + kfree(mem); + return NULL; + } + + /* Initialize our descriptor */ + aldes->type = PTRBOX_HEAP; + aldes->base = mem; + aldes->length = len; + + /* Push it to the pointer box */ + TAILQ_INSERT_TAIL(&pbox->allist, aldes, link); + ++pbox->alcnt; + return mem; +} + +void * +ptrbox_alloc(struct ptrbox *pbox, size_t len, ptrbox_altype_t type) +{ + if (pbox == NULL || len == 0) { + return NULL; + } + + switch (type) { + case PTRBOX_HEAP: + return ptrbox_heapalloc(pbox, len); + default: + return NULL; + } + + return NULL; +} + +void +ptrbox_free(struct ptrbox *pbox) +{ + struct ptrbox_aldes *desc; + + if (pbox == NULL) { + return; + } + + TAILQ_FOREACH(desc, &pbox->allist, link) { + if (__unlikely(desc == NULL)) { + continue; + } + + if (desc->base == NULL) { + kfree(desc); + continue; + } + + switch (desc->type) { + case PTRBOX_HEAP: + kfree(desc->base); + break; + } + + kfree(desc); + } +} + +int +ptrbox_init(struct ptrbox *pbox) +{ + if (pbox == NULL) { + return -EINVAL; + } + + TAILQ_INIT(&pbox->allist); + pbox->alcnt = 0; + return 0; +} -- cgit v1.2.3