From: Saleem Abdulrasool Date: Sun, 20 Nov 2016 02:36:38 +0000 (+0000) Subject: ExceptionDemo: remove some undefined behaviour X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=802a1be56a3f4a0de31ed222141dc5b4c3020e2a;p=llvm ExceptionDemo: remove some undefined behaviour The casting based reading of the LSDA could attempt to read unsuitably aligned data. Avoid that case by explicitly using a memcpy. A similar approach is used in libc++abi to address the same UB. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287479 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index 1b2f3450530..a8b82e1da77 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -219,6 +219,16 @@ static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function &function, // Runtime C Library functions // +namespace { +template +uintptr_t ReadType(const uint8_t *&p) { + Type_ value; + memcpy(&value, p, sizeof(Type_)); + p += sizeof(Type_); + return static_cast(value); +} +} + // Note: using an extern "C" block so that static functions can be used extern "C" { @@ -409,8 +419,7 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) { // first get value switch (encoding & 0x0F) { case llvm::dwarf::DW_EH_PE_absptr: - result = *((uintptr_t*)p); - p += sizeof(uintptr_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_uleb128: result = readULEB128(&p); @@ -420,28 +429,22 @@ static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) { result = readSLEB128(&p); break; case llvm::dwarf::DW_EH_PE_udata2: - result = *((uint16_t*)p); - p += sizeof(uint16_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_udata4: - result = *((uint32_t*)p); - p += sizeof(uint32_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_udata8: - result = *((uint64_t*)p); - p += sizeof(uint64_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_sdata2: - result = *((int16_t*)p); - p += sizeof(int16_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_sdata4: - result = *((int32_t*)p); - p += sizeof(int32_t); + result = ReadType(p); break; case llvm::dwarf::DW_EH_PE_sdata8: - result = *((int64_t*)p); - p += sizeof(int64_t); + result = ReadType(p); break; default: // not supported