aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-30 17:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-30 17:38:04 +0000
commitcbb560c9ba3c378189c7a438bed9977b482410fb (patch)
tree8ed3968b9cb86039eb38b3b8d66fd7c17a5aed0f
parentbef2946c219dc621608bcc9e47f8b973e5ef5c70 (diff)
downloadsrc-cbb560c9ba3c378189c7a438bed9977b482410fb.tar.gz
src-cbb560c9ba3c378189c7a438bed9977b482410fb.zip
Vendor import of lld trunk r304222:vendor/lld/lld-trunk-r304222
Notes
Notes: svn path=/vendor/lld/dist/; revision=319238 svn path=/vendor/lld/lld-trunk-r304222/; revision=319239; tag=vendor/lld/lld-trunk-r304222
-rw-r--r--ELF/LinkerScript.cpp13
-rw-r--r--ELF/LinkerScript.h5
-rw-r--r--ELF/MapFile.cpp15
-rw-r--r--ELF/MapFile.h5
-rw-r--r--ELF/OutputSections.cpp2
-rw-r--r--ELF/ScriptParser.cpp6
-rw-r--r--ELF/Writer.cpp53
-rw-r--r--test/ELF/linkerscript/align.s2
-rw-r--r--test/ELF/linkerscript/bss-fill.s7
-rw-r--r--test/ELF/linkerscript/merge-sections.s10
-rw-r--r--test/ELF/linkerscript/symbol-reserved.s6
11 files changed, 83 insertions, 41 deletions
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index 492b81c1fa76..99c464e3714c 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -52,11 +52,12 @@ LinkerScript *elf::Script;
uint64_t ExprValue::getValue() const {
if (Sec) {
if (Sec->getOutputSection())
- return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;
+ return alignTo(Sec->getOffset(Val) + Sec->getOutputSection()->Addr,
+ Alignment);
error("unable to evaluate expression: input section " + Sec->Name +
" has no output section assigned");
}
- return Val;
+ return alignTo(Val, Alignment);
}
uint64_t ExprValue::getSecAddr() const {
@@ -143,7 +144,7 @@ void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
} else {
Sym->Section = V.Sec;
if (Sym->Section->Flags & SHF_ALLOC)
- Sym->Value = V.Val;
+ Sym->Value = alignTo(V.Val, V.Alignment);
else
Sym->Value = V.getValue();
}
@@ -290,6 +291,9 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
size_t SizeBefore = Ret.size();
for (InputSectionBase *Sec : InputSections) {
+ if (!isa<InputSection>(Sec))
+ continue;
+
if (Sec->Assigned)
continue;
@@ -1076,6 +1080,9 @@ template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
return;
}
+ if (Sec->Type == SHT_NOBITS)
+ return;
+
// Write leading padding.
ArrayRef<InputSection *> Sections = Sec->Sections;
uint32_t Filler = getFiller();
diff --git a/ELF/LinkerScript.h b/ELF/LinkerScript.h
index e56e569d4e72..08f60f4517a7 100644
--- a/ELF/LinkerScript.h
+++ b/ELF/LinkerScript.h
@@ -41,7 +41,12 @@ struct ExprValue {
SectionBase *Sec;
uint64_t Val;
bool ForceAbsolute;
+ uint64_t Alignment = 1;
+ ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
+ uint64_t Alignment)
+ : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) {
+ }
ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
: Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index 806e99e3d9dd..e0c7d8cd8b1b 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -100,7 +100,7 @@ getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
}
template <class ELFT>
-void elf::writeMapFile(llvm::ArrayRef<BaseCommand *> Script) {
+void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) {
if (Config->MapFile.empty())
return;
@@ -123,10 +123,7 @@ void elf::writeMapFile(llvm::ArrayRef<BaseCommand *> Script) {
<< " Align Out In Symbol\n";
// Print out file contents.
- for (BaseCommand *Base : Script) {
- auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
- if (!Cmd)
- continue;
+ for (OutputSectionCommand *Cmd : Script) {
OutputSection *OSec = Cmd->Sec;
writeHeader<ELFT>(OS, OSec->Addr, OSec->Size, OSec->Alignment);
OS << OSec->Name << '\n';
@@ -147,7 +144,7 @@ void elf::writeMapFile(llvm::ArrayRef<BaseCommand *> Script) {
}
}
-template void elf::writeMapFile<ELF32LE>(ArrayRef<BaseCommand *>);
-template void elf::writeMapFile<ELF32BE>(ArrayRef<BaseCommand *>);
-template void elf::writeMapFile<ELF64LE>(ArrayRef<BaseCommand *>);
-template void elf::writeMapFile<ELF64BE>(ArrayRef<BaseCommand *>);
+template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionCommand *>);
+template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionCommand *>);
+template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionCommand *>);
+template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionCommand *>);
diff --git a/ELF/MapFile.h b/ELF/MapFile.h
index f50ef00061ff..68d8ba8d4a04 100644
--- a/ELF/MapFile.h
+++ b/ELF/MapFile.h
@@ -14,8 +14,9 @@
namespace lld {
namespace elf {
-struct BaseCommand;
-template <class ELFT> void writeMapFile(llvm::ArrayRef<BaseCommand *> Script);
+struct OutputSectionCommand;
+template <class ELFT>
+void writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script);
}
}
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index d82fdcdc31ba..f117690c3828 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -117,7 +117,7 @@ template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
// the symbol table.
Sec->Link = InX::SymTab->OutSec->SectionIndex;
- // sh_link then contain index of an entry in symbol table section which
+ // sh_info then contain index of an entry in symbol table section which
// provides signature of the section group.
elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
assert(Config->Relocatable && Sec->Sections.size() == 1);
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index f1bc245c9256..4b77e35b9bae 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -859,7 +859,11 @@ Expr ScriptParser::readPrimary() {
expect(",");
Expr E2 = readExpr();
expect(")");
- return [=] { return alignTo(E().getValue(), E2().getValue()); };
+ return [=] {
+ ExprValue V = E();
+ V.Alignment = E2().getValue();
+ return V;
+ };
}
if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral();
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index e539d8ffce6e..77d6412f80ad 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -74,6 +74,7 @@ private:
std::unique_ptr<FileOutputBuffer> Buffer;
std::vector<OutputSection *> OutputSections;
+ std::vector<OutputSectionCommand *> OutputSectionCommands;
OutputSectionFactory Factory{OutputSections};
void addRelIpltSymbols();
@@ -262,6 +263,10 @@ template <class ELFT> void Writer<ELFT>::run() {
Script->fabricateDefaultCommands();
}
+ for (BaseCommand *Base : Script->Opt.Commands)
+ if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+ OutputSectionCommands.push_back(Cmd);
+
// If -compressed-debug-sections is specified, we need to compress
// .debug_* sections. Do it right now because it changes the size of
// output sections.
@@ -311,7 +316,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// Handle -Map option.
- writeMapFile<ELFT>(Script->Opt.Commands);
+ writeMapFile<ELFT>(OutputSectionCommands);
if (ErrorCount)
return;
@@ -1201,8 +1206,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (ErrorCount)
return;
- // So far we have added sections from input object files.
- // This function adds linker-created Out::* sections.
addPredefinedSections();
removeUnusedSyntheticSections(OutputSections);
@@ -1270,8 +1273,20 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
// ARM ABI requires .ARM.exidx to be terminated by some piece of data.
// We have the terminater synthetic section class. Add that at the end.
auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx"));
- if (OS && !OS->Sections.empty() && !Config->Relocatable)
- OS->addSection(make<ARMExidxSentinelSection>());
+ if (!OS || OS->Sections.empty() || Config->Relocatable)
+ return;
+
+ auto *Sentinel = make<ARMExidxSentinelSection>();
+ OS->addSection(Sentinel);
+ // If there are linker script commands existing at this point then add the
+ // sentinel to the last of these too.
+ if (OutputSectionCommand *C = Script->getCmd(OS)) {
+ auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(),
+ [](const BaseCommand *Base) {
+ return isa<InputSectionDescription>(Base);
+ });
+ cast<InputSectionDescription>(*ISD)->Sections.push_back(Sentinel);
+ }
}
// The linker is expected to define SECNAME_start and SECNAME_end
@@ -1315,10 +1330,9 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
template <class ELFT>
OutputSectionCommand *Writer<ELFT>::findSectionCommand(StringRef Name) {
- for (BaseCommand *Base : Script->Opt.Commands)
- if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
- if (Cmd->Name == Name)
- return Cmd;
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ if (Cmd->Name == Name)
+ return Cmd;
return nullptr;
}
@@ -1713,7 +1727,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
EHdr->e_ehsize = sizeof(Elf_Ehdr);
EHdr->e_phnum = Phdrs.size();
EHdr->e_shentsize = sizeof(Elf_Shdr);
- EHdr->e_shnum = OutputSections.size() + 1;
+ EHdr->e_shnum = OutputSectionCommands.size() + 1;
EHdr->e_shstrndx = InX::ShStrTab->OutSec->SectionIndex;
if (Config->EMachine == EM_ARM)
@@ -1745,8 +1759,8 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// Write the section header table. Note that the first table entry is null.
auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
- for (OutputSection *Sec : OutputSections)
- Sec->writeHeaderTo<ELFT>(++SHdrs);
+ for (OutputSectionCommand *Cmd : OutputSectionCommands)
+ Cmd->Sec->writeHeaderTo<ELFT>(++SHdrs);
}
// Open a result file.
@@ -1769,10 +1783,7 @@ template <class ELFT> void Writer<ELFT>::openFile() {
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
uint8_t *Buf = Buffer->getBufferStart();
- for (BaseCommand *Base : Script->Opt.Commands) {
- auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
- if (!Cmd)
- continue;
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
OutputSection *Sec = Cmd->Sec;
if (Sec->Flags & SHF_ALLOC)
Cmd->writeTo<ELFT>(Buf + Sec->Offset);
@@ -1799,19 +1810,13 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
// In -r or -emit-relocs mode, write the relocation sections first as in
// ELf_Rel targets we might find out that we need to modify the relocated
// section while doing it.
- for (BaseCommand *Base : Script->Opt.Commands) {
- auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
- if (!Cmd)
- continue;
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
OutputSection *Sec = Cmd->Sec;
if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
Cmd->writeTo<ELFT>(Buf + Sec->Offset);
}
- for (BaseCommand *Base : Script->Opt.Commands) {
- auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
- if (!Cmd)
- continue;
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
OutputSection *Sec = Cmd->Sec;
if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
Sec->Type != SHT_RELA)
diff --git a/test/ELF/linkerscript/align.s b/test/ELF/linkerscript/align.s
index ffeb1acbd027..357f54ce1ca5 100644
--- a/test/ELF/linkerscript/align.s
+++ b/test/ELF/linkerscript/align.s
@@ -64,7 +64,7 @@
# SYMBOLS-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
# SYMBOLS-NEXT: 0000000000001000 *ABS* 00000000 VAR
# SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb
-# SYMBOLS-NEXT: 0000000000012000 *ABS* 00000000 __end_bbb
+# SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb
.global _start
_start:
diff --git a/test/ELF/linkerscript/bss-fill.s b/test/ELF/linkerscript/bss-fill.s
new file mode 100644
index 000000000000..92f9fdf56190
--- /dev/null
+++ b/test/ELF/linkerscript/bss-fill.s
@@ -0,0 +1,7 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { .bss : { . += 0x10000; *(.bss) } =0xFF };" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+
+.section .bss,"",@nobits
+.short 0
diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s
index ae53ebc4d400..950d822ec403 100644
--- a/test/ELF/linkerscript/merge-sections.s
+++ b/test/ELF/linkerscript/merge-sections.s
@@ -31,6 +31,16 @@
# 0x19E = begin + sizeof(.foo) = 0x190 + 0xE
# CHECK-NEXT: Value: 0x19E
+# Check that we don't crash with --gc-sections
+# RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared
+# RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC
+
+# GC: Name: .foo
+# GC-NEXT: Type: SHT_PROGBITS
+# GC-NEXT: Flags [
+# GC-NEXT: SHF_ALLOC
+# GC-NEXT: ]
+
.section .foo.1a,"aMS",@progbits,1
.asciz "foo"
diff --git a/test/ELF/linkerscript/symbol-reserved.s b/test/ELF/linkerscript/symbol-reserved.s
index ccbe761738ba..e0b259597381 100644
--- a/test/ELF/linkerscript/symbol-reserved.s
+++ b/test/ELF/linkerscript/symbol-reserved.s
@@ -11,6 +11,12 @@
# SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym
+# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(__ehdr_start, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script
+# RUN: ld.lld -o %t1 %t.script %t
+# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGNED %s
+
+# ALIGNED: 0000000000200005 .text 00000000 .hidden newsym
+
.global _start
_start:
lea newsym(%rip),%rax