diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-05-04 14:29:05 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-05-04 14:29:05 +0000 |
commit | 772455c964ec51d034ca32bb2718b239c01a05d2 (patch) | |
tree | db26776fea6b771c846220928c74b08f5e9380b9 /libgo | |
parent | 71d372eba9d83660d02d03e9f3d6f2872b8bd972 (diff) | |
download | gcc-772455c964ec51d034ca32bb2718b239c01a05d2.zip gcc-772455c964ec51d034ca32bb2718b239c01a05d2.tar.gz gcc-772455c964ec51d034ca32bb2718b239c01a05d2.tar.bz2 |
libgo: fix for unaligned read in go-unwind.c's read_encoded_value()
Change code to work properly reading unaligned data on architectures
that don't support unaliged reads. This fixes a regression (broke
Solaris/sparc) introduced in https://golang.org/cl/90235.
Reviewed-on: https://go-review.googlesource.com/111296
From-SVN: r259935
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/runtime/go-unwind.c | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index 536a619..a059acb 100644 --- a/libgo/runtime/go-unwind.c +++ b/libgo/runtime/go-unwind.c @@ -197,10 +197,6 @@ read_sleb128 (const uint8_t *p, _sleb128_t *val) #define ROUND_UP_TO_PVB(x) (x + sizeof(void *) - 1) &- sizeof(void *) -#define COPY_AND_ADVANCE(dst, ptr, typ) \ - (dst = *((const typ*)ptr), \ - ptr += sizeof(typ)) - static inline const uint8_t * read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, const uint8_t *p, _Unwind_Ptr *val) @@ -221,17 +217,53 @@ read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, switch (encoding & 0x0f) { case DW_EH_PE_sdata2: + { + int16_t result; + __builtin_memcpy (&result, p, sizeof(int16_t)); + decoded = result; + p += sizeof(int16_t); + break; + } case DW_EH_PE_udata2: - COPY_AND_ADVANCE (decoded, p, uint16_t); - break; + { + uint16_t result; + __builtin_memcpy (&result, p, sizeof(uint16_t)); + decoded = result; + p += sizeof(uint16_t); + break; + } case DW_EH_PE_sdata4: + { + int32_t result; + __builtin_memcpy (&result, p, sizeof(int32_t)); + decoded = result; + p += sizeof(int32_t); + break; + } case DW_EH_PE_udata4: - COPY_AND_ADVANCE (decoded, p, uint32_t); - break; + { + uint32_t result; + __builtin_memcpy (&result, p, sizeof(uint32_t)); + decoded = result; + p += sizeof(uint32_t); + break; + } case DW_EH_PE_sdata8: + { + int64_t result; + __builtin_memcpy (&result, p, sizeof(int64_t)); + decoded = result; + p += sizeof(int64_t); + break; + } case DW_EH_PE_udata8: - COPY_AND_ADVANCE (decoded, p, uint64_t); - break; + { + uint64_t result; + __builtin_memcpy (&result, p, sizeof(uint64_t)); + decoded = result; + p += sizeof(uint64_t); + break; + } case DW_EH_PE_uleb128: { _uleb128_t value; @@ -247,7 +279,7 @@ read_encoded_value (struct _Unwind_Context *context, uint8_t encoding, break; } case DW_EH_PE_absptr: - decoded = (_Unwind_Internal_Ptr)(*(const void *const *)p); + __builtin_memcpy (&decoded, (const void *)p, sizeof(const void*)); p += sizeof(void *); break; default: |