Disable --rosegment when we have linker scripts.
Linker scripts are responsible for aliging '.'. Since they are
designed for bfd which has no --rosegment, they don't align the RO to
RX transition.
llvm-svn: 281978
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c66126d..629d0e3 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -944,6 +944,17 @@
return true;
}
+// Linker scripts are responsible for aligning addresses. Unfortunately, most
+// linker scripts are designed for creating two PT_LOADs only, one RX and one
+// RW. This means that there is no alignment in the RO to RX transition and we
+// cannot create a PT_LOAD there.
+template <class ELFT>
+static typename ELFT::uint computeFlags(typename ELFT::uint F) {
+ if (ScriptConfig->HasSections && !(F & PF_W))
+ return F | PF_X;
+ return F;
+}
+
// Decide which program headers to create and which sections to include in each
// one.
template <class ELFT>
@@ -966,7 +977,7 @@
}
// Add the first PT_LOAD segment for regular output sections.
- uintX_t Flags = PF_R;
+ uintX_t Flags = computeFlags<ELFT>(PF_R);
Phdr *Load = AddHdr(PT_LOAD, Flags);
Load->add(Out<ELFT>::ElfHeader);
Load->add(Out<ELFT>::ProgramHeaders);
@@ -992,7 +1003,7 @@
// Therefore, we need to create a new phdr when the next section has
// different flags or is loaded at a discontiguous address using AT linker
// script command.
- uintX_t NewFlags = Sec->getPhdrFlags();
+ uintX_t NewFlags = computeFlags<ELFT>(Sec->getPhdrFlags());
if (Script<ELFT>::X->getLma(Sec->getName()) || Flags != NewFlags) {
Load = AddHdr(PT_LOAD, NewFlags);
Flags = NewFlags;