Starting Point
This commit is contained in:
1
lib/.gitignore
vendored
Normal file
1
lib/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# empty gitignore
|
||||
59
lib/mem.c
Normal file
59
lib/mem.c
Normal 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
154
lib/ubsan.c
Normal 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();
|
||||
}
|
||||
Reference in New Issue
Block a user