[PATCH] D35265: [libunwind] Handle .ARM.exidx tables without sentinel last entry

Momchil Velikov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 11 09:29:24 PDT 2017


chill created this revision.
Herald added subscribers: kristof.beyls, aemerson.

`UnwindCursor<A, R>::getInfoFromEHABISection` assumes the last
entry in the index table never corresponds to a real function.
Indeed, GNU ld always inserts an `EXIDX_CANTUNWIND` entry,
containing the end of the .text section. However, the EHABI specification
(http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf)
does not seem to contain text that requires the presence of a sentinel entry.
In that sense the libunwind implementation isn't compliant with the specification.

This patch makes `getInfoFromEHABISection` examine the last entry in the index
table if `upper_bound` returns the end iterator.


https://reviews.llvm.org/D35265

Files:
  src/UnwindCursor.hpp


Index: src/UnwindCursor.hpp
===================================================================
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -696,6 +696,11 @@
     return _Self(addressSpace, sects,
                  sects.arm_section_length / sizeof(EHABIIndexEntry));
   }
+  static _Self last(A& addressSpace, const UnwindInfoSections& sects) {
+    assert(sects.arm_section_length > 0);
+    return _Self(addressSpace, sects,
+                 sects.arm_section_length / sizeof(EHABIIndexEntry) - 1);
+  }
 
   EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i)
       : _i(i), _addressSpace(&addressSpace), _sects(&sects) {}
@@ -746,13 +751,24 @@
       EHABISectionIterator<A>::end(_addressSpace, sects);
 
   EHABISectionIterator<A> itNextPC = std::upper_bound(begin, end, pc);
-  if (itNextPC == begin || itNextPC == end)
+  if (itNextPC == begin || begin == end)
     return false;
-  EHABISectionIterator<A> itThisPC = itNextPC - 1;
 
-  pint_t thisPC = itThisPC.functionAddress();
-  pint_t nextPC = itNextPC.functionAddress();
-  pint_t indexDataAddr = itThisPC.dataAddress();
+  pint_t thisPC, nextPC, indexDataAddr;
+  if (itNextPC == end) {
+    EHABISectionIterator<A> last =
+        EHABISectionIterator<A>::last(_addressSpace, sects);
+    thisPC = last.functionAddress();
+    if (pc < thisPC)
+      return false;
+    nextPC = ~static_cast<pint_t>(0);
+    indexDataAddr = last.dataAddress();
+  } else {
+    EHABISectionIterator<A> itThisPC = itNextPC - 1;
+    thisPC = itThisPC.functionAddress();
+    nextPC = itNextPC.functionAddress();
+    indexDataAddr = itThisPC.dataAddress();
+  }
 
   if (indexDataAddr == 0)
     return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35265.106043.patch
Type: text/x-patch
Size: 1700 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170711/05647b08/attachment.bin>


More information about the llvm-commits mailing list