mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
Vendor import of lld trunk r304222:
https://llvm.org/svn/llvm-project/lld/trunk@304222
This commit is contained in:
parent
bef2946c21
commit
cbb560c9ba
11 changed files with 83 additions and 41 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
|
|
@ -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 *>);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
7
test/ELF/linkerscript/bss-fill.s
Normal file
7
test/ELF/linkerscript/bss-fill.s
Normal file
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue