[lld] af1328e - [ELF] Simplify EhInputSection::split. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 31 17:00:03 PDT 2022


Author: Fangrui Song
Date: 2022-07-31T16:59:57-07:00
New Revision: af1328ef452b9eaa4e9f0bc115aeda8f40c4bbff

URL: https://github.com/llvm/llvm-project/commit/af1328ef452b9eaa4e9f0bc115aeda8f40c4bbff
DIFF: https://github.com/llvm/llvm-project/commit/af1328ef452b9eaa4e9f0bc115aeda8f40c4bbff.diff

LOG: [ELF] Simplify EhInputSection::split. NFC

* Inline getReloc
* Fold the UINT32_MAX length check into the section size check.
  This transformation is valid because we don't support .eh_frame input sections
  larger than 32-bit (unrealistic even for large code models).

Added: 
    

Modified: 
    lld/ELF/InputSection.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index f473e0ebe2ee..394c512c2abc 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -1260,25 +1260,6 @@ SyntheticSection *EhInputSection::getParent() const {
   return cast_or_null<SyntheticSection>(parent);
 }
 
-// Returns the index of the first relocation that points to a region between
-// Begin and Begin+Size.
-template <class IntTy, class RelTy>
-static unsigned getReloc(IntTy begin, IntTy size, const ArrayRef<RelTy> &rels,
-                         unsigned &relocI) {
-  // Start search from RelocI for fast access. That works because the
-  // relocations are sorted in .eh_frame.
-  for (unsigned n = rels.size(); relocI < n; ++relocI) {
-    const RelTy &rel = rels[relocI];
-    if (rel.r_offset < begin)
-      continue;
-
-    if (rel.r_offset < begin + size)
-      return relocI;
-    return -1;
-  }
-  return -1;
-}
-
 // .eh_frame is a sequence of CIE or FDE records.
 // This function splits an input section into records and returns them.
 template <class ELFT> void EhInputSection::split() {
@@ -1308,20 +1289,25 @@ void EhInputSection::split(ArrayRef<RelTy> rels) {
     if (size == 0) // ZERO terminator
       break;
     uint32_t id = endian::read32<ELFT::TargetEndianness>(d.data() + 4);
-    // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
-    // but we do not support that format yet.
-    if (size == UINT32_MAX) {
-      msg = "CIE/FDE too large";
-      break;
-    }
     size += 4;
-    if (size > d.size()) {
-      msg = "CIE/FDE ends past the end of the section";
+    if (LLVM_UNLIKELY(size > d.size())) {
+      // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
+      // but we do not support that format yet.
+      msg = size == UINT32_MAX + uint64_t(4)
+                ? "CIE/FDE too large"
+                : "CIE/FDE ends past the end of the section";
       break;
     }
 
-    uint64_t off = d.data() - rawData.data();
-    (id == 0 ? cies : fdes).emplace_back(off, this, size, getReloc(off, size, rels, relI));
+    // Find the first relocation that points to [off,off+size). Relocations
+    // have been sorted by r_offset.
+    const uint64_t off = d.data() - rawData.data();
+    while (relI != rels.size() && rels[relI].r_offset < off)
+      ++relI;
+    unsigned firstRel = -1;
+    if (relI != rels.size() && rels[relI].r_offset < off + size)
+      firstRel = relI;
+    (id == 0 ? cies : fdes).emplace_back(off, this, size, firstRel);
     d = d.slice(size);
   }
   if (msg)


        


More information about the llvm-commits mailing list