aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-10-07 15:28:36 -0700
committerIan Lance Taylor <iant@golang.org>2021-10-07 15:28:36 -0700
commit0b6b70a0733672600644c8df96942cda5bf86d3d (patch)
tree9a1fbd7f782c54df55ab225ed1be057e3f3b0b8a /libphobos
parenta5b5cabc91c38710adbe5c8a2b53882abe994441 (diff)
parentfba228e259dd5112851527f2dbb62c5601100985 (diff)
downloadgcc-0b6b70a0733672600644c8df96942cda5bf86d3d.zip
gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.gz
gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.bz2
Merge from trunk revision fba228e259dd5112851527f2dbb62c5601100985.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/ChangeLog34
-rw-r--r--libphobos/libdruntime/__main.di14
-rw-r--r--libphobos/libdruntime/core/runtime.d14
-rw-r--r--libphobos/libdruntime/gcc/backtrace.d24
-rw-r--r--libphobos/libdruntime/gcc/deh.d79
-rw-r--r--libphobos/libdruntime/gcc/unwind/generic.d22
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;