[lld] r282750 - Don't error if we can't put the header in a PT_LOAD.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 29 11:50:35 PDT 2016
Author: rafael
Date: Thu Sep 29 13:50:34 2016
New Revision: 282750
URL: http://llvm.org/viewvc/llvm-project?rev=282750&view=rev
Log:
Don't error if we can't put the header in a PT_LOAD.
If there is not sufficient address space, just give up and don't put
the header in the PT_LOAD.
This matches bfd behaviour and I found at least one script that
depends on having a section at address 0.
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/linkerscript/no-space.s
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=282750&r1=282749&r2=282750&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Sep 29 13:50:34 2016
@@ -553,7 +553,8 @@ static bool shouldSkip(const BaseCommand
return Assign->Name != ".";
}
-template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
+template <class ELFT>
+void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) {
// Orphan sections are sections present in the input files which
// are not explicitly placed into the output file by the linker script.
// We place orphan sections at end of file.
@@ -628,14 +629,20 @@ template <class ELFT> void LinkerScript<
}
uintX_t HeaderSize = getHeaderSize();
- if (HeaderSize > MinVA)
- fatal("Not enough space for ELF and program headers");
-
- // ELF and Program headers need to be right before the first section in
- // memory. Set their addresses accordingly.
- MinVA = alignDown(MinVA - HeaderSize, Target->PageSize);
- Out<ELFT>::ElfHeader->setVA(MinVA);
- Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
+ auto FirstPTLoad =
+ std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry<ELFT> &E) {
+ return E.H.p_type == PT_LOAD;
+ });
+ if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) {
+ // ELF and Program headers need to be right before the first section in
+ // memory. Set their addresses accordingly.
+ MinVA = alignDown(MinVA - HeaderSize, Target->PageSize);
+ Out<ELFT>::ElfHeader->setVA(MinVA);
+ Out<ELFT>::ProgramHeaders->setVA(Out<ELFT>::ElfHeader->getSize() + MinVA);
+ FirstPTLoad->First = Out<ELFT>::ElfHeader;
+ if (!FirstPTLoad->Last)
+ FirstPTLoad->Last = Out<ELFT>::ProgramHeaders;
+ }
}
// Creates program headers as instructed by PHDRS linker script command.
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=282750&r1=282749&r2=282750&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Thu Sep 29 13:50:34 2016
@@ -208,7 +208,7 @@ public:
Expr getLma(StringRef Name);
bool shouldKeep(InputSectionBase<ELFT> *S);
void assignOffsets(OutputSectionCommand *Cmd);
- void assignAddresses();
+ void assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs);
bool hasPhdrsCommands();
uint64_t getOutputSectionAddress(StringRef Name) override;
uint64_t getOutputSectionSize(StringRef Name) override;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=282750&r1=282749&r2=282750&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Sep 29 13:50:34 2016
@@ -275,7 +275,7 @@ template <class ELFT> void Writer<ELFT>:
: createPhdrs();
fixHeaders();
if (ScriptConfig->HasSections) {
- Script<ELFT>::X->assignAddresses();
+ Script<ELFT>::X->assignAddresses(Phdrs);
} else {
fixSectionAlignments();
assignAddresses();
@@ -1047,8 +1047,10 @@ std::vector<PhdrEntry<ELFT>> Writer<ELFT
// Add the first PT_LOAD segment for regular output sections.
uintX_t Flags = computeFlags<ELFT>(PF_R);
Phdr *Load = AddHdr(PT_LOAD, Flags);
- Load->add(Out<ELFT>::ElfHeader);
- Load->add(Out<ELFT>::ProgramHeaders);
+ if (!ScriptConfig->HasSections) {
+ Load->add(Out<ELFT>::ElfHeader);
+ Load->add(Out<ELFT>::ProgramHeaders);
+ }
Phdr TlsHdr(PT_TLS, PF_R);
Phdr RelRo(PT_GNU_RELRO, PF_R);
Modified: lld/trunk/test/ELF/linkerscript/no-space.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/no-space.s?rev=282750&r1=282749&r2=282750&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/no-space.s (original)
+++ lld/trunk/test/ELF/linkerscript/no-space.s Thu Sep 29 13:50:34 2016
@@ -2,9 +2,21 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script
-# RUN: not ld.lld -o %t --script %t.script %t.o -shared 2>&1 | FileCheck %s
+# RUN: ld.lld -o %t --script %t.script %t.o -shared
+# RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s
-# CHECK: Not enough space for ELF and program headers
+# There is not enough address space available for the header, so just start the PT_LOAD
+# after it.
+
+# CHECK: Program Headers:
+# CHECK-NEXT: Type Offset VirtAddr PhysAddr
+# CHECK-NEXT: PHDR
+# CHECK-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000
+
+# CHECK: Section to Segment mapping:
+# CHECK-NEXT: Segment Sections...
+# CHECK-NEXT: 00
+# CHECK-NEXT: 01 foo .dynsym .hash .dynstr
.section foo, "a"
.quad 0
More information about the llvm-commits
mailing list