diff mbox series

libgo patch committed: Fix unaligned read in unwind code

Message ID CAOyqgcXR8L5skTE36UbTZwLiuB=-2YsZkdtw3OsgiWQ45SuZhg@mail.gmail.com
State New
Headers show
Series libgo patch committed: Fix unaligned read in unwind code | expand

Commit Message

Ian Lance Taylor May 4, 2018, 2:29 p.m. UTC
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
diff mbox series

Patch

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: