mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
kernel: add ubsan bindings, fix some UB reported by it
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
|
||||
#include <uacpi/kernel_api.h>
|
||||
|
||||
static volatile struct limine_rsdp_request rsdpreq = {
|
||||
static volatile struct limine_rsdp_request rsdp_request = {
|
||||
.id = LIMINE_RSDP_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *outrsdp) {
|
||||
*outrsdp = (uintptr_t)FROM_HHDM(rsdpreq.response->address);
|
||||
uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *rsdp_out) {
|
||||
*rsdp_out = (uintptr_t)FROM_HHDM(rsdp_request.response->address);
|
||||
return UACPI_STATUS_OK;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <uacpi/acpi.h>
|
||||
|
||||
#define IOAPIC_REG_ID 0
|
||||
#define IOAPIC_REG_ENTRYCOUNT 1
|
||||
#define IOAPIC_REG_ENTRY_COUNT 1
|
||||
#define IOAPIC_REG_PRIORITY 2
|
||||
#define IOAPIC_REG_ENTRY 0x10
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#define APIC_LVT_LINT0 0x350
|
||||
#define APIC_LVT_LINT1 0x360
|
||||
#define APIC_LVT_ERROR 0x370
|
||||
#define APIC_TIMER_INITIALCOUNT 0x380
|
||||
#define APIC_TIMER_INITIAL_COUNT 0x380
|
||||
#define APIC_TIMER_COUNT 0x390
|
||||
#define APIC_TIMER_DIVIDE 0x3E0
|
||||
|
||||
@@ -39,22 +39,22 @@ typedef struct {
|
||||
void *addr;
|
||||
int base;
|
||||
int top;
|
||||
} ioapicdesc_t;
|
||||
} ioapic_desc_t;
|
||||
|
||||
static ioapicdesc_t *ioapics;
|
||||
static ioapic_desc_t *ioapics;
|
||||
|
||||
static struct acpi_madt *madt;
|
||||
static struct acpi_entry_hdr *liststart;
|
||||
static struct acpi_entry_hdr *listend;
|
||||
static void *lapicaddr;
|
||||
static struct acpi_entry_hdr *list_start;
|
||||
static struct acpi_entry_hdr *list_end;
|
||||
static void *lapic_address;
|
||||
|
||||
static size_t overridecount;
|
||||
static size_t iocount;
|
||||
static size_t lapiccount;
|
||||
static size_t lapicnmicount;
|
||||
static size_t override_count;
|
||||
static size_t io_count;
|
||||
static size_t lapic_count;
|
||||
static size_t lapic_nmi_count;
|
||||
|
||||
static ioapicdesc_t *ioapicfromgsi(int gsi) {
|
||||
for (int i = 0; i < iocount; ++i) {
|
||||
static ioapic_desc_t *ioapicfromgsi(int gsi) {
|
||||
for (int i = 0; i < io_count; ++i) {
|
||||
if (ioapics[i].base <= gsi && ioapics[i].top > gsi)
|
||||
return &ioapics[i];
|
||||
}
|
||||
@@ -67,9 +67,9 @@ static inline struct acpi_entry_hdr *getnext(struct acpi_entry_hdr *header) {
|
||||
}
|
||||
|
||||
static inline void *getentry(int type, int n) {
|
||||
struct acpi_entry_hdr *entry = liststart;
|
||||
struct acpi_entry_hdr *entry = list_start;
|
||||
|
||||
while (entry < listend) {
|
||||
while (entry < list_end) {
|
||||
if (entry->type == type) {
|
||||
if (n-- == 0)
|
||||
return entry;
|
||||
@@ -81,10 +81,10 @@ static inline void *getentry(int type, int n) {
|
||||
}
|
||||
|
||||
static int getcount(int type) {
|
||||
struct acpi_entry_hdr *entry = liststart;
|
||||
struct acpi_entry_hdr *entry = list_start;
|
||||
int count = 0;
|
||||
|
||||
while (entry < listend) {
|
||||
while (entry < list_end) {
|
||||
if (entry->type == type)
|
||||
++count;
|
||||
entry = getnext(entry);
|
||||
@@ -94,12 +94,12 @@ static int getcount(int type) {
|
||||
}
|
||||
|
||||
static inline void writelapic(int reg, uint32_t v) {
|
||||
volatile uint32_t *ptr = (void *)((uintptr_t)lapicaddr + reg);
|
||||
volatile uint32_t *ptr = (void *)((uintptr_t)lapic_address + reg);
|
||||
*ptr = v;
|
||||
}
|
||||
|
||||
static inline uint32_t readlapic(int reg) {
|
||||
volatile uint32_t *ptr = (void *)((uintptr_t)lapicaddr + reg);
|
||||
volatile uint32_t *ptr = (void *)((uintptr_t)lapic_address + reg);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked)
|
||||
// default settings for ISA irqs
|
||||
uint8_t polarity = 1; // active high
|
||||
uint8_t trigger = 0; // edge triggered
|
||||
for (uintmax_t i = 0; i < overridecount; ++i) {
|
||||
for (uintmax_t i = 0; i < override_count; ++i) {
|
||||
struct acpi_madt_interrupt_source_override *override = getentry(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE, i);
|
||||
if (override->source != irq)
|
||||
continue;
|
||||
@@ -142,7 +142,7 @@ void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked)
|
||||
break;
|
||||
}
|
||||
|
||||
ioapicdesc_t* ioapic = ioapicfromgsi(irq);
|
||||
ioapic_desc_t* ioapic = ioapicfromgsi(irq);
|
||||
__assert(ioapic);
|
||||
irq = irq - ioapic->base;
|
||||
writeiored(ioapic->addr, irq, vector, 0, 0, polarity, trigger, masked ? 1 : 0, proc);
|
||||
@@ -170,7 +170,7 @@ void arch_apic_initap() {
|
||||
|
||||
// get the acpi id for the local nmi sources
|
||||
|
||||
for (size_t i = 0; i < lapiccount; ++i) {
|
||||
for (size_t i = 0; i < lapic_count; ++i) {
|
||||
struct acpi_madt_lapic *current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC, i);
|
||||
if (current_cpu()->id == current->id) {
|
||||
current_cpu()->acpiid = current->uid;
|
||||
@@ -181,7 +181,7 @@ void arch_apic_initap() {
|
||||
isr_t *nmiisr = interrupt_allocate(nmi, NULL, IPL_MAX); // MAX IPL because NMI
|
||||
__assert(nmiisr);
|
||||
|
||||
for (size_t i = 0; i < lapicnmicount; ++i) {
|
||||
for (size_t i = 0; i < lapic_nmi_count; ++i) {
|
||||
struct acpi_madt_lapic_nmi* current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI, i);
|
||||
if (current->uid == current_cpu()->acpiid || current->uid == 0xff)
|
||||
writelapic(APIC_LVT_LINT0 + 0x10 * current->lint, (nmiisr->id & 0xff) | LVT_DELIVERY_NMI | (current->flags << 12));
|
||||
@@ -194,16 +194,16 @@ void arch_apic_eoi() {
|
||||
|
||||
static time_t stoptimer(timer_t *) {
|
||||
time_t remaining = readlapic(APIC_TIMER_COUNT);
|
||||
time_t initial = readlapic(APIC_TIMER_INITIALCOUNT);
|
||||
time_t initial = readlapic(APIC_TIMER_INITIAL_COUNT);
|
||||
|
||||
writelapic(APIC_TIMER_INITIALCOUNT, 0);
|
||||
writelapic(APIC_TIMER_INITIAL_COUNT, 0);
|
||||
|
||||
return initial - remaining;
|
||||
}
|
||||
|
||||
static time_t time_passed(timer_t *) {
|
||||
time_t remaining = readlapic(APIC_TIMER_COUNT);
|
||||
time_t initial = readlapic(APIC_TIMER_INITIALCOUNT);
|
||||
time_t initial = readlapic(APIC_TIMER_INITIAL_COUNT);
|
||||
|
||||
return initial - remaining;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ static void timerisr(isr_t *isr, context_t *context) {
|
||||
}
|
||||
|
||||
static void armtimer(timer_t *, time_t ticks) {
|
||||
writelapic(APIC_TIMER_INITIALCOUNT, ticks);
|
||||
writelapic(APIC_TIMER_INITIAL_COUNT, ticks);
|
||||
}
|
||||
|
||||
void arch_apic_timerinit() {
|
||||
@@ -223,13 +223,13 @@ void arch_apic_timerinit() {
|
||||
|
||||
writelapic(APIC_TIMER_DIVIDE, 11);
|
||||
|
||||
writelapic(APIC_TIMER_INITIALCOUNT, 0xffffffff);
|
||||
writelapic(APIC_TIMER_INITIAL_COUNT, 0xffffffff);
|
||||
|
||||
timekeeper_wait_us(50000);
|
||||
|
||||
time_t ticksperus = (0xffffffff - readlapic(APIC_TIMER_COUNT)) / 50000;
|
||||
|
||||
writelapic(APIC_TIMER_INITIALCOUNT, 0);
|
||||
writelapic(APIC_TIMER_INITIAL_COUNT, 0);
|
||||
|
||||
printf("cpu%lu: local apic timer calibrated at %lu ticks per us. ISR vector %lu\n", current_cpu()->id, ticksperus, vec);
|
||||
|
||||
@@ -252,13 +252,13 @@ void arch_apic_init() {
|
||||
__assert(ret == UACPI_STATUS_OK);
|
||||
|
||||
madt = tbl.ptr;
|
||||
liststart = (void *)((uintptr_t)madt + sizeof(struct acpi_madt));
|
||||
listend = (void *)((uintptr_t)madt + madt->hdr.length);
|
||||
list_start = (void *)((uintptr_t)madt + sizeof(struct acpi_madt));
|
||||
list_end = (void *)((uintptr_t)madt + madt->hdr.length);
|
||||
|
||||
overridecount = getcount(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE);
|
||||
iocount = getcount(ACPI_MADT_ENTRY_TYPE_IOAPIC);
|
||||
lapiccount = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC);
|
||||
lapicnmicount = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI);
|
||||
override_count = getcount(ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE);
|
||||
io_count = getcount(ACPI_MADT_ENTRY_TYPE_IOAPIC);
|
||||
lapic_count = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC);
|
||||
lapic_nmi_count = getcount(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI);
|
||||
|
||||
// map LAPIC to virtual memory
|
||||
|
||||
@@ -269,22 +269,22 @@ void arch_apic_init() {
|
||||
if (lapic64)
|
||||
printf("\e[94mUsing 64 bit override for the local APIC address\n\e[0m");
|
||||
|
||||
lapicaddr = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
|
||||
__assert(lapicaddr);
|
||||
lapic_address = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
|
||||
__assert(lapic_address);
|
||||
|
||||
// map I/O apics to memory
|
||||
|
||||
ioapics = alloc(sizeof(ioapicdesc_t) * iocount);
|
||||
ioapics = alloc(sizeof(ioapic_desc_t) * io_count);
|
||||
__assert(ioapics);
|
||||
|
||||
for (int i = 0; i < iocount; ++i) {
|
||||
for (int i = 0; i < io_count; ++i) {
|
||||
struct acpi_madt_ioapic *entry = getentry(ACPI_MADT_ENTRY_TYPE_IOAPIC, i);
|
||||
|
||||
__assert((entry->address % PAGE_SIZE) == 0);
|
||||
ioapics[i].addr = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(uint64_t)entry->address);
|
||||
__assert(ioapics[i].addr);
|
||||
ioapics[i].base = entry->gsi_base;
|
||||
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRYCOUNT) >> 16) & 0xff) + 1;
|
||||
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRY_COUNT) >> 16) & 0xff) + 1;
|
||||
printf("ioapic%lu: addr %p base %lu top %lu\n", i, entry->address, entry->gsi_base, ioapics[i].top);
|
||||
for (int j = ioapics[i].base; j < ioapics[i].top; ++j)
|
||||
writeiored(ioapics[i].addr, j - ioapics[i].base, 0xfe, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _TOPOLOGY_H
|
||||
#define _TOPOLOGY_H
|
||||
|
||||
#define TOPOLOGY_MAKE_ID(depth, id) ((depth << 16) | id)
|
||||
#define TOPOLOGY_MAKE_ID(depth, id) (((depth & 0xfffflu) << 16) | id)
|
||||
|
||||
#include <arch/cpu.h>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ size_t strlen(const char *str);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *str);
|
||||
void *memcpy(void *dest, const void *src, size_t size);
|
||||
void *memset(void *dest, unsigned long what, size_t size);
|
||||
void *memset(void *dest, int what, size_t size);
|
||||
int strcmp(const char *a, const char *b);
|
||||
int strncmp(const char *a, const char *b, size_t c);
|
||||
int memcmp(const void *a, const void *b, size_t s);
|
||||
|
||||
+8
-6
@@ -12,6 +12,11 @@ uint16_t pci_read16(int bus, int device, int function, uint32_t offset) {
|
||||
return (pci_archread32(bus, device, function, offset) >> ((offset & 0b11) * 8)) & 0xffff;
|
||||
}
|
||||
|
||||
uint32_t pci_read32(int bus, int device, int function, uint32_t offset) {
|
||||
return pci_archread32(bus, device, function, offset);
|
||||
}
|
||||
|
||||
|
||||
void pci_write8(int bus, int device, int function, uint32_t offset, uint8_t v) {
|
||||
uint32_t old = pci_archread32(bus, device, function, offset);
|
||||
int bitoffset = 8 * (offset & 0b11);
|
||||
@@ -23,19 +28,16 @@ void pci_write8(int bus, int device, int function, uint32_t offset, uint8_t v) {
|
||||
void pci_write16(int bus, int device, int function, uint32_t offset, uint16_t v) {
|
||||
uint32_t old = pci_archread32(bus, device, function, offset);
|
||||
int bitoffset = 8 * (offset & 0b11);
|
||||
old &= ~(0xffff << bitoffset);
|
||||
old |= v << bitoffset;
|
||||
old &= ~(0xfffflu << bitoffset);
|
||||
old |= (uint32_t)v << bitoffset;
|
||||
pci_archwrite32(bus, device, function, offset, old);
|
||||
}
|
||||
|
||||
uint32_t pci_read32(int bus, int device, int function, uint32_t offset) {
|
||||
return pci_archread32(bus, device, function, offset);
|
||||
}
|
||||
|
||||
void pci_write32(int bus, int device, int function, uint32_t offset, uint32_t value) {
|
||||
pci_archwrite32(bus, device, function, offset, value);
|
||||
}
|
||||
|
||||
|
||||
int pci_getcapoffset(pcienum_t *e, int cap, int n) {
|
||||
if ((PCI_READ16(e, PCI_CONFIG_STATUS) & PCI_STATUS_HASCAP) == 0)
|
||||
return 0;
|
||||
|
||||
@@ -30,7 +30,7 @@ static int maxseek(int minor, size_t *max) {
|
||||
|
||||
static long current = 0xdeadbeefbadc0ffe;
|
||||
|
||||
static uint8_t getrand8() {
|
||||
__attribute__((no_sanitize("undefined"))) static uint8_t getrand8() {
|
||||
current += timekeeper_timefromboot().ns * timekeeper_timefromboot().s - timekeeper_time().ns * timekeeper_time().s + timekeeper_time().s;
|
||||
return current & 0xff;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ void *memcpy(void *d, const void *s, size_t c) {
|
||||
return d;
|
||||
}
|
||||
|
||||
void *memset(void *ptr, unsigned long value, size_t num) {
|
||||
void *memset(void *ptr, int value, size_t num) {
|
||||
#ifdef __x86_64__
|
||||
asm volatile ("rep stosb" : : "D"(ptr), "a"(value), "c"(num) : "memory");
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
#include <stdint.h>
|
||||
#include <logging.h>
|
||||
|
||||
/*
|
||||
typedefs and some other bits taken from https://git.thenest.dev/wux/elysium-os/-/blob/5.0/kernel/src/ubsan.c
|
||||
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2024, ImWuX
|
||||
|
||||
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 the copyright holder 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 HOLDER 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.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *filename;
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
} source_location_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t kind;
|
||||
uint16_t info;
|
||||
char name[];
|
||||
} type_descriptor_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
} data_only_location_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *type;
|
||||
} data_location_type_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *type;
|
||||
} data_load_invalid_value_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
source_location_t attr_location;
|
||||
int arg_index;
|
||||
} data_nonnull_arg_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *lhs_type;
|
||||
type_descriptor_t *rhs_type;
|
||||
} data_shift_out_of_bounds_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *array_type;
|
||||
type_descriptor_t *index_type;
|
||||
} data_out_of_bounds_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *type;
|
||||
uint8_t alignment;
|
||||
uint8_t type_check_kind;
|
||||
} data_type_mismatch_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
source_location_t assumption_location;
|
||||
type_descriptor_t *type;
|
||||
} data_alignment_assumption_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
type_descriptor_t *from_type;
|
||||
type_descriptor_t *to_type;
|
||||
uint8_t kind;
|
||||
} data_implicit_conversion_t;
|
||||
|
||||
typedef struct {
|
||||
source_location_t location;
|
||||
uint8_t kind;
|
||||
} data_invalid_builtin_t;
|
||||
|
||||
const char *kind_to_type(uint16_t kind) {
|
||||
const char* type;
|
||||
switch (kind) {
|
||||
case 0: type = "integer"; break;
|
||||
case 1: type = "float"; break;
|
||||
default: type = "unknown"; break;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
unsigned int info_to_bits(uint16_t info) {
|
||||
return 1 << (info >> 1);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_load_invalid_value(data_load_invalid_value_t *data, uintptr_t value) {
|
||||
printf("\e[93mubsan: load_invalid_value @ %s:%u:%u {value: %#lx}\e[0m\n", data->location.filename, data->location.line, data->location.column, value);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nonnull_arg(data_nonnull_arg_t *data) {
|
||||
printf("\e[93mubsan: handle_nonnull_arg @ %s:%u:%u {arg_index: %i}\e[0m\n", data->location.filename, data->location.line, data->location.column, data->arg_index);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nullability_arg(data_nonnull_arg_t *data) {
|
||||
printf("\e[93mubsan: nullability_arg @ %s:%u:%u {arg_index: %i}\e[0m\n", data->location.filename, data->location.line, data->location.column, data->arg_index);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nonnull_return_v1(data_only_location_t *data [[maybe_unused]], source_location_t *location) {
|
||||
printf("\e[93mubsan: nonnull_return @ %s:%u:%u\e[0m\n", location->filename, location->line, location->column);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_nullability_return_v1(data_only_location_t *data [[maybe_unused]], source_location_t *location) {
|
||||
printf("\e[93mubsan: nullability_return @ %s:%u:%u\e[0m\n", location->filename, location->line, location->column);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_vla_bound_not_positive(data_location_type_t *data, uintptr_t bound) {
|
||||
printf("\e[93mubsan: vla_bound_not_positive @ %s:%u:%u {bound: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, bound, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_add_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
|
||||
printf("\e[93mubsan: add_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_sub_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
|
||||
printf("\e[93mubsan: sub_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_mul_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
|
||||
printf("\e[93mubsan: mul_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_divrem_overflow(data_location_type_t *data, uintptr_t lhs, uintptr_t rhs) {
|
||||
printf("\e[93mubsan: divrem_overflow @ %s:%u:%u {lhs: %#lx, rhs: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, lhs, rhs, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_negate_overflow(data_location_type_t *data, uintptr_t old) {
|
||||
printf("\e[93mubsan: negate_overflow @ %s:%u:%u {old: %#lx, type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, old, info_to_bits(data->type->info), kind_to_type(data->type->kind), data->type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_shift_out_of_bounds(data_shift_out_of_bounds_t *data, uintptr_t lhs, uintptr_t rhs) {
|
||||
printf("\e[93mubsan: shift_out_of_bounds @ %s:%u:%u {lhs: %#lx, rhs: %#lx, rhs_type: %u-bit %s %s, lhs_type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, lhs, rhs,
|
||||
info_to_bits(data->rhs_type->info), kind_to_type(data->rhs_type->kind), data->rhs_type->name,
|
||||
info_to_bits(data->lhs_type->info), kind_to_type(data->lhs_type->kind), data->lhs_type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_out_of_bounds(data_out_of_bounds_t *data, uint64_t index) {
|
||||
printf("\e[93mubsan: out_of_bounds @ %s:%u:%u {index: %#lx, array_type: %u-bit %s %s, index_type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, index,
|
||||
info_to_bits(data->array_type->info), kind_to_type(data->array_type->kind), data->array_type->name,
|
||||
info_to_bits(data->index_type->info), kind_to_type(data->index_type->kind), data->index_type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_type_mismatch_v1(data_type_mismatch_t *data, void *pointer) {
|
||||
static const char *kind_strs[] = {
|
||||
"load of",
|
||||
"store to",
|
||||
"reference binding to",
|
||||
"member access within",
|
||||
"member call on",
|
||||
"constructor call on",
|
||||
"downcast of",
|
||||
"downcast of",
|
||||
"upcast of",
|
||||
"cast to virtual base of",
|
||||
"nonnull binding to",
|
||||
"dynamic operation on"
|
||||
};
|
||||
|
||||
if(pointer == NULL) {
|
||||
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s NULL pointer of type %s)\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], data->type->name
|
||||
);
|
||||
} else if((1 << data->alignment) - 1) {
|
||||
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s misaligned address %#lx of type %s)\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], (uintptr_t) pointer, data->type->name
|
||||
);
|
||||
} else {
|
||||
printf("\e[93mubsan: type_mismatch @ %s:%u:%u (%s address %#lx, not enough spce for type %s)\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column, kind_strs[data->type_check_kind], (uintptr_t) pointer, data->type->name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_alignment_assumption(data_alignment_assumption_t *data, void *, void *, void *) {
|
||||
printf("\e[93mubsan: alignment_assumption @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_implicit_conversion(data_implicit_conversion_t *data, void *, void *) {
|
||||
printf("\e[93mubsan: implicit_conversion @ %s:%u:%u {from_type: %u-bit %s %s, to_type: %u-bit %s %s}\e[0m\n",
|
||||
data->location.filename, data->location.line, data->location.column,
|
||||
info_to_bits(data->from_type->info), kind_to_type(data->from_type->kind), data->from_type->name,
|
||||
info_to_bits(data->to_type->info), kind_to_type(data->to_type->kind), data->to_type->name
|
||||
);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_invalid_builtin(data_invalid_builtin_t *data) {
|
||||
printf("\e[93mubsan: invalid_builtin @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) void __ubsan_handle_pointer_overflow(data_only_location_t *data, void *, void *) {
|
||||
printf("\e[93mubsan: pointer_overflow @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) __attribute__((noreturn)) void __ubsan_handle_builtin_unreachable(data_only_location_t *data) {
|
||||
printf("\e[93mubsan: builtin_unreachable @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
|
||||
__assert(!"ubsan error");
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) __attribute__((noreturn)) void __ubsan_handle_missing_return(data_only_location_t *data) {
|
||||
printf("\e[93mubsan: missing_return @ %s:%u:%u\e[0m\n", data->location.filename, data->location.line, data->location.column);
|
||||
__assert(!"ubsan error");
|
||||
}
|
||||
@@ -35,7 +35,7 @@ static void dtor(scache_t *cache, void *obj) {
|
||||
}
|
||||
|
||||
static scache_t *getcachefromsize(size_t size) {
|
||||
if (size == 0)
|
||||
if (size <= 1)
|
||||
return caches[0];
|
||||
|
||||
size_t i = 64 - __builtin_clzll(size - 1);
|
||||
|
||||
+34
-34
@@ -4,48 +4,48 @@
|
||||
#include <limine.h>
|
||||
#include <logging.h>
|
||||
|
||||
static volatile struct limine_kernel_file_request kfreq = {
|
||||
static volatile struct limine_kernel_file_request kernel_file_request = {
|
||||
.id = LIMINE_KERNEL_FILE_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
static hashtable_t pairtable;
|
||||
static hashtable_t pair_table;
|
||||
|
||||
char *cmdline_get(char *key) {
|
||||
void *v;
|
||||
return hashtable_get(&pairtable, &v, key, strlen(key)) == 0 ? v : NULL;
|
||||
return hashtable_get(&pair_table, &v, key, strlen(key)) == 0 ? v : NULL;
|
||||
}
|
||||
|
||||
void cmdline_parse() {
|
||||
__assert(hashtable_init(&pairtable, 16) == 0);
|
||||
__assert(kfreq.response);
|
||||
struct limine_file *kernelfile = kfreq.response->kernel_file;
|
||||
__assert(kernelfile);
|
||||
char *cmdline = kernelfile->cmdline;
|
||||
__assert(hashtable_init(&pair_table, 16) == 0);
|
||||
__assert(kernel_file_request.response);
|
||||
struct limine_file *kernel_file = kernel_file_request.response->kernel_file;
|
||||
__assert(kernel_file);
|
||||
char *cmdline = kernel_file->cmdline;
|
||||
__assert(cmdline);
|
||||
|
||||
size_t bufferlen = strlen(cmdline) + 1;
|
||||
char buffer[bufferlen];
|
||||
memset(buffer, 0, bufferlen);
|
||||
char *cmdp = cmdline;
|
||||
char *buffp = buffer;
|
||||
size_t buffer_len = strlen(cmdline) + 1;
|
||||
char buffer[buffer_len];
|
||||
memset(buffer, 0, buffer_len);
|
||||
char *cmdline_ptr = cmdline;
|
||||
char *buffer_ptr = buffer;
|
||||
|
||||
bool doconvert = true;
|
||||
bool do_convert = true;
|
||||
|
||||
while (*cmdp) {
|
||||
char cmdchar = *cmdp++;
|
||||
if (cmdchar == ' ' && doconvert)
|
||||
*buffp++ = '\0';
|
||||
else if (cmdchar == '"') {
|
||||
doconvert = !doconvert;
|
||||
--bufferlen;
|
||||
while (*cmdline_ptr) {
|
||||
char cmd_char = *cmdline_ptr++;
|
||||
if (cmd_char == ' ' && do_convert)
|
||||
*buffer_ptr++ = '\0';
|
||||
else if (cmd_char == '"') {
|
||||
do_convert = !do_convert;
|
||||
--buffer_len;
|
||||
} else
|
||||
*buffp++ = cmdchar;
|
||||
*buffer_ptr++ = cmd_char;
|
||||
}
|
||||
buffer[bufferlen] = '\0';
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
|
||||
int i = 0;
|
||||
while (i < bufferlen) {
|
||||
while (i < buffer_len) {
|
||||
char *iterator = &buffer[i];
|
||||
bool pair = false;
|
||||
while (*iterator) {
|
||||
@@ -56,22 +56,22 @@ void cmdline_parse() {
|
||||
++iterator;
|
||||
}
|
||||
|
||||
size_t keylen = strlen(&buffer[i]);
|
||||
size_t key_len = strlen(&buffer[i]);
|
||||
if (pair) {
|
||||
char *valuep = &buffer[i + keylen + 1];
|
||||
size_t valuelen = strlen(valuep);
|
||||
char *value_ptr = &buffer[i + key_len + 1];
|
||||
size_t value_len = strlen(value_ptr);
|
||||
|
||||
char *value = alloc(valuelen) + 1;
|
||||
char *value = alloc(value_len) + 1;
|
||||
__assert(value);
|
||||
strcpy(value, valuep);
|
||||
__assert(hashtable_set(&pairtable, value, &buffer[i], keylen, true) == 0);
|
||||
i += valuelen + 1;
|
||||
strcpy(value, value_ptr);
|
||||
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
|
||||
i += value_len + 1;
|
||||
} else {
|
||||
char *value = alloc(keylen + 1);
|
||||
char *value = alloc(key_len + 1);
|
||||
__assert(value);
|
||||
strcpy(value, &buffer[i]);
|
||||
__assert(hashtable_set(&pairtable, value, &buffer[i], keylen, true) == 0);
|
||||
__assert(hashtable_set(&pair_table, value, &buffer[i], key_len, true) == 0);
|
||||
}
|
||||
i += keylen + 1;
|
||||
i += key_len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,6 +422,11 @@ void signal_signalproc(struct proc_t *proc, int signal) {
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("undefined"))) static inline void set_siginfo_ucontext(context_t *context, void *stack) {
|
||||
CTX_ARG1(context) = (uint64_t)&((sigframe_t *)stack)->siginfo;
|
||||
CTX_ARG2(context) = (uint64_t)ARCH_SIGFRAME_GET_UCONTEXT_POINTER((sigframe_t *)stack);
|
||||
}
|
||||
|
||||
// returns true if should retry check
|
||||
bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno, bool *need_context_switch) {
|
||||
bool retry = false;
|
||||
@@ -593,8 +598,7 @@ bool signal_check(struct thread_t *thread, context_t *context, bool syscall, uin
|
||||
CTX_IP(context) = (uint64_t)action->address;
|
||||
CTX_SP(context) = (uint64_t)stack;
|
||||
CTX_ARG0(context) = signal;
|
||||
CTX_ARG1(context) = (uint64_t)&((sigframe_t *)stack)->siginfo;
|
||||
CTX_ARG2(context) = (uint64_t)ARCH_SIGFRAME_GET_UCONTEXT_POINTER((sigframe_t *)stack);
|
||||
set_siginfo_ucontext(context, stack);
|
||||
|
||||
// reset handler if asked for
|
||||
if (action->flags & SA_RESETHAND)
|
||||
|
||||
Reference in New Issue
Block a user