diff --git a/include/sys/unwind.h b/include/sys/unwind.h new file mode 100644 index 0000000..9267db6 --- /dev/null +++ b/include/sys/unwind.h @@ -0,0 +1,125 @@ +#ifndef _SYS_UNWIND_H +#define _SYS_UNWIND_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum __unwind_reason_code { + __URC_NO_REASON, + __URC_FOREIGN_EXCEPTION, + __URC_FATAL_PHASE2, + __URC_FATAL_PHASE1, + __URC_NORMAL_STOP, + __URC_END_OF_STACK, + __URC_HANDLER_FOUND, + __URC_INSTALL_CONTEXT, + __URC_CONTINUE_UNWIND, +}; + + +#define __UA_SEARCH_PHASE 0x01 +#define __UA_CLEANUP_PHASE 0x02 +#define __UA_HANDLER_FRAME 0x04 +#define __UA_FORCE_UNWIND 0x08 +#define __UA_END_OF_STACK 0x10 + + + + +struct _nt_exception_record; +struct _nt_dispatcher_context; + +struct __unwind_exception; +struct __unwind_context; + + + + +typedef enum __unwind_reason_code(*__unwind_personality_routine)( + int, int, uintptr_t, + struct __unwind_exception *, + struct __unwind_context *); + +typedef void (*__unwind_exception_cleanup_routine)( + enum __unwind_reason_code, + struct __unwind_exception *); + + + +struct __unwind_exception { + uintptr_t exception_class; + __unwind_exception_cleanup_routine exception_cleanup; + uintptr_t __opaque[6]; +}; + + + +int __unwind_exception_filter( + struct _nt_exception_record *, + void *, + mcontext_t *, + struct _nt_dispatcher_context *, + __unwind_personality_routine); + +int __unwind_exception_handler( + struct _nt_exception_record *, + uintptr_t, + mcontext_t *, + struct _nt_dispatcher_context *); + +int __unwind_raise_exception( + struct __unwind_exception *); + +void __unwind_delete_exception( + struct __unwind_exception *); + +void __unwind_resume( + struct __unwind_exception *); + +int __unwind_resume_or_rethrow( + struct __unwind_exception *); + +int __unwind_force( + struct __unwind_exception *, + int (*)( + int, int, uintptr_t, + struct __unwind_exception *, + struct __unwind_context *, + void *), + void *); + +void * __unwind_get_language_specific_data( + struct __unwind_context *); + +int __unwind_backtrace( + enum __unwind_reason_code (*)( + struct __unwind_context *, + void *), + void *); + +int __unwind_calltrace(); + +uintptr_t __unwind_get_ip(const struct __unwind_context *); +void __unwind_set_ip(struct __unwind_context *, uintptr_t); + +uintptr_t __unwind_get_gr(const struct __unwind_context *, int); +void __unwind_set_gr(struct __unwind_context *, int, uintptr_t); + +uintptr_t __unwind_get_data_rel_base(const struct __unwind_context *); +uintptr_t __unwind_get_text_rel_base(const struct __unwind_context *); + +uintptr_t __unwind_get_cfa(const struct __unwind_context *); +uintptr_t __unwind_get_ip_info(const struct __unwind_context *, int *); + +uintptr_t __unwind_get_region_start(const struct __unwind_context *); +void * __unwind_find_enclosing_function(const void *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/arch.mk b/project/arch.mk index 6eb9f20..9bb0f43 100644 --- a/project/arch.mk +++ b/project/arch.mk @@ -1,5 +1,7 @@ ifeq ($(OS),midipix) +CFLAGS_CONFIG += -I\$(PROJECT_DIR)/include + src/env/__libc_start_main.lo: CFLAGS_SHARED += -USHARED SHARED_OBJS += crt/$(ARCH)/crtn.o @@ -20,4 +22,13 @@ LDFLAGS_CONFIG += -Wl,--exclude-symbols=_IO_putc LDFLAGS_CONFIG += -Wl,--exclude-symbols=_IO_putc_unlocked LDFLAGS_CONFIG += -Wl,--exclude-symbols=___errno_location +TARGET_SYS_HEADERS = \ + $(PROJECT_DIR)/include/sys/unwind.h \ + +install-headers: install-target-sys-headers + endif + +install-target-sys-headers: $(TARGET_SYS_HEADERS) + mkdir -p $(DESTDIR)$(INCLUDEDIR)/sys + cp -p $(TARGET_SYS_HEADERS) $(DESTDIR)$(INCLUDEDIR)/sys diff --git a/src/arch/nt64/unwind.c b/src/arch/nt64/unwind.c new file mode 100644 index 0000000..28026c6 --- /dev/null +++ b/src/arch/nt64/unwind.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include "psxseh.h" + +extern const struct __seh_vtbl * __seh_vtbl; + + +int __unwind_exception_filter( + struct _nt_exception_record * erec, + void * fctx, + mcontext_t * tctx, + struct _nt_dispatcher_context * dctx, + __unwind_personality_routine uw_routine) +{ + return __seh_vtbl->seh_exception_filter( + erec,fctx,tctx,dctx,uw_routine); +} + + +int __unwind_exception_handler( + struct _nt_exception_record * erec, + uintptr_t fbase, + mcontext_t * tctx, + struct _nt_dispatcher_context * dctx) +{ + return __seh_vtbl->seh_exception_handler( + erec,fbase,tctx,dctx); +} + + +int __unwind_raise_exception(struct __unwind_exception * e) +{ + return __seh_vtbl->seh_unwind_raise_exception(e); +} + + +void __unwind_delete_exception(struct __unwind_exception * e) +{ + return __seh_vtbl->seh_unwind_delete_exception(e); +} + + +void __unwind_resume(struct __unwind_exception * e) +{ + return __seh_vtbl->seh_unwind_resume(e); +} + + +int __unwind_resume_or_rethrow(struct __unwind_exception * e) +{ + return __seh_vtbl->seh_unwind_resume_or_rethrow(e); +} + + +int __unwind_force( + struct __unwind_exception * e, + int (*stop_fn)( + int, int, uintptr_t, + struct __unwind_exception *, + struct __unwind_context *, + void *), + void * ctx) +{ + return __seh_vtbl->seh_unwind_force(e,stop_fn,ctx); +} + + +void * __unwind_get_language_specific_data(struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_language_specific_data(uwctx); +} + + +int __unwind_backtrace( + enum __unwind_reason_code (*trace_fn)( + struct __unwind_context *, + void *), + void * ctx) +{ + return __seh_vtbl->seh_unwind_backtrace(trace_fn,ctx); +} + + +int __unwind_calltrace() +{ + return __seh_vtbl->seh_unwind_calltrace(); +} + + +uintptr_t __unwind_get_ip(const struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_ip(uwctx); +} + + +void __unwind_set_ip(struct __unwind_context * uwctx, uintptr_t ip) +{ + return __seh_vtbl->seh_unwind_set_ip(uwctx,ip); +} + + +uintptr_t __unwind_get_gr(const struct __unwind_context * uwctx, int idx) +{ + return __seh_vtbl->seh_unwind_get_gr(uwctx,idx); +} + + +void __unwind_set_gr(struct __unwind_context * uwctx, int idx, uintptr_t rval) +{ + return __seh_vtbl->seh_unwind_set_gr(uwctx,idx,rval); +} + + +uintptr_t __unwind_get_data_rel_base(const struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_data_rel_base(uwctx); +} + + +uintptr_t __unwind_get_text_rel_base(const struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_text_rel_base(uwctx); +} + + +uintptr_t __unwind_get_cfa(const struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_cfa(uwctx); +} + + +uintptr_t __unwind_get_ip_info(const struct __unwind_context * uwctx, int * pinfo) +{ + return __seh_vtbl->seh_unwind_get_ip_info(uwctx,pinfo); +} + + +uintptr_t __unwind_get_region_start(const struct __unwind_context * uwctx) +{ + return __seh_vtbl->seh_unwind_get_region_start(uwctx); +} + + +void * __unwind_find_enclosing_function(const void * addr) +{ + return __seh_vtbl->seh_unwind_find_enclosing_function(addr); +}