diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-10-07 15:28:36 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-10-07 15:28:36 -0700 |
commit | 0b6b70a0733672600644c8df96942cda5bf86d3d (patch) | |
tree | 9a1fbd7f782c54df55ab225ed1be057e3f3b0b8a /libphobos | |
parent | a5b5cabc91c38710adbe5c8a2b53882abe994441 (diff) | |
parent | fba228e259dd5112851527f2dbb62c5601100985 (diff) | |
download | gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.zip gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.gz gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.bz2 |
Merge from trunk revision fba228e259dd5112851527f2dbb62c5601100985.
Diffstat (limited to 'libphobos')
-rw-r--r-- | libphobos/ChangeLog | 34 | ||||
-rw-r--r-- | libphobos/libdruntime/__main.di | 14 | ||||
-rw-r--r-- | libphobos/libdruntime/core/runtime.d | 14 | ||||
-rw-r--r-- | libphobos/libdruntime/gcc/backtrace.d | 24 | ||||
-rw-r--r-- | libphobos/libdruntime/gcc/deh.d | 79 | ||||
-rw-r--r-- | libphobos/libdruntime/gcc/unwind/generic.d | 22 |
6 files changed, 121 insertions, 66 deletions
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index fa1aef7..0cc0b3d 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,37 @@ +2021-09-30 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/gcc/deh.d (ExceptionHeader.getClassInfo): Move to... + (getClassInfo): ...here as free function. Add lsda parameter. + (scanLSDA): Pass lsda to actionTableLookup. + (actionTableLookup): Add lsda parameter, pass to getClassInfo. + (__gdc_personality): Remove currentCfa variable. + +2021-09-30 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/gcc/deh.d (_d_print_throwable): Declare. + (_d_throw): Print stacktrace before terminating program due to + uncaught exception. + +2021-09-30 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/core/runtime.d (runModuleUnitTests): Use scope to new + LibBacktrace on the stack. + * libdruntime/gcc/backtrace.d (FIRSTFRAME): Remove. + (LibBacktrace.MaxAlignment): Remove. + (LibBacktrace.this): Remove default initialization of firstFrame. + (UnwindBacktrace.this): Likewise. + +2021-09-30 Iain Buclaw <ibuclaw@gdcproject.org> + + * libdruntime/gcc/unwind/generic.d (__aligned__): Define. + (_Unwind_Exception): Align struct to __aligned__. + +2021-09-30 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/102476 + * libdruntime/__main.di: Define main function as extern(C) when + compiling without D runtime. + 2021-09-01 Iain Buclaw <ibuclaw@gdcproject.org> * m4/druntime/os.m4: Update comment for DRUNTIME_OS_SOURCES. diff --git a/libphobos/libdruntime/__main.di b/libphobos/libdruntime/__main.di index 8062bf4..ab1264b 100644 --- a/libphobos/libdruntime/__main.di +++ b/libphobos/libdruntime/__main.di @@ -20,7 +20,17 @@ module __main; -int main(char[][]) +version (D_BetterC) { - return 0; + extern (C) int main(int, char**) + { + return 0; + } +} +else +{ + int main(char[][]) + { + return 0; + } } diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d index 848b607..5fc9904 100644 --- a/libphobos/libdruntime/core/runtime.d +++ b/libphobos/libdruntime/core/runtime.d @@ -483,17 +483,9 @@ extern (C) bool runModuleUnitTests() fprintf(stderr, "Segmentation fault while running unittests:\n"); fprintf(stderr, "----------------\n"); - enum alignment = LibBacktrace.MaxAlignment; - enum classSize = __traits(classInstanceSize, LibBacktrace); - - void[classSize + alignment] bt_store = void; - void* alignedAddress = cast(byte*)((cast(size_t)(bt_store.ptr + alignment - 1)) - & ~(alignment - 1)); - - (alignedAddress[0 .. classSize]) = typeid(LibBacktrace).initializer[]; - auto bt = cast(LibBacktrace)(alignedAddress); - // First frame is LibBacktrace ctor. Second is signal handler, but include that for now - bt.__ctor(1); + // First frame is LibBacktrace ctor. Second is signal handler, + // but include that for now + scope bt = new LibBacktrace(1); foreach (size_t i, const(char[]) msg; bt) fprintf(stderr, "%s\n", msg.ptr ? msg.ptr : "???"); diff --git a/libphobos/libdruntime/gcc/backtrace.d b/libphobos/libdruntime/gcc/backtrace.d index 8f5582d..3c4d65f 100644 --- a/libphobos/libdruntime/gcc/backtrace.d +++ b/libphobos/libdruntime/gcc/backtrace.d @@ -24,24 +24,6 @@ module gcc.backtrace; import gcc.libbacktrace; -version (Posix) -{ - // NOTE: The first 5 frames with the current implementation are - // inside core.runtime and the object code, so eliminate - // these for readability. The alternative would be to - // exclude the first N frames that are in a list of - // mangled function names. - private enum FIRSTFRAME = 5; -} -else -{ - // NOTE: On Windows, the number of frames to exclude is based on - // whether the exception is user or system-generated, so - // it may be necessary to exclude a list of function names - // instead. - private enum FIRSTFRAME = 0; -} - // Max size per line of the traceback. private enum MAX_BUFSIZE = 1536; @@ -205,8 +187,6 @@ static if (BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC) // FIXME: state is never freed as libbacktrace doesn't provide a free function... public class LibBacktrace : Throwable.TraceInfo { - enum MaxAlignment = (void*).alignof; - static void initLibBacktrace() { if (!initialized) @@ -216,7 +196,7 @@ static if (BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC) } } - this(int firstFrame = FIRSTFRAME) + this(int firstFrame) { _firstFrame = firstFrame; @@ -365,7 +345,7 @@ else */ public class UnwindBacktrace : Throwable.TraceInfo { - this(int firstFrame = FIRSTFRAME) + this(int firstFrame) { _firstFrame = firstFrame; _callstack = getBacktrace(); diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index eb83751c..ba57fed 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -34,6 +34,7 @@ extern(C) { int _d_isbaseof(ClassInfo, ClassInfo); void _d_createTrace(Object, void*); + void _d_print_throwable(Throwable t); } /** @@ -279,26 +280,6 @@ struct ExceptionHeader } /** - * Look at the chain of inflight exceptions and pick the class type that'll - * be looked for in catch clauses. - */ - static ClassInfo getClassInfo(_Unwind_Exception* unwindHeader) @nogc - { - ExceptionHeader* eh = toExceptionHeader(unwindHeader); - // The first thrown Exception at the top of the stack takes precedence - // over others that are inflight, unless an Error was thrown, in which - // case, we search for error handlers instead. - Throwable ehobject = eh.object; - for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next) - { - Error e = cast(Error)ehobject; - if (e is null || (cast(Error)ehn.object) !is null) - ehobject = ehn.object; - } - return ehobject.classinfo; - } - - /** * Convert from pointer to unwindHeader to pointer to ExceptionHeader * that it is embedded inside of. */ @@ -510,7 +491,11 @@ extern(C) void _d_throw(Throwable object) // things, almost certainly we will have crashed before now, rather than // actually being able to diagnose the problem. if (r == _URC_END_OF_STACK) + { + __gdc_begin_catch(&eh.unwindHeader); + _d_print_throwable(object); terminate("uncaught exception", __LINE__); + } terminate("unwind error", __LINE__); } @@ -661,7 +646,7 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti { // Otherwise we have a catch handler or exception specification. handler = actionTableLookup(actions, unwindHeader, actionRecord, - exceptionClass, TTypeBase, + lsda, exceptionClass, TTypeBase, TType, TTypeEncoding, saw_handler, saw_cleanup); } @@ -689,7 +674,8 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti * Look up and return the handler index of the classType in Action Table. */ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, - const(ubyte)* actionRecord, _Unwind_Exception_Class exceptionClass, + const(ubyte)* actionRecord, const(ubyte)* lsda, + _Unwind_Exception_Class exceptionClass, _Unwind_Ptr TTypeBase, const(ubyte)* TType, ubyte TTypeEncoding, out bool saw_handler, out bool saw_cleanup) @@ -697,7 +683,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, ClassInfo thrownType; if (isGdcExceptionClass(exceptionClass)) { - thrownType = ExceptionHeader.getClassInfo(unwindHeader); + thrownType = getClassInfo(unwindHeader, lsda); } while (1) @@ -774,6 +760,41 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, } /** + * Look at the chain of inflight exceptions and pick the class type that'll + * be looked for in catch clauses. + */ +ClassInfo getClassInfo(_Unwind_Exception* unwindHeader, + const(ubyte)* currentLsd) @nogc +{ + ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader); + // The first thrown Exception at the top of the stack takes precedence + // over others that are inflight, unless an Error was thrown, in which + // case, we search for error handlers instead. + Throwable ehobject = eh.object; + for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next) + { + const(ubyte)* nextLsd = void; + _Unwind_Ptr nextLandingPad = void; + _Unwind_Word nextCfa = void; + int nextHandler = void; + + ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa); + + // Don't combine when the exceptions are from different functions. + if (currentLsd != nextLsd) + break; + + Error e = cast(Error)ehobject; + if (e is null || (cast(Error)ehn.object) !is null) + { + currentLsd = nextLsd; + ehobject = ehn.object; + } + } + return ehobject.classinfo; +} + +/** * Called when the personality function has found neither a cleanup or handler. * To support ARM EABI personality routines, that must also unwind the stack. */ @@ -929,16 +950,15 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions, // current object onto the end of the prevous object. ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader); auto currentLsd = lsda; - auto currentCfa = cfa; bool bypassed = false; while (eh.next) { ExceptionHeader* ehn = eh.next; - const(ubyte)* nextLsd; - _Unwind_Ptr nextLandingPad; - _Unwind_Word nextCfa; - int nextHandler; + const(ubyte)* nextLsd = void; + _Unwind_Ptr nextLandingPad = void; + _Unwind_Word nextCfa = void; + int nextHandler = void; ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa); @@ -947,14 +967,13 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions, { // We found an Error, bypass the exception chain. currentLsd = nextLsd; - currentCfa = nextCfa; eh = ehn; bypassed = true; continue; } // Don't combine when the exceptions are from different functions. - if (currentLsd != nextLsd && currentCfa != nextCfa) + if (currentLsd != nextLsd) break; // Add our object onto the end of the existing chain. diff --git a/libphobos/libdruntime/gcc/unwind/generic.d b/libphobos/libdruntime/gcc/unwind/generic.d index 592b3af..68ddd1d 100644 --- a/libphobos/libdruntime/gcc/unwind/generic.d +++ b/libphobos/libdruntime/gcc/unwind/generic.d @@ -123,7 +123,27 @@ enum : _Unwind_Reason_Code // @@@ The IA-64 ABI says that this structure must be double-word aligned. // Taking that literally does not make much sense generically. Instead we // provide the maximum alignment required by any type for the machine. -struct _Unwind_Exception + version (ARM) private enum __aligned__ = 8; +else version (AArch64) private enum __aligned__ = 16; +else version (HPPA) private enum __aligned__ = 8; +else version (HPPA64) private enum __aligned__ = 16; +else version (MIPS_N32) private enum __aligned__ = 16; +else version (MIPS_N64) private enum __aligned__ = 16; +else version (MIPS32) private enum __aligned__ = 8; +else version (MIPS64) private enum __aligned__ = 8; +else version (PPC) private enum __aligned__ = 16; +else version (PPC64) private enum __aligned__ = 16; +else version (RISCV32) private enum __aligned__ = 16; +else version (RISCV64) private enum __aligned__ = 16; +else version (S390) private enum __aligned__ = 8; +else version (SPARC) private enum __aligned__ = 8; +else version (SPARC64) private enum __aligned__ = 16; +else version (SystemZ) private enum __aligned__ = 8; +else version (X86) private enum __aligned__ = 16; +else version (X86_64) private enum __aligned__ = 16; +else static assert( false, "Platform not supported."); + +align(__aligned__) struct _Unwind_Exception { _Unwind_Exception_Class exception_class; _Unwind_Exception_Cleanup_Fn exception_cleanup; |