Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -248,6 +248,10 @@ // True if we are creating position-independent code. bool Pic; + // True if non-writable segments contain dynamic relocs so that we need to + // emit DF_TEXTREL. + bool NeedTextRel = false; + // 4 for ELF32, 8 for ELF64. int Wordsize; }; Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -788,6 +788,9 @@ } bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText; if (CanWrite) { + if (!(Sec.Flags & SHF_WRITE)) + Config->NeedTextRel = true; + // R_GOT refers to a position in the got, even if the symbol is preemptible. bool IsPreemptibleValue = Sym.IsPreemptible && Expr != R_GOT; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1061,7 +1061,7 @@ DtFlags |= DF_ORIGIN; DtFlags1 |= DF_1_ORIGIN; } - if (!Config->ZText) + if (!Config->ZText && Config->NeedTextRel) DtFlags |= DF_TEXTREL; if (DtFlags) @@ -1125,7 +1125,7 @@ addInt(DT_SYMENT, sizeof(Elf_Sym)); addInSec(DT_STRTAB, InX::DynStrTab); addInt(DT_STRSZ, InX::DynStrTab->getSize()); - if (!Config->ZText) + if (DtFlags & DF_TEXTREL) addInt(DT_TEXTREL, 0); if (InX::GnuHashTab) addInSec(DT_GNU_HASH, InX::GnuHashTab);