rt.dwarfeh

Exception handling support for Dwarf-style portable exceptions.

License:
Distributed under the Boost Software License 1.0. (See accompanying file LICENSE)
Authors:
Walter Bright
Source
rt/dwarfeh.d
struct ExceptionHeader;

Wrap the unwinder's data with our own compiler specific struct with our own data.

static @nogc ExceptionHeader* create(Throwable o);

Allocate and initialize an ExceptionHeader.

Parameters:
Throwable o thrown object
Returns:
allocated and initalized ExceptionHeader
static void free(ExceptionHeader* eh);

Free ExceptionHeader that was created by create().

Parameters:
ExceptionHeader* eh ExceptionHeader to free
void push();

Push this onto stack of chained exceptions.

static ExceptionHeader* pop();

Pop and return top of chained exception stack.

static ExceptionHeader* toExceptionHeader(_Unwind_Exception* eo);

Convert from pointer to exception_object to pointer to ExceptionHeader that it is embedded inside of.

Parameters:
_Unwind_Exception* eo pointer to exception_object field
Returns:
pointer to ExceptionHeader that eo points into.
Throwable __dmd_begin_catch(_Unwind_Exception* exceptionObject);

The first thing a catch handler does is call this.

Parameters:
_Unwind_Exception* exceptionObject value passed to catch handler by unwinder
Returns:
object that was caught
nothrow @nogc void* _d_eh_swapContextDwarf(void* newContext);

Called when fibers switch contexts.

Parameters:
void* newContext stack to switch to
Returns:
previous value of stack
void _d_throwdwarf(Throwable o);

Called by D code to throw an exception via

throw o;

Parameters:
Throwable o Object to throw
Returns:
doesn't return
_Unwind_Reason_Code __dmd_personality_v0(int ver, _Unwind_Action actions, _Unwind_Exception_Class exceptionClass, _Unwind_Exception* exceptionObject, _Unwind_Context* context);

"personality" function, specific to each language. This one, of course, is specific to DMD.

Parameters:
int ver version must be 1
_Unwind_Action actions bitwise OR of the 4 actions UA_xxx. UA_SEARCH_PHASE means return URC_HANDLER_FOUND if current frame has a handler, URC_CONTINUE_UNWIND if not. Cannot be used with UA_CLEANUP_PHASE. UA_CLEANUP_PHASE means perform cleanup for current frame by calling nested functions and returning URC_CONTINUE_UNWIND. Or, set up registers and IP for Landing Pad and return URC_INSTALL_CONTEXT. UA_HANDLER_FRAME means this frame was the one with the handler in Phase 1, and now it is Phase 2 and the handler must be run. UA_FORCE_UNWIND means unwinding the stack for longjmp or thread cancellation. Run finally clauses, not catch clauses, finallys must end with call to Uwind_Resume().
_Unwind_Exception_Class exceptionClass 8 byte value indicating type of thrown exception. If the low 4 bytes are "C++\0", it's a C++ exception.
_Unwind_Exception* exceptionObject language specific exception information
_Unwind_Context* context opaque type of unwinder state information
Returns:
reason code
See Also:
http://www.ucw.cz/~hubicka/papers/abi/node25.html
ClassInfo getClassInfo(_Unwind_Exception* exceptionObject, const(ubyte)* currentLsd);

Look at the chain of inflight exceptions and pick the class type that'll be looked for in catch clauses.

Parameters:
_Unwind_Exception* exceptionObject language specific exception information
const(ubyte)* currentLsd pointer to LSDA table
Returns:
class type to look for
_uleb128_t uLEB128(const(ubyte)** p);

Decode Unsigned LEB128.

Parameters:
const(ubyte)** p pointer to data pointer, *p is updated to point past decoded value
Returns:
decoded value
See Also:
https://en.wikipedia.org/wiki/LEB128
_sleb128_t sLEB128(const(ubyte)** p);

Decode Signed LEB128.

Parameters:
const(ubyte)** p pointer to data pointer, *p is updated to point past decoded value
Returns:
decoded value
See Also:
https://en.wikipedia.org/wiki/LEB128
LsdaResult scanLSDA(const(ubyte)* lsda, _Unwind_Ptr ip, _Unwind_Exception_Class exceptionClass, bool cleanupsOnly, bool preferHandler, _Unwind_Exception* exceptionObject, out _Unwind_Ptr landingPad, out int handler);

Read and extract information from the LSDA (aka gcc_except_table section). The dmd Call Site Table is structurally different from other implementations. It is organized as nested ranges, and one ip can map to multiple ranges. The most nested candidate is selected when searched. Other implementations have one candidate per ip.

Parameters:
const(ubyte)* lsda pointer to LSDA table
_Unwind_Ptr ip offset from start of function at which exception happened
_Unwind_Exception_Class exceptionClass which language threw the exception
bool cleanupsOnly only look for cleanups
bool preferHandler if a handler encloses a cleanup, prefer the handler
_Unwind_Exception* exceptionObject language specific exception information
_Unwind_Ptr landingPad set to landing pad
int handler set to index of which catch clause was matched
Returns:
LsdaResult
See Also:
http://reverseengineering.stackexchange.com/questions/6311/how-to-recover-the-exception-info-from-gcc-except-table-and-eh-handle-sections http://www.airs.com/blog/archives/464 https://anarcheuz.github.io/2015/02/15/ELF%20internals%20part%202%20-%20exception%20handling/
int actionTableLookup(_Unwind_Exception* exceptionObject, uint actionRecordPtr, const(ubyte)* pActionTable, const(ubyte)* tt, ubyte TType, _Unwind_Exception_Class exceptionClass, const(ubyte)* lsda);

Look up classType in Action Table.

Parameters:
_Unwind_Exception* exceptionObject language specific exception information
uint actionRecordPtr starting index in Action Table + 1
const(ubyte)* pActionTable pointer to start of Action Table
const(ubyte)* tt pointer past end of Type Table
ubyte TType encoding of entries in Type Table
_Unwind_Exception_Class exceptionClass which language threw the exception
const(ubyte)* lsda pointer to LSDA table
Returns:
  • >=1 means the handler index of the classType
  • 0 means classType is not in the Action Table
  • <0 means corrupt
enum _Unwind_Exception_Class cppExceptionClass;

C++ Support

void* getCppPtrToThrownObject(_Unwind_Exception* exceptionObject, CppTypeInfo sti);

Get Pointer to Thrown Object if type of thrown object is implicitly convertible to the catch type.

Parameters:
_Unwind_Exception* exceptionObject language specific exception information
CppTypeInfo sti type of catch clause
Returns:
null if not caught, pointer to thrown object if caught
interface CppTypeInfo;

Access C++ std::type_info's virtual functions from D, being careful to not require linking with libstd++ or interfere with core.stdcpp.typeinfo. So, give it a different name.

struct CppExceptionHeader;

The C++ version of D's ExceptionHeader wrapper

static CppExceptionHeader* toExceptionHeader(_Unwind_Exception* eo);

Convert from pointer to exception_object field to pointer to CppExceptionHeader that it is embedded inside of.

Parameters:
_Unwind_Exception* eo pointer to exception_object field
Returns:
pointer to CppExceptionHeader that eo points into.

© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/rt_dwarfeh.html