1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#include "stdafx.h"
#include "Gc/DwarfTable.h"
#ifdef POSIX
namespace code {
namespace eh {
// Struct used as a parameter to '_Unwind_Find_FDE'.
struct dwarf_eh_bases {
void *tbase;
void *dbase;
void *func;
};
// Previous version of the _Unwind_Find_FDE function (present in libgcc.so). Put inside a
// class to use the one-time initialization without additional locks.
struct PrevFindFDE {
typedef FDE *(*Ptr)(void *pc, struct dwarf_eh_bases *bases);
Ptr ptr;
PrevFindFDE() {
ptr = (Ptr)dlsym(RTLD_NEXT, "_Unwind_Find_FDE");
if (!ptr) {
printf("Failed to initialize exception handling (no _Unwind_Find_FDE found)\n");
printf("Did you compile Storm using GCC with DWARF2 unwind information?\n");
exit(250);
}
}
};
// Previous FDE finding function.
PrevFindFDE prevFindFDE;
// Hook into the exception resolution system so that we can provide our generated DWARF
// frames when required.
extern "C" SHARED_EXPORT FDE *_Unwind_Find_FDE(void *pc, struct dwarf_eh_bases *bases) {
// Try asking the standard library first.
FDE *found = (*prevFindFDE.ptr)(pc, bases);
if (found)
return found;
// If the standard library did not know of the current 'pc', then we try to find it
// inside the code generated by Storm!
found = dwarfTable().find(pc);
if (found && bases) {
bases->tbase = null;
bases->dbase = null;
bases->func = (void *)found->codeStart();
}
return found;
}
void initHook() {
// Note: This hook does not do anything. We need to reference this object file from
// somewhere that is used, otherwise the linker will not include the object file in the
// final build, and therefore our override will not be visible otherwise. Just calling
// the function somewhere is therefore enough to initialize the hook.
}
}
}
#endif
|