aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-05-04 14:29:05 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-05-04 14:29:05 +0000
commit772455c964ec51d034ca32bb2718b239c01a05d2 (patch)
treedb26776fea6b771c846220928c74b08f5e9380b9 /libgo
parent71d372eba9d83660d02d03e9f3d6f2872b8bd972 (diff)
downloadgcc-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.c54
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: