Index: contrib/libcxxrt/dwarf_eh.h =================================================================== --- contrib/libcxxrt/dwarf_eh.h +++ contrib/libcxxrt/dwarf_eh.h @@ -144,6 +144,96 @@ } } +/** + * Attempt to correctly read 16 bit, 32 bit, 64 bit and pointer values from + * possibly unaligned data pointers. + */ + +static inline uint16_t read_uint16(dw_eh_ptr_t *data) +{ + uint16_t res = +#if defined(__NO_STRICT_ALIGNMENT) + reinterpret_cast(*data)[0]; +#elif defined(__LITTLE_ENDIAN__) + static_cast((*data)[0]) << 0 | + static_cast((*data)[1]) << 8; +#else + static_cast((*data)[0]) << 8 | + static_cast((*data)[1]) << 0; +#endif + *data += sizeof(uint16_t); + return res; +} + +static inline int16_t read_int16(dw_eh_ptr_t *data) +{ + return static_cast(read_uint16(data)); +} + +static uint32_t read_uint32(dw_eh_ptr_t *data) +{ + uint32_t res = +#if defined(__NO_STRICT_ALIGNMENT) + reinterpret_cast(*data)[0]; +#elif defined(__LITTLE_ENDIAN__) + static_cast((*data)[0]) << 0 | + static_cast((*data)[1]) << 8 | + static_cast((*data)[2]) << 16 | + static_cast((*data)[3]) << 24; +#else + static_cast((*data)[0]) << 24 | + static_cast((*data)[1]) << 16 | + static_cast((*data)[2]) << 8 | + static_cast((*data)[3]) << 0; +#endif + *data += sizeof(uint32_t); + return res; +} + +static int32_t read_int32(dw_eh_ptr_t *data) +{ + return static_cast(read_uint32(data)); +} + +static uint64_t read_uint64(dw_eh_ptr_t *data) +{ + uint64_t res = +#if defined(__NO_STRICT_ALIGNMENT) + reinterpret_cast(*data)[0]; +#elif defined(__LITTLE_ENDIAN__) + static_cast((*data)[0]) << 0 | + static_cast((*data)[1]) << 8 | + static_cast((*data)[2]) << 16 | + static_cast((*data)[3]) << 24 | + static_cast((*data)[4]) << 32 | + static_cast((*data)[5]) << 40 | + static_cast((*data)[6]) << 48 | + static_cast((*data)[7]) << 56; +#else + static_cast((*data)[0]) << 56 | + static_cast((*data)[1]) << 48 | + static_cast((*data)[2]) << 40 | + static_cast((*data)[3]) << 32 | + static_cast((*data)[4]) << 24 | + static_cast((*data)[5]) << 16 | + static_cast((*data)[6]) << 8 | + static_cast((*data)[7]) << 0; +#endif + *data += sizeof(uint64_t); + return res; +} + +static int64_t read_int64(dw_eh_ptr_t *data) +{ + return static_cast(read_uint64(data)); +} + +#if defined(__LP64__) +#define read_ptr read_uint64 +#else +#define read_ptr read_uint32 +#endif + /** * Read an unsigned, little-endian, base-128, DWARF value. Updates *data to * point to the end of the value. Stores the number of bits read in the value @@ -222,19 +312,25 @@ switch (type) { // Read fixed-length types -#define READ(dwarf, type) \ - case dwarf:\ - v = static_cast(*reinterpret_cast(*data));\ - *data += sizeof(type);\ - break; - READ(DW_EH_PE_udata2, uint16_t) - READ(DW_EH_PE_udata4, uint32_t) - READ(DW_EH_PE_udata8, uint64_t) - READ(DW_EH_PE_sdata2, int16_t) - READ(DW_EH_PE_sdata4, int32_t) - READ(DW_EH_PE_sdata8, int64_t) - READ(DW_EH_PE_absptr, intptr_t) -#undef READ + case DW_EH_PE_udata2: + v = read_uint16(data); + break; + case DW_EH_PE_udata4: + v = read_uint32(data); + break; + case DW_EH_PE_udata8: + v = read_uint64(data); + break; + case DW_EH_PE_sdata2: + v = read_int16(data); + break; + case DW_EH_PE_sdata4: + v = read_int32(data); + case DW_EH_PE_sdata8: + v = read_int64(data); + case DW_EH_PE_absptr: + v = read_ptr(data); + break; // Read variable-length types case DW_EH_PE_sleb128: v = read_sleb128(data);