Exception handling poirting in gcc

11
Exception handling porting in GCC Shiva Chen [email protected] m MAY 2013

Transcript of Exception handling poirting in gcc

Page 1: Exception handling poirting in gcc

Exception handling porting in GCC

Shiva Chen

[email protected]

MAY 2013

Page 2: Exception handling poirting in gcc

Why need exception handling ?

Exceptions provide a way to react to exceptional circumstances (like runtime errors) Transferring control to special functions called

handlers Make system more stable

Page 3: Exception handling poirting in gcc

Example

// exceptions #include <iostream> using namespace std;

int main () { try { throw 20; } catch (int e) { cout << "An exception occurred. Exception Nr. " << e << endl; } return 0; }

Page 4: Exception handling poirting in gcc

Unwinding After throwing a exception object, exception library will do

unwinding frame to find the handler which could handle the exception object. There are two way to do unwinding

Set jump/long jump (SJLJ) unwinding Don’t know about the frame info restore all registers saved in the jump-buffer by setjmp Smaller code size but slower (store all register when enter each frame) Configure gcc with --enable-sjlj-exceptions

Dwarf2 unwinding Obtain eh_rame, gcc_except_table to record frame relative info Could know which register will really corrupt and restore the register which

really needed Code size bigger but faster

Page 5: Exception handling poirting in gcc

Dwarf2 unwinding

Startup code to support dwarf2 unwinding

_init call frame_dummy call __register_frame_info_base call __do_global_ctors

call atexit (__do_global_dtors)

__register_frame_info_base Called from crtbegin.o to register the unwind info for an object

libgcc/config.host extra_parts="crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o“Which will use libgcc/crtstuff.c to build startup code

Page 6: Exception handling poirting in gcc

Dwarf2 unwinding relative porting There are three thing for Dwarf2 unwinding are

ABI specific which need porting code to handle this part Pass exception info to exception handler

Prologue need preserve original register value Adjust stack pointer from unwind frame to handler Modify return value to exception handler

After unwinding, unwinding library will modify return value to handler and jump to handler by function return

Return value could be in Return register Frame stack

Page 7: Exception handling poirting in gcc

Dwarf2 unwinding relative porting Pass exception info to exception handler

Define EH_RETURN_DATA_REGNOThe register to pass exception infoPrologue need push original value to the stack before setting

exception info Adjust stack pointer from unwind frame to handler

Define EH_RETURN_STACKADJ_RTXThe register to contain adjust offset

Modify return value to exception handler Define EH_RETURN_HANDLER_RTX or eh_return

pattern To modify return value to handler

Page 8: Exception handling poirting in gcc

eh_return pattern of arm

arm_set_return_address (rtx source, rtx scratch) { … /* if return address in LR_REGNUM emit a move to change return address to handler */ if ((saved_regs & (1 << LR_REGNUM)) == 0) emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source);

/* return value in stack */ else { }

source contain return value

Page 9: Exception handling poirting in gcc

eh_return pattern of arm

arm_set_return_address (rtx source, rtx scratch) { … /* return value in stack */ else { if (frame_pointer_needed) addr = plus_constant(hard_frame_pointer_rtx, -4); else { /* LR will be the first saved register. */ delta = offsets->outgoing_args - (offsets->frame + 4); If (delta >= 4096) { emit_insn (gen_addsi3 (scratch, stack_pointer_rtx, GEN_INT (delta & ~4095))); addr = scratch; delta &= 4095; } else addr = stack_pointer_rtx; addr = plus_constant (addr, delta); } emit_move_insn (gen_frame_mem (Pmode, addr), source); } }

source contain return value

Use fp to find return address in stack

Emit memory move to modify return address in stack

Find the return address in stack

Page 10: Exception handling poirting in gcc

Sections for dwarf2 unwinding

.eh_frame Contains the information necessary to pop back to the

state of the machine registers and the stack at any point higher up the call stack

.gcc_except_table Contains information about the exception handling

"langing pads" the locations of handlers. This is necessary so as to know when to stop

unwinding. http://gcc.gnu.org/ml/gcc-help/2010-09/msg00116.html

Page 11: Exception handling poirting in gcc

Reference

C++ ABI for Itanium: Exception handling http://refspecs.linuxfoundation.org/abi-eh-

1.22.htm sjlj vs dw2 in GCC

http://stackoverflow.com/questions/318383/exception-handling-models-of-gcc