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); Index: test/ELF/ztext.s =================================================================== --- test/ELF/ztext.s +++ test/ELF/ztext.s @@ -1,7 +1,9 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ztext.s -o %t2.o -# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: ld.lld -z notext %t2.o -o %t2.so -shared + +# RUN: llvm-readobj -dynamic-table %t2.so | FileCheck --check-prefix=UNNECESSARY %s # RUN: ld.lld -z notext %t.o %t2.so -o %t -shared # RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s @@ -16,6 +18,8 @@ # If the preference is to have text relocations, don't create plt of copy relocations. +# UNNECESSARY-NOT: TEXTREL + # CHECK: Relocations [ # CHECK-NEXT: Section {{.*}} .rela.dyn { # CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000