Commit 84bbfdce authored by Tom Stellard's avatar Tom Stellard
Browse files

Merging r231839:

------------------------------------------------------------------------
r231839 | ericwf | 2015-03-10 13:43:34 -0700 (Tue, 10 Mar 2015) | 11 lines

[libcxx] Fix PR21580 - Undefined behavior in readEncodedPointer()

Summary: This patch fixes a bug in `readEncodedPointer()` where it would read from memory that was not suitably aligned. This patch fixes it by using memcpy.

Reviewers: danalbert, echristo, compnerd, mclow.lists

Reviewed By: compnerd, mclow.lists

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D8179
------------------------------------------------------------------------

llvm-svn: 236860
parent 1c30c229
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <typeinfo>

#include "config.h"
@@ -141,6 +142,19 @@ Notes:
namespace __cxxabiv1
{

namespace
{

template <class AsType>
uintptr_t readPointerHelper(const uint8_t*& p) {
    AsType value;
    memcpy(&value, const_cast<uint8_t*>(p), sizeof(AsType));
    p += sizeof(AsType);
    return static_cast<uintptr_t>(value);
}

} // end namespace

extern "C"
{

@@ -245,28 +259,22 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding)
        result = static_cast<uintptr_t>(readSLEB128(&p));
        break;
    case DW_EH_PE_udata2:
        result = *((uint16_t*)p);
        p += sizeof(uint16_t);
        result = readPointerHelper<uint16_t>(p);
        break;
    case DW_EH_PE_udata4:
        result = *((uint32_t*)p);
        p += sizeof(uint32_t);
        result = readPointerHelper<uint32_t>(p);
        break;
    case DW_EH_PE_udata8:
        result = static_cast<uintptr_t>(*((uint64_t*)p));
        p += sizeof(uint64_t);
        result = readPointerHelper<uint64_t>(p);
        break;
    case DW_EH_PE_sdata2:
        result = static_cast<uintptr_t>(*((int16_t*)p));
        p += sizeof(int16_t);
        result = readPointerHelper<int16_t>(p);
        break;
    case DW_EH_PE_sdata4:
        result = static_cast<uintptr_t>(*((int32_t*)p));
        p += sizeof(int32_t);
        result = readPointerHelper<int32_t>(p);
        break;
    case DW_EH_PE_sdata8:
        result = static_cast<uintptr_t>(*((int64_t*)p));
        p += sizeof(int64_t);
        result = readPointerHelper<int64_t>(p);
        break;
    default:
        // not supported