@@ -540,43 +540,6 @@ void EhFrameSection::finalizeContents() {
540540 this ->size = off;
541541}
542542
543- // Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
544- // to get an FDE from an address to which FDE is applied. This function
545- // returns a list of such pairs.
546- SmallVector<EhFrameSection::FdeData, 0 > EhFrameSection::getFdeData () const {
547- uint8_t *buf = ctx.bufferStart + getParent ()->offset + outSecOff;
548- SmallVector<FdeData, 0 > ret;
549-
550- uint64_t va = getPartition (ctx).ehFrameHdr ->getVA ();
551- for (CieRecord *rec : cieRecords) {
552- uint8_t enc = getFdeEncoding (rec->cie );
553- for (EhSectionPiece *fde : rec->fdes ) {
554- uint64_t pc = getFdePc (buf, fde->outputOff , enc);
555- uint64_t fdeVA = getParent ()->addr + fde->outputOff ;
556- if (!isInt<32 >(pc - va)) {
557- Err (ctx) << fde->sec << " : PC offset is too large: 0x"
558- << Twine::utohexstr (pc - va);
559- continue ;
560- }
561- ret.push_back ({uint32_t (pc - va), uint32_t (fdeVA - va)});
562- }
563- }
564-
565- // Sort the FDE list by their PC and uniqueify. Usually there is only
566- // one FDE for a PC (i.e. function), but if ICF merges two functions
567- // into one, there can be more than one FDEs pointing to the address.
568- auto less = [](const FdeData &a, const FdeData &b) {
569- return a.pcRel < b.pcRel ;
570- };
571- llvm::stable_sort (ret, less);
572- auto eq = [](const FdeData &a, const FdeData &b) {
573- return a.pcRel == b.pcRel ;
574- };
575- ret.erase (llvm::unique (ret, eq), ret.end ());
576-
577- return ret;
578- }
579-
580543static uint64_t readFdeAddr (Ctx &ctx, uint8_t *buf, int size) {
581544 switch (size) {
582545 case DW_EH_PE_udata2:
@@ -630,14 +593,79 @@ void EhFrameSection::writeTo(uint8_t *buf) {
630593 }
631594 }
632595
633- // Apply relocations. .eh_frame section contents are not contiguous
634- // in the output buffer, but relocateAlloc() still works because
635- // getOffset() takes care of discontiguous section pieces.
596+ // Apply relocations to .eh_frame entries. This includes CIE personality
597+ // pointers, FDE initial_location fields, and LSDA pointers.
636598 for (EhInputSection *s : sections)
637599 ctx.target ->relocateEh (*s, buf);
638600
639- if (getPartition (ctx).ehFrameHdr && getPartition (ctx).ehFrameHdr ->getParent ())
640- getPartition (ctx).ehFrameHdr ->write ();
601+ EhFrameHeader *hdr = getPartition (ctx).ehFrameHdr .get ();
602+ if (!hdr || !hdr->getParent ())
603+ return ;
604+
605+ // Write the .eh_frame_hdr section, which contains a binary search table of
606+ // pointers to FDEs. This must be written after .eh_frame relocation since
607+ // the content depends on relocated initial_location fields in FDEs.
608+ using FdeData = EhFrameSection::FdeData;
609+ SmallVector<FdeData, 0 > fdes;
610+ uint64_t va = hdr->getVA ();
611+ for (CieRecord *rec : cieRecords) {
612+ uint8_t enc = getFdeEncoding (rec->cie );
613+ for (EhSectionPiece *fde : rec->fdes ) {
614+ uint64_t pc = getFdePc (buf, fde->outputOff , enc);
615+ uint64_t fdeVA = getParent ()->addr + fde->outputOff ;
616+ if (!isInt<32 >(pc - va)) {
617+ Err (ctx) << fde->sec << " : PC offset is too large: 0x"
618+ << Twine::utohexstr (pc - va);
619+ continue ;
620+ }
621+ fdes.push_back ({uint32_t (pc - va), uint32_t (fdeVA - va)});
622+ }
623+ }
624+
625+ // Sort the FDE list by their PC and uniqueify. Usually there is only
626+ // one FDE for a PC (i.e. function), but if ICF merges two functions
627+ // into one, there can be more than one FDEs pointing to the address.
628+ llvm::stable_sort (fdes, [](const FdeData &a, const FdeData &b) {
629+ return a.pcRel < b.pcRel ;
630+ });
631+ fdes.erase (
632+ llvm::unique (fdes, [](auto &a, auto &b) { return a.pcRel == b.pcRel ; }),
633+ fdes.end ());
634+
635+ // Write header.
636+ uint8_t *hdrBuf = ctx.bufferStart + hdr->getParent ()->offset + hdr->outSecOff ;
637+ hdrBuf[0 ] = 1 ; // version
638+ hdrBuf[1 ] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; // eh_frame_ptr_enc
639+ hdrBuf[2 ] = DW_EH_PE_udata4; // fde_count_enc
640+ hdrBuf[3 ] = DW_EH_PE_datarel | DW_EH_PE_sdata4; // table_enc
641+ write32 (ctx, hdrBuf + 4 ,
642+ getParent ()->addr - hdr->getVA () - 4 ); // eh_frame_ptr
643+ write32 (ctx, hdrBuf + 8 , fdes.size ()); // fde_count
644+ hdrBuf += 12 ;
645+
646+ // Write binary search table. Each entry describes the starting PC and the FDE
647+ // address.
648+ for (FdeData &fde : fdes) {
649+ write32 (ctx, hdrBuf, fde.pcRel );
650+ write32 (ctx, hdrBuf + 4 , fde.fdeVARel );
651+ hdrBuf += 8 ;
652+ }
653+ }
654+
655+ EhFrameHeader::EhFrameHeader (Ctx &ctx)
656+ : SyntheticSection(ctx, " .eh_frame_hdr" , SHT_PROGBITS, SHF_ALLOC, 4 ) {}
657+
658+ void EhFrameHeader::writeTo (uint8_t *buf) {
659+ // The section content is written during EhFrameSection::writeTo.
660+ }
661+
662+ size_t EhFrameHeader::getSize () const {
663+ // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
664+ return 12 + getPartition (ctx).ehFrame ->numFdes * 8 ;
665+ }
666+
667+ bool EhFrameHeader::isNeeded () const {
668+ return isLive () && getPartition (ctx).ehFrame ->isNeeded ();
641669}
642670
643671GotSection::GotSection (Ctx &ctx)
@@ -3658,51 +3686,6 @@ void GdbIndexSection::writeTo(uint8_t *buf) {
36583686
36593687bool GdbIndexSection::isNeeded () const { return !chunks.empty (); }
36603688
3661- EhFrameHeader::EhFrameHeader (Ctx &ctx)
3662- : SyntheticSection(ctx, " .eh_frame_hdr" , SHT_PROGBITS, SHF_ALLOC, 4 ) {}
3663-
3664- void EhFrameHeader::writeTo (uint8_t *buf) {
3665- // Unlike most sections, the EhFrameHeader section is written while writing
3666- // another section, namely EhFrameSection, which calls the write() function
3667- // below from its writeTo() function. This is necessary because the contents
3668- // of EhFrameHeader depend on the relocated contents of EhFrameSection and we
3669- // don't know which order the sections will be written in.
3670- }
3671-
3672- // .eh_frame_hdr contains a binary search table of pointers to FDEs.
3673- // Each entry of the search table consists of two values,
3674- // the starting PC from where FDEs covers, and the FDE's address.
3675- // It is sorted by PC.
3676- void EhFrameHeader::write () {
3677- uint8_t *buf = ctx.bufferStart + getParent ()->offset + outSecOff;
3678- using FdeData = EhFrameSection::FdeData;
3679- SmallVector<FdeData, 0 > fdes = getPartition (ctx).ehFrame ->getFdeData ();
3680-
3681- buf[0 ] = 1 ;
3682- buf[1 ] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
3683- buf[2 ] = DW_EH_PE_udata4;
3684- buf[3 ] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
3685- write32 (ctx, buf + 4 ,
3686- getPartition (ctx).ehFrame ->getParent ()->addr - this ->getVA () - 4 );
3687- write32 (ctx, buf + 8 , fdes.size ());
3688- buf += 12 ;
3689-
3690- for (FdeData &fde : fdes) {
3691- write32 (ctx, buf, fde.pcRel );
3692- write32 (ctx, buf + 4 , fde.fdeVARel );
3693- buf += 8 ;
3694- }
3695- }
3696-
3697- size_t EhFrameHeader::getSize () const {
3698- // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
3699- return 12 + getPartition (ctx).ehFrame ->numFdes * 8 ;
3700- }
3701-
3702- bool EhFrameHeader::isNeeded () const {
3703- return isLive () && getPartition (ctx).ehFrame ->isNeeded ();
3704- }
3705-
37063689VersionDefinitionSection::VersionDefinitionSection (Ctx &ctx)
37073690 : SyntheticSection(ctx, " .gnu.version_d" , SHT_GNU_verdef, SHF_ALLOC,
37083691 sizeof (uint32_t )) {}
0 commit comments