Starting Point

This commit is contained in:
Hannes
2025-10-26 15:21:48 +01:00
parent 788ca8b1c0
commit 532c3fc295
21 changed files with 631 additions and 0 deletions

1
lib/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
# empty gitignore

59
lib/mem.c Normal file
View File

@@ -0,0 +1,59 @@
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n)
{
const unsigned char *str1 = s1;
const unsigned char *str2 = s2;
int res = 0;
while (n > 0 && res == 0) {
res = *str1 - *str2;
str1++;
str2++;
n--;
}
return res;
}
void *memcpy(void *restrict s1, const void *restrict s2, size_t n)
{
char *restrict str1 = s1;
const char *restrict str2 = s2;
while (n > 0) {
*str1 = *str2;
str1++;
str2++;
n--;
}
return s1;
}
void *memmove(void *s1, const void *s2, size_t n)
{
char *str1 = s1;
const char *str2 = s2;
if (str1 < str2) {
while (n > 0) {
*str1 = *str2;
str1++;
str2++;
n--;
}
} else {
while (n > 0) {
n--;
*(str1 + n) = *(str2 + n);
}
}
return s1;
}
void *memset(void *s, int c, size_t n)
{
unsigned char *str = s;
while (n > 0) {
*str = (unsigned char)c;
str++;
n--;
}
return s;
}

154
lib/ubsan.c Normal file
View File

@@ -0,0 +1,154 @@
#include <stdint.h>
#include <stddef.h>
#include <arch/bsp/yellow_led.h>
#include <config.h>
#define halt() \
do { \
asm("cpsid if"); \
while (true) { \
asm("wfi"); \
} \
} while (0)
void kprintf [[gnu::format(printf, 1, 2)]] (const char *format, ...);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
void kprintf [[gnu::weak, gnu::format(printf, 1, 2)]] (const char *, ...)
{
init_yellow();
while (true) {
for (volatile unsigned int i = 0; i < BUSY_WAIT_COUNTER; i++) {
}
yellow_on();
for (volatile unsigned int i = 0; i < BUSY_WAIT_COUNTER; i++) {
}
yellow_off();
}
}
#pragma GCC diagnostic pop
// structs copyed form the linux kernel
// https://github.com/torvalds/linux/blob/master/lib/ubsan.h
struct source_location {
const char *file_name;
const uint32_t line;
const uint32_t column;
};
struct type_descriptor {
const uint16_t type_kind;
const uint16_t type_info;
const char type_name[1];
const char unused[3];
};
struct type_mismatch_data_v1 {
const struct source_location location;
const struct type_descriptor *type;
const unsigned char log_alignment;
const unsigned char type_check_kind;
const char unused[2];
};
struct out_of_bounds_data {
struct source_location loc;
struct type_descriptor *array_type;
struct type_descriptor *index_type;
};
static_assert(sizeof(unsigned int) == sizeof(long));
static void print_source_location(const struct source_location *location)
{
kprintf("%s:%u:%u", location->file_name, (unsigned int)location->line,
(unsigned int)location->column);
}
#define DEF_UBSAN_HANDLER(name) \
void __ubsan_handle_##name [[noreturn]] (const struct source_location *location); \
void __ubsan_handle_##name [[noreturn]] (const struct source_location *location) \
{ \
kprintf("Undefined behavior detected: " #name " at "); \
print_source_location(location); \
kprintf("\n"); \
halt(); \
}
DEF_UBSAN_HANDLER(add_overflow)
DEF_UBSAN_HANDLER(add_overflow_abort)
DEF_UBSAN_HANDLER(alignment_assumption)
DEF_UBSAN_HANDLER(builtin_unreachable)
DEF_UBSAN_HANDLER(alignment_assumption_abort)
DEF_UBSAN_HANDLER(cfi_check_fail)
DEF_UBSAN_HANDLER(cfi_bad_type)
DEF_UBSAN_HANDLER(divrem_overflow)
DEF_UBSAN_HANDLER(cfi_check_fail_abort)
DEF_UBSAN_HANDLER(dynamic_type_cache_miss)
DEF_UBSAN_HANDLER(divrem_overflow_abort)
DEF_UBSAN_HANDLER(float_cast_overflow)
DEF_UBSAN_HANDLER(dynamic_type_cache_miss_abort)
DEF_UBSAN_HANDLER(function_type_mismatch_v1)
DEF_UBSAN_HANDLER(float_cast_overflow_abort)
DEF_UBSAN_HANDLER(implicit_conversion)
DEF_UBSAN_HANDLER(function_type_mismatch_v1_abort)
DEF_UBSAN_HANDLER(invalid_builtin)
DEF_UBSAN_HANDLER(implicit_conversion_abort)
DEF_UBSAN_HANDLER(invalid_objc_cast)
DEF_UBSAN_HANDLER(invalid_builtin_abort)
DEF_UBSAN_HANDLER(load_invalid_value)
DEF_UBSAN_HANDLER(invalid_objc_cast_abort)
DEF_UBSAN_HANDLER(missing_return)
DEF_UBSAN_HANDLER(load_invalid_value_abort)
DEF_UBSAN_HANDLER(mul_overflow_abort)
DEF_UBSAN_HANDLER(mul_overflow)
DEF_UBSAN_HANDLER(negate_overflow_abort)
DEF_UBSAN_HANDLER(negate_overflow)
DEF_UBSAN_HANDLER(nonnull_arg_abort)
DEF_UBSAN_HANDLER(nonnull_arg)
DEF_UBSAN_HANDLER(nonnull_return_v1_abort)
DEF_UBSAN_HANDLER(nonnull_return_v1)
DEF_UBSAN_HANDLER(nullability_arg_abort)
DEF_UBSAN_HANDLER(nullability_arg)
DEF_UBSAN_HANDLER(nullability_return_v1_abort)
DEF_UBSAN_HANDLER(nullability_return_v1)
DEF_UBSAN_HANDLER(out_of_bounds_abort)
DEF_UBSAN_HANDLER(pointer_overflow_abort)
DEF_UBSAN_HANDLER(pointer_overflow)
DEF_UBSAN_HANDLER(shift_out_of_bounds_abort)
DEF_UBSAN_HANDLER(shift_out_of_bounds)
DEF_UBSAN_HANDLER(sub_overflow_abort)
DEF_UBSAN_HANDLER(sub_overflow)
DEF_UBSAN_HANDLER(type_mismatch_v1_abort)
DEF_UBSAN_HANDLER(vla_bound_not_positive_abort)
DEF_UBSAN_HANDLER(vla_bound_not_positive)
void __ubsan_handle_out_of_bounds
[[noreturn]] (struct out_of_bounds_data *data, unsigned long index);
void __ubsan_handle_out_of_bounds
[[noreturn]] (struct out_of_bounds_data *data, unsigned long index)
{
kprintf("Undefined behavior detected: out of bounds access index %u at ",
(unsigned int)index);
print_source_location(&data->loc);
kprintf("\n");
halt();
}
void __ubsan_handle_type_mismatch_v1 [[noreturn]] (struct type_mismatch_data_v1 *data_v1, int ptr);
void __ubsan_handle_type_mismatch_v1 [[noreturn]] (struct type_mismatch_data_v1 *data_v1, int ptr)
{
if (ptr == (uint32_t)NULL) {
kprintf("Undefined behavior detected: null pointer access at ");
} else if (data_v1->log_alignment && (ptr & (data_v1->log_alignment - 1))) {
kprintf("Undefined behavior detected: unaligned access at ");
} else {
kprintf("Undefined behavior detected: type mismatch at ");
}
print_source_location(&data_v1->location);
kprintf("\n");
halt();
}