Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -681,8 +681,9 @@ RF_NOT_INTERP = 1 << 17, RF_NOT_ALLOC = 1 << 16, RF_WRITE = 1 << 15, - RF_EXEC_WRITE = 1 << 13, - RF_EXEC = 1 << 12, + RF_EXEC_WRITE = 1 << 14, + RF_EXEC = 1 << 13, + RF_PROGBITS = 1 << 12, RF_NON_TLS_BSS = 1 << 11, RF_NON_TLS_BSS_RO = 1 << 10, RF_NOT_TLS = 1 << 9, @@ -717,6 +718,12 @@ if (!(Sec->Flags & SHF_ALLOC)) return Rank | RF_NOT_ALLOC; + // Place sections with PROGBITS closer. We want to put progbits + // sections closer as an effort to prevent relocation overflow + // between these sections. + if (Sec->Type == SHT_PROGBITS && !isRelroSection(Sec)) + Rank |= RF_PROGBITS; + // Sort sections based on their access permission in the following // order: R, RX, RWX, RW. This order is based on the following // considerations: @@ -1674,17 +1681,20 @@ // The linker is expected to define SECNAME_start and SECNAME_end // symbols for a few sections. This function defines them. template void Writer::addStartEndSymbols() { + // These symbols resolve to the image base or ".text" if the section + // does not exist. Set symbol value to ".text" mitigates the possibilities + // that an relocation from .text section to these symbols overflows. + // A special value -1 indicates end of the section. + OutputSection *DefaultOutSec = findSection(".text"); + if (!DefaultOutSec && Config->Pic) + DefaultOutSec = Out::ElfHeader; auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) { - // These symbols resolve to the image base if the section does not exist. - // A special value -1 indicates end of the section. if (OS) { addOptionalRegular(Start, OS, 0); addOptionalRegular(End, OS, -1); } else { - if (Config->Pic) - OS = Out::ElfHeader; - addOptionalRegular(Start, OS, 0); - addOptionalRegular(End, OS, 0); + addOptionalRegular(Start, DefaultOutSec, 0); + addOptionalRegular(End, DefaultOutSec, 0); } };