Fix a wrong assumption.

llvm-svn: 270573
This commit is contained in:
Rafael Espindola 2016-05-24 16:03:27 +00:00
parent 19ccffe4bc
commit 1f5696f9c1
2 changed files with 34 additions and 19 deletions

View File

@ -964,14 +964,6 @@ CieRecord *EhOutputSection<ELFT>::addCie(SectionPiece &Piece,
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;
const endianness E = ELFT::TargetEndianness;
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))
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;
Cie->FdePieces.push_back(&FdePiece);
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(&Piece);
NumFdes++;
}
}

View File

@ -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: