Compare commits
No commits in common. "8352df5ee879d100b664163b1407b0853653b9e6" and "794567327f5fc00feb208bce5ad6caeddf11188d" have entirely different histories.
8352df5ee8
...
794567327f
@ -1,2 +1 @@
|
|||||||
target_compile_definitions(moon PRIVATE LOCKED_VALUE_DEBUG)
|
target_compile_definitions(moon PRIVATE LOCKED_VALUE_DEBUG)
|
||||||
target_compile_options(moon PRIVATE -fsanitize=undefined)
|
|
||||||
|
@ -84,5 +84,4 @@ void debug_log_impl(const char* format, va_list ap)
|
|||||||
{
|
{
|
||||||
pure_cstyle_format(
|
pure_cstyle_format(
|
||||||
format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap);
|
format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap);
|
||||||
console_write("\n", 1);
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ set(FREESTANDING_SOURCES
|
|||||||
src/DebugLog.cpp
|
src/DebugLog.cpp
|
||||||
src/Heap.cpp
|
src/Heap.cpp
|
||||||
src/Spinlock.cpp
|
src/Spinlock.cpp
|
||||||
src/UBSAN.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <luna/Types.h>
|
|
||||||
|
|
||||||
namespace UBSAN
|
|
||||||
{
|
|
||||||
struct SourceLocation
|
|
||||||
{
|
|
||||||
const char* file;
|
|
||||||
u32 line;
|
|
||||||
u32 column;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeDescriptor
|
|
||||||
{
|
|
||||||
u16 kind;
|
|
||||||
u16 info;
|
|
||||||
char name[];
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace UBInfo
|
|
||||||
{
|
|
||||||
struct TypeMismatchInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* type;
|
|
||||||
usize alignment;
|
|
||||||
u8 type_check_kind;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeMismatchInfo_v1
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* type;
|
|
||||||
u8 log_alignment;
|
|
||||||
u8 type_check_kind;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OverflowInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UnreachableInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OutOfBoundsInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* array_type;
|
|
||||||
TypeDescriptor* index_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InvalidValueInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShiftOutOfBoundsInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
TypeDescriptor* lhs_type;
|
|
||||||
TypeDescriptor* rhs_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PointerOverflowInfo
|
|
||||||
{
|
|
||||||
SourceLocation location;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
#include <luna/Check.h>
|
|
||||||
#include <luna/DebugLog.h>
|
|
||||||
#include <luna/SourceLocation.h>
|
|
||||||
#include <luna/UBSAN.h>
|
|
||||||
|
|
||||||
using namespace UBSAN::UBInfo;
|
|
||||||
|
|
||||||
[[noreturn]] void ub_panic(SourceLocation caller = SourceLocation::current())
|
|
||||||
{
|
|
||||||
expect_at(false, caller, "Undefined behavior");
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DISPLAY(loc) loc.file, loc.line, loc.column
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
void __ubsan_handle_builtin_unreachable(UnreachableInfo* info)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: __builtin_unreachable reached at %s:%d:%d", DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __ubsan_handle_pointer_overflow(PointerOverflowInfo* info)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: pointer overflow occurred at %s:%d:%d", DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsInfo* info)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: shift out of bounds for type %s at %s:%d:%d", info->lhs_type->name, DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __ubsan_handle_load_invalid_value(InvalidValueInfo* info)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: load invalid value for type %s at %s:%d:%d", info->type->name, DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __ubsan_handle_out_of_bounds(OutOfBoundsInfo* info, usize index)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: out of bounds array (of type %s) access (index %zu of type %s) at %s:%d:%d",
|
|
||||||
info->array_type->name, index, info->index_type->name, DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ubsan_handle_generic_overflow(OverflowInfo* info, const char* overflow_type)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
dbgln("ubsan: %s overflow (value cannot fit into type %s) at %s:%d:%d", overflow_type, info->type->name,
|
|
||||||
DISPLAY(location));
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UBSAN_OVERFLOW_BINARY(operation) \
|
|
||||||
void __ubsan_handle_##operation##_overflow(OverflowInfo* info, usize, usize) \
|
|
||||||
{ \
|
|
||||||
ubsan_handle_generic_overflow(info, #operation); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UBSAN_OVERFLOW_UNARY(operation) \
|
|
||||||
void __ubsan_handle_##operation##_overflow(OverflowInfo* info, usize) \
|
|
||||||
{ \
|
|
||||||
ubsan_handle_generic_overflow(info, #operation); \
|
|
||||||
}
|
|
||||||
|
|
||||||
UBSAN_OVERFLOW_BINARY(add);
|
|
||||||
UBSAN_OVERFLOW_BINARY(sub);
|
|
||||||
UBSAN_OVERFLOW_BINARY(mul);
|
|
||||||
UBSAN_OVERFLOW_UNARY(negate);
|
|
||||||
UBSAN_OVERFLOW_BINARY(divrem);
|
|
||||||
|
|
||||||
#define is_aligned(value, alignment) !(value & (alignment - 1))
|
|
||||||
|
|
||||||
const char* g_type_check_kinds[] = {
|
|
||||||
"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",
|
|
||||||
};
|
|
||||||
|
|
||||||
void __ubsan_handle_type_mismatch(TypeMismatchInfo* info, usize pointer)
|
|
||||||
{
|
|
||||||
const auto& location = info->location;
|
|
||||||
|
|
||||||
if (pointer == 0) { dbgln("ubsan: null pointer access at %s:%d:%d", DISPLAY(location)); }
|
|
||||||
else if (info->alignment != 0 && is_aligned(pointer, info->alignment))
|
|
||||||
{
|
|
||||||
dbgln("ubsan: unaligned pointer access (address %p) at %s:%d:%d", (void*)pointer, DISPLAY(location));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbgln("ubsan: %s address %p with insufficient space for object of type %s at %s:%d:%d",
|
|
||||||
g_type_check_kinds[info->type_check_kind], (void*)pointer, info->type->name, DISPLAY(location));
|
|
||||||
}
|
|
||||||
ub_panic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __ubsan_handle_type_mismatch_v1(TypeMismatchInfo_v1* v1_info, usize pointer)
|
|
||||||
{
|
|
||||||
TypeMismatchInfo info = {
|
|
||||||
.location = v1_info->location,
|
|
||||||
.type = v1_info->type,
|
|
||||||
.alignment = 1UL << v1_info->log_alignment,
|
|
||||||
.type_check_kind = v1_info->type_check_kind,
|
|
||||||
};
|
|
||||||
__ubsan_handle_type_mismatch(&info, pointer);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user