summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-03-10 09:39:55 -0400
committermidipix <writeonce@midipix.org>2019-03-12 02:27:23 -0400
commitd293463f416a242c4a6e6c28d593fd3955112be5 (patch)
treea71cba5d83fc869610af31838e67604674792e3f
parente1d2681818033bd7475408fc4e3847fcaaf8e275 (diff)
downloadmmglue-d293463f416a242c4a6e6c28d593fd3955112be5.tar.bz2
mmglue-d293463f416a242c4a6e6c28d593fd3955112be5.tar.xz
midipix: nt64: added sys/unwind.h, unwind (framework wrapper) interfaces.
-rw-r--r--include/sys/unwind.h125
-rw-r--r--project/arch.mk11
-rw-r--r--src/arch/nt64/unwind.c148
3 files changed, 284 insertions, 0 deletions
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 <stdint.h>
+#include <signal.h>
+
+#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 <stdint.h>
+#include <signal.h>
+#include <sys/unwind.h>
+#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);
+}