[lld] r282180 - Don't move orphan sections past assignments.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 22 11:05:49 PDT 2016
Author: rafael
Date: Thu Sep 22 13:05:49 2016
New Revision: 282180
URL: http://llvm.org/viewvc/llvm-project?rev=282180&view=rev
Log:
Don't move orphan sections past assignments.
This fixes a case where we would produce an unaligned PT_LOAD.
Added:
lld/trunk/test/ELF/linkerscript/orphan-align.s
Modified:
lld/trunk/ELF/LinkerScript.cpp
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=282180&r1=282179&r2=282180&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Sep 22 13:05:49 2016
@@ -514,6 +514,29 @@ template <class ELFT> void LinkerScript<
}
}
+// When placing orphan sections, we want to place them after symbol assignments
+// so that an orphan after
+// begin_foo = .;
+// foo : { *(foo) }
+// end_foo = .;
+// doesn't break the intended meaning of the begin/end symbols.
+// We don't want to go over sections since Writer<ELFT>::sortSections is the
+// one in charge of deciding the order of the sections.
+// We don't want to go over alignments, since doing so in
+// rx_sec : { *(rx_sec) }
+// . = ALIGN(0x1000);
+// /* The RW PT_LOAD starts here*/
+// rw_sec : { *(rw_sec) }
+// would mean that the RW PT_LOAD would become unaligned.
+static bool shouldSkip(const BaseCommand &Cmd) {
+ if (isa<OutputSectionCommand>(Cmd))
+ return false;
+ const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd);
+ if (!Assign)
+ return true;
+ return Assign->Name != ".";
+}
+
template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
// Orphan sections are sections present in the input files which
// are not explicitly placed into the output file by the linker script.
@@ -529,10 +552,10 @@ template <class ELFT> void LinkerScript<
StringRef Name = Sec->getName();
// Find the last spot where we can insert a command and still get the
- // correct order.
+ // correct result.
auto CmdIter = Opt.Commands.begin() + CmdIndex;
auto E = Opt.Commands.end();
- while (CmdIter != E && !isa<OutputSectionCommand>(**CmdIter)) {
+ while (CmdIter != E && shouldSkip(**CmdIter)) {
++CmdIter;
++CmdIndex;
}
@@ -545,10 +568,13 @@ template <class ELFT> void LinkerScript<
if (Pos == E) {
Opt.Commands.insert(CmdIter,
llvm::make_unique<OutputSectionCommand>(Name));
- } else {
- assert(Pos == CmdIter && "Section order doesn't match the linker script");
+ ++CmdIndex;
+ continue;
}
- ++CmdIndex;
+
+ // Continue from where we found it.
+ CmdIndex = (Pos - Opt.Commands.begin()) + 1;
+ continue;
}
// Assign addresses as instructed by linker script SECTIONS sub-commands.
Added: lld/trunk/test/ELF/linkerscript/orphan-align.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/orphan-align.s?rev=282180&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/orphan-align.s (added)
+++ lld/trunk/test/ELF/linkerscript/orphan-align.s Thu Sep 22 13:05:49 2016
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN: .text : { *(.text) } \
+# RUN: . = ALIGN(0x1000); \
+# RUN: .data.rel.ro : { *(.data.rel.ro) } \
+# RUN: }" \ > %t.script
+# RUN: ld.lld -o %t -T %t.script %t.o -shared
+# RUN: llvm-readobj -l %t | FileCheck %s
+
+
+# Test that the orphan section foo is placed before the ALIGN and so the second
+# PT_LOAD is aligned.
+
+
+# CHECK: Type: PT_LOAD
+# CHECK-NEXT: Offset: 0x0
+
+# CHECK: Type: PT_LOAD
+# CHECK-NEXT: Offset: 0x1000
+
+nop
+.section .data.rel.ro, "aw"
+.byte 0
+
+.section foo, "ax"
+nop
More information about the llvm-commits
mailing list