From 772455c964ec51d034ca32bb2718b239c01a05d2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 4 May 2018 14:29:05 +0000 Subject: [PATCH] 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 --- gcc/go/gofrontend/MERGE | 2 +- libgo/runtime/go-unwind.c | 54 +++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index d299f23d675..02bf62520cb 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -30e2033a91fc08be9351d26737599a1fa6486017 +0c9b7a1ca4c6308345ea2a276cf820ff52513592 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/runtime/go-unwind.c b/libgo/runtime/go-unwind.c index 536a619d298..a059acbc22a 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: