[libcxx-commits] [PATCH] D79852: [libunwind] Fix wrong endianness check in Unwind-EHABI

Idan Freiberg via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed May 13 05:21:47 PDT 2020


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)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79852.263674.patch
Type: text/x-patch
Size: 1157 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200513/f3213cf1/attachment-0001.bin>


More information about the libcxx-commits mailing list