speidy created this revision.
speidy added a reviewer: miyuki.
speidy added a project: libunwind.
Herald added subscribers: libcxx-commits, llvm-commits, kristof.beyls.
Herald added a project: LLVM.
Herald added a reviewer: libunwind.
speidy edited the summary of this revision.
speidy edited the summary of this revision.
speidy edited the summary of this revision.

The ARM specific code was trying to determine endianness using the
`__LITTLE_ENDIAN__` macro which is not guaranteed to be defined.
When not defined, it makes libunwind to build the big-endian code even
when the compiler builds for a little-endian target.

This issue leads libunwind to crash with SIGSEGV during stack unwinding when
it built for ARM by using musl-gcc toolchain (from http://musl.cc) and breaks 
exception
handling.

Switched into a more hermetic check which should also raise a
compile-time error in case endianness could not be determined.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79852

Files:
  libunwind/src/Unwind-EHABI.cpp


Index: libunwind/src/Unwind-EHABI.cpp
===================================================================
--- libunwind/src/Unwind-EHABI.cpp
+++ libunwind/src/Unwind-EHABI.cpp
@@ -31,10 +31,12 @@
 // signinficant byte.
 uint8_t getByte(const uint32_t* data, size_t offset) {
   const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data);
-#ifdef __LITTLE_ENDIAN__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
   return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))];
-#else
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   return byteData[offset];
+#else
+#error "Unable to determine endianess"
 #endif
 }
 
@@ -943,10 +945,12 @@
         // SP is only 32-bit aligned so don't copy 64-bit at a time.
         uint64_t w0 = *sp++;
         uint64_t w1 = *sp++;
-#ifdef __LITTLE_ENDIAN__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
         uint64_t value = (w1 << 32) | w0;
-#else
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
         uint64_t value = (w0 << 32) | w1;
+#else
+#error "Unable to determine endianess"
 #endif
         if (_Unwind_VRS_Set(context, regclass, i, representation, &value) !=
             _UVRSR_OK)


Index: libunwind/src/Unwind-EHABI.cpp
===================================================================
--- libunwind/src/Unwind-EHABI.cpp
+++ libunwind/src/Unwind-EHABI.cpp
@@ -31,10 +31,12 @@
 // signinficant byte.
 uint8_t getByte(const uint32_t* data, size_t offset) {
   const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data);
-#ifdef __LITTLE_ENDIAN__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
   return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))];
-#else
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
   return byteData[offset];
+#else
+#error "Unable to determine endianess"
 #endif
 }
 
@@ -943,10 +945,12 @@
         // SP is only 32-bit aligned so don't copy 64-bit at a time.
         uint64_t w0 = *sp++;
         uint64_t w1 = *sp++;
-#ifdef __LITTLE_ENDIAN__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
         uint64_t value = (w1 << 32) | w0;
-#else
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
         uint64_t value = (w0 << 32) | w1;
+#else
+#error "Unable to determine endianess"
 #endif
         if (_Unwind_VRS_Set(context, regclass, i, representation, &value) !=
             _UVRSR_OK)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to