diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-01 21:05:05 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-01 21:05:05 +0000 |
commit | 58c3aa204906def9a157ea9a9db091f69af76e4b (patch) | |
tree | f81e0ac003e68c1026a8181bb10df13b2c212c0b /examples | |
parent | de3931241a23ffe9a5e67a0b758c3b32b4b3b5e4 (diff) |
Add support for other typeinfo encodings in the ExceptionDemo.
The old jit always uses DW_EH_PE_absptr, but MCJIT can use other encodings.
This is in preparation for adding EH support to MCJIT, but not directly
related, so I am committing it first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ExceptionDemo/ExceptionDemo.cpp | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index 264ef5481f..0bd49a3732 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -418,6 +418,30 @@ static uintptr_t readSLEB128(const uint8_t **data) { return result; } +unsigned getEncodingSize(uint8_t Encoding) { + if (Encoding == llvm::dwarf::DW_EH_PE_omit) + return 0; + + switch (Encoding & 0x0F) { + case llvm::dwarf::DW_EH_PE_absptr: + return sizeof(uintptr_t); + case llvm::dwarf::DW_EH_PE_udata2: + return sizeof(uint16_t); + case llvm::dwarf::DW_EH_PE_udata4: + return sizeof(uint32_t); + case llvm::dwarf::DW_EH_PE_udata8: + return sizeof(uint64_t); + case llvm::dwarf::DW_EH_PE_sdata2: + return sizeof(int16_t); + case llvm::dwarf::DW_EH_PE_sdata4: + return sizeof(int32_t); + case llvm::dwarf::DW_EH_PE_sdata8: + return sizeof(int64_t); + default: + // not supported + abort(); + } +} /// Read a pointer encoded value and advance pointer /// See Variable Length Data in: @@ -523,7 +547,8 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) { /// @returns whether or not a type info was found. False is returned if only /// a cleanup was found static bool handleActionValue(int64_t *resultAction, - struct OurExceptionType_t **classInfo, + uint8_t TTypeEncoding, + const uint8_t *ClassInfo, uintptr_t actionEntry, uint64_t exceptionClass, struct _Unwind_Exception *exceptionObject) { @@ -572,16 +597,22 @@ static bool handleActionValue(int64_t *resultAction, // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector // argument has been matched. - if ((typeOffset > 0) && - (type == (classInfo[-typeOffset])->type)) { + if (typeOffset > 0) { #ifdef DEBUG fprintf(stderr, "handleActionValue(...):actionValue <%d> found.\n", i); #endif - *resultAction = i + 1; - ret = true; - break; + unsigned EncSize = getEncodingSize(TTypeEncoding); + const uint8_t *EntryP = ClassInfo - typeOffset * EncSize; + uintptr_t P = readEncodedPointer(&EntryP, TTypeEncoding); + struct OurExceptionType_t *ThisClassInfo = + reinterpret_cast<struct OurExceptionType_t *>(P); + if (ThisClassInfo->type == type) { + *resultAction = i + 1; + ret = true; + break; + } } #ifdef DEBUG @@ -633,7 +664,7 @@ static _Unwind_Reason_Code handleLsda(int version, // emitted dwarf code) uintptr_t funcStart = _Unwind_GetRegionStart(context); uintptr_t pcOffset = pc - funcStart; - struct OurExceptionType_t **classInfo = NULL; + const uint8_t *ClassInfo = NULL; // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding // dwarf emission @@ -653,7 +684,7 @@ static _Unwind_Reason_Code handleLsda(int version, // were flagged by type info arguments to llvm.eh.selector // intrinsic classInfoOffset = readULEB128(&lsda); - classInfo = (struct OurExceptionType_t**) (lsda + classInfoOffset); + ClassInfo = lsda + classInfoOffset; } // Walk call-site table looking for range that @@ -714,7 +745,8 @@ static _Unwind_Reason_Code handleLsda(int version, if (actionEntry) { exceptionMatched = handleActionValue(&actionValue, - classInfo, + ttypeEncoding, + ClassInfo, actionEntry, exceptionClass, exceptionObject); |