This patch by Than McIntosh fixes some unaligned reads in the Go unwinding code. Bootstrapped and ran a few Go tests on sparc-solaris11. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 259920) +++ gcc/go/gofrontend/MERGE (working copy) @@ -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. Index: libgo/runtime/go-unwind.c =================================================================== --- libgo/runtime/go-unwind.c (revision 259861) +++ libgo/runtime/go-unwind.c (working copy) @@ -197,10 +197,6 @@ read_sleb128 (const uint8_t *p, _sleb128 #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_Conte 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_Conte 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: