[lld] r270573 - Fix a wrong assumption.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue May 24 09:03:28 PDT 2016


Author: rafael
Date: Tue May 24 11:03:27 2016
New Revision: 270573

URL: http://llvm.org/viewvc/llvm-project?rev=270573&view=rev
Log:
Fix a wrong assumption.

Added:
    lld/trunk/test/ELF/eh-frame-multilpe-cie.s
Modified:
    lld/trunk/ELF/OutputSections.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=270573&r1=270572&r2=270573&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue May 24 11:03:27 2016
@@ -964,14 +964,6 @@ CieRecord *EhOutputSection<ELFT>::addCie
   return Cie;
 }
 
-template <class ELFT> static void validateFde(SectionPiece &Piece) {
-  // We assume that all FDEs refer the first CIE in the same object file.
-  const endianness E = ELFT::TargetEndianness;
-  uint32_t ID = read32<E>(Piece.Data.data() + 4);
-  if (Piece.InputOff + 4 - ID != 0)
-    fatal("invalid CIE reference");
-}
-
 // There is one FDE per function. Returns true if a given FDE
 // points to a live function.
 template <class ELFT>
@@ -998,19 +990,30 @@ template <class ELFT>
 template <class RelTy>
 void EhOutputSection<ELFT>::addSectionAux(EhInputSection<ELFT> *Sec,
                                           ArrayRef<RelTy> Rels) {
-  SectionPiece &CiePiece = Sec->Pieces[0];
-  // The empty record is the end marker.
-  if (CiePiece.Data.size() == 4)
-    return;
-
-  CieRecord *Cie = addCie(CiePiece, Sec, Rels);
-
-  for (size_t I = 1, End = Sec->Pieces.size(); I != End; ++I) {
-    SectionPiece &FdePiece = Sec->Pieces[I];
-    validateFde<ELFT>(FdePiece);
-    if (!isFdeLive(FdePiece, Sec, Rels))
+  const endianness E = ELFT::TargetEndianness;
+
+  DenseMap<size_t, CieRecord *> OffsetToCie;
+  for (size_t I = 0, End = Sec->Pieces.size(); I != End; ++I) {
+    SectionPiece &Piece = Sec->Pieces[I];
+    // The empty record is the end marker.
+    if (Piece.Data.size() == 4)
+      continue;
+
+    size_t Offset = Piece.InputOff;
+    uint32_t ID = read32<E>(Piece.Data.data() + 4);
+    if (ID == 0) {
+      OffsetToCie[Offset] = addCie(Piece, Sec, Rels);
+      continue;
+    }
+
+    uint32_t CieOffset = Offset + 4 - ID;
+    CieRecord *Cie = OffsetToCie[CieOffset];
+    if (!Cie)
+      fatal("invalid CIE reference");
+
+    if (!isFdeLive(Piece, Sec, Rels))
       continue;
-    Cie->FdePieces.push_back(&FdePiece);
+    Cie->FdePieces.push_back(&Piece);
     NumFdes++;
   }
 }

Added: lld/trunk/test/ELF/eh-frame-multilpe-cie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/eh-frame-multilpe-cie.s?rev=270573&view=auto
==============================================================================
--- lld/trunk/test/ELF/eh-frame-multilpe-cie.s (added)
+++ lld/trunk/test/ELF/eh-frame-multilpe-cie.s Tue May 24 11:03:27 2016
@@ -0,0 +1,12 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
+// We would fail to parse multiple cies in the same file.
+
+        .cfi_startproc
+        .cfi_personality 0x9b, foo
+        .cfi_endproc
+
+        .cfi_startproc
+        .cfi_endproc
+
+foo:




More information about the llvm-commits mailing list