2015-07-25 05:03:07 +08:00
|
|
|
//===- Writer.cpp ---------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-09-05 06:48:30 +08:00
|
|
|
#include "Writer.h"
|
2017-12-05 23:59:05 +08:00
|
|
|
#include "AArch64ErrataFix.h"
|
2015-08-06 07:51:50 +08:00
|
|
|
#include "Config.h"
|
2017-03-24 08:15:16 +08:00
|
|
|
#include "Filesystem.h"
|
2016-02-12 05:17:59 +08:00
|
|
|
#include "LinkerScript.h"
|
2017-01-14 05:05:46 +08:00
|
|
|
#include "MapFile.h"
|
2015-09-22 05:38:08 +08:00
|
|
|
#include "OutputSections.h"
|
2016-05-25 04:24:43 +08:00
|
|
|
#include "Relocations.h"
|
2015-08-06 07:24:46 +08:00
|
|
|
#include "SymbolTable.h"
|
2017-12-10 00:56:18 +08:00
|
|
|
#include "Symbols.h"
|
2016-11-02 04:28:21 +08:00
|
|
|
#include "SyntheticSections.h"
|
2015-09-23 02:19:46 +08:00
|
|
|
#include "Target.h"
|
2017-11-29 04:39:17 +08:00
|
|
|
#include "lld/Common/Memory.h"
|
2018-03-01 01:38:19 +08:00
|
|
|
#include "lld/Common/Strings.h"
|
2017-10-14 02:22:55 +08:00
|
|
|
#include "lld/Common/Threads.h"
|
2015-11-12 17:52:08 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
2015-10-13 04:51:48 +08:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2016-09-29 09:45:22 +08:00
|
|
|
#include <climits>
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::ELF;
|
|
|
|
using namespace llvm::object;
|
2016-10-10 17:39:26 +08:00
|
|
|
using namespace llvm::support;
|
|
|
|
using namespace llvm::support::endian;
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
using namespace lld;
|
2016-02-28 08:25:54 +08:00
|
|
|
using namespace lld::elf;
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2015-08-06 07:24:46 +08:00
|
|
|
namespace {
|
|
|
|
// The writer writes a SymbolTable result to a file.
|
|
|
|
template <class ELFT> class Writer {
|
|
|
|
public:
|
2017-11-14 02:06:43 +08:00
|
|
|
Writer() : Buffer(errorHandler().OutputBuffer) {}
|
2016-03-15 07:16:09 +08:00
|
|
|
typedef typename ELFT::Shdr Elf_Shdr;
|
|
|
|
typedef typename ELFT::Ehdr Elf_Ehdr;
|
|
|
|
typedef typename ELFT::Phdr Elf_Phdr;
|
2017-04-06 05:46:06 +08:00
|
|
|
|
2015-08-06 07:24:46 +08:00
|
|
|
void run();
|
|
|
|
|
|
|
|
private:
|
2015-10-09 07:49:30 +08:00
|
|
|
void copyLocalSymbols();
|
2017-02-11 09:40:49 +08:00
|
|
|
void addSectionSymbols();
|
2017-02-23 10:28:28 +08:00
|
|
|
void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
|
2016-09-22 06:36:19 +08:00
|
|
|
void sortSections();
|
2017-12-12 21:30:44 +08:00
|
|
|
void resolveShfLinkOrder();
|
2017-10-30 18:12:49 +08:00
|
|
|
void sortInputSections();
|
2016-07-20 22:43:20 +08:00
|
|
|
void finalizeSections();
|
2017-09-13 00:38:01 +08:00
|
|
|
void setReservedSymbolSections();
|
2015-12-25 15:38:58 +08:00
|
|
|
|
2017-07-27 15:46:50 +08:00
|
|
|
std::vector<PhdrEntry *> createPhdrs();
|
2016-12-06 21:43:34 +08:00
|
|
|
void removeEmptyPTLoad();
|
2017-07-27 15:46:50 +08:00
|
|
|
void addPtArmExid(std::vector<PhdrEntry *> &Phdrs);
|
2016-04-02 01:07:17 +08:00
|
|
|
void assignFileOffsets();
|
2016-08-25 17:05:47 +08:00
|
|
|
void assignFileOffsetsBinary();
|
2016-04-02 01:07:17 +08:00
|
|
|
void setPhdrs();
|
2018-04-04 17:24:31 +08:00
|
|
|
void checkSections();
|
2016-03-31 03:41:51 +08:00
|
|
|
void fixSectionAlignments();
|
2016-04-02 01:24:19 +08:00
|
|
|
void openFile();
|
2017-08-03 00:35:00 +08:00
|
|
|
void writeTrapInstr();
|
2015-08-06 07:24:46 +08:00
|
|
|
void writeHeader();
|
|
|
|
void writeSections();
|
2016-08-25 17:05:47 +08:00
|
|
|
void writeSectionsBinary();
|
ELF: Implement --build-id.
This patch implements --build-id. After the linker creates an output file
in the memory buffer, it computes the FNV1 hash of the resulting file
and set the hash to the .note section as a build-id.
GNU ld and gold have the same feature, but their default choice of the
hash function is different. Their default is SHA1.
We made a deliberate choice to not use a secure hash function for the
sake of performance. Computing a secure hash is slow -- for example,
MD5 throughput is usually 400 MB/s or so. SHA1 is slower than that.
As a result, if you pass --build-id to gold, then the linker becomes about
10% slower than that without the option. We observed a similar degradation
in an experimental implementation of build-id for LLD. On the other hand,
we observed only 1-2% performance degradation with the FNV hash.
Since build-id is not for digital certificate or anything, we think that
a very small probability of collision is acceptable.
We considered using other signals such as using input file timestamps as
inputs to a secure hash function. But such signals would have an issue
with build reproducibility (if you build a binary from the same source
tree using the same toolchain, the build id should become the same.)
GNU linkers accepts --build-id=<style> option where style is one of
"MD5", "SHA1", or an arbitrary hex string. That option is out of scope
of this patch.
http://reviews.llvm.org/D18091
llvm-svn: 263292
2016-03-12 04:51:53 +08:00
|
|
|
void writeBuildId();
|
2015-08-06 07:24:46 +08:00
|
|
|
|
2017-11-14 02:06:43 +08:00
|
|
|
std::unique_ptr<FileOutputBuffer> &Buffer;
|
2015-09-18 03:58:07 +08:00
|
|
|
|
2015-12-26 17:47:57 +08:00
|
|
|
void addRelIpltSymbols();
|
2015-12-26 17:48:00 +08:00
|
|
|
void addStartEndSymbols();
|
2017-02-24 23:07:30 +08:00
|
|
|
void addStartStopSymbols(OutputSection *Sec);
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t getEntryAddr();
|
2015-10-11 06:34:30 +08:00
|
|
|
|
2017-07-27 15:46:50 +08:00
|
|
|
std::vector<PhdrEntry *> Phdrs;
|
2015-09-18 03:58:07 +08:00
|
|
|
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t FileSize;
|
|
|
|
uint64_t SectionHeaderOff;
|
2017-06-26 18:22:17 +08:00
|
|
|
|
|
|
|
bool HasGotBaseSym = false;
|
2015-08-06 07:24:46 +08:00
|
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2017-12-01 17:04:52 +08:00
|
|
|
StringRef elf::getOutputSectionName(InputSectionBase *S) {
|
2016-10-05 18:10:45 +08:00
|
|
|
if (Config->Relocatable)
|
2017-12-01 17:14:56 +08:00
|
|
|
return S->Name;
|
2016-10-05 18:10:45 +08:00
|
|
|
|
2017-12-01 17:04:52 +08:00
|
|
|
// This is for --emit-relocs. If .text.foo is emitted as .text.bar, we want
|
|
|
|
// to emit .rela.text.foo as .rela.text.bar for consistency (this is not
|
|
|
|
// technically required, but not doing it is odd). This code guarantees that.
|
2018-03-27 02:49:31 +08:00
|
|
|
if (auto *IS = dyn_cast<InputSection>(S)) {
|
|
|
|
if (InputSectionBase *Rel = IS->getRelocatedSection()) {
|
|
|
|
OutputSection *Out = Rel->getOutputSection();
|
|
|
|
if (S->Type == SHT_RELA)
|
|
|
|
return Saver.save(".rela" + Out->Name);
|
|
|
|
return Saver.save(".rel" + Out->Name);
|
|
|
|
}
|
2017-12-01 17:04:52 +08:00
|
|
|
}
|
2017-10-27 19:38:31 +08:00
|
|
|
|
2016-09-20 03:59:21 +08:00
|
|
|
for (StringRef V :
|
2017-03-17 18:14:53 +08:00
|
|
|
{".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
|
|
|
|
".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
|
2017-06-28 17:12:38 +08:00
|
|
|
".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) {
|
2016-09-20 03:59:21 +08:00
|
|
|
StringRef Prefix = V.drop_back();
|
2017-12-01 17:14:56 +08:00
|
|
|
if (S->Name.startswith(V) || S->Name == Prefix)
|
2016-09-20 03:59:21 +08:00
|
|
|
return Prefix;
|
|
|
|
}
|
2016-10-13 06:36:31 +08:00
|
|
|
|
2016-11-06 07:05:47 +08:00
|
|
|
// CommonSection is identified as "COMMON" in linker scripts.
|
|
|
|
// By default, it should go to .bss section.
|
2017-12-01 17:14:56 +08:00
|
|
|
if (S->Name == "COMMON")
|
2016-11-06 07:05:47 +08:00
|
|
|
return ".bss";
|
|
|
|
|
2017-12-01 17:14:56 +08:00
|
|
|
return S->Name;
|
2016-07-12 16:50:42 +08:00
|
|
|
}
|
|
|
|
|
2017-09-19 17:20:54 +08:00
|
|
|
static bool needsInterpSection() {
|
|
|
|
return !SharedFiles.empty() && !Config->DynamicLinker.empty() &&
|
2017-10-08 11:52:15 +08:00
|
|
|
Script->needsInterpSection();
|
2016-07-21 19:01:23 +08:00
|
|
|
}
|
|
|
|
|
2016-11-14 18:14:18 +08:00
|
|
|
template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
|
2015-10-08 03:18:16 +08:00
|
|
|
|
2016-12-06 21:43:34 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
|
2017-08-28 17:28:15 +08:00
|
|
|
llvm::erase_if(Phdrs, [&](const PhdrEntry *P) {
|
2017-07-27 15:46:50 +08:00
|
|
|
if (P->p_type != PT_LOAD)
|
2016-12-06 21:43:34 +08:00
|
|
|
return false;
|
2017-09-07 19:01:10 +08:00
|
|
|
if (!P->FirstSec)
|
2016-12-08 11:17:05 +08:00
|
|
|
return true;
|
2017-09-07 19:01:10 +08:00
|
|
|
uint64_t Size = P->LastSec->Addr + P->LastSec->Size - P->FirstSec->Addr;
|
2016-12-06 21:43:34 +08:00
|
|
|
return Size == 0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-11 04:00:42 +08:00
|
|
|
template <class ELFT> static void combineEhFrameSections() {
|
|
|
|
for (InputSectionBase *&S : InputSections) {
|
|
|
|
EhInputSection *ES = dyn_cast<EhInputSection>(S);
|
2017-03-15 20:31:54 +08:00
|
|
|
if (!ES || !ES->Live)
|
2017-03-11 04:00:42 +08:00
|
|
|
continue;
|
|
|
|
|
2017-10-27 11:13:39 +08:00
|
|
|
InX::EhFrame->addSection<ELFT>(ES);
|
2017-03-11 04:00:42 +08:00
|
|
|
S = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<InputSectionBase *> &V = InputSections;
|
|
|
|
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
|
|
|
|
}
|
|
|
|
|
2017-12-09 03:13:27 +08:00
|
|
|
static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
|
|
|
|
uint64_t Val, uint8_t StOther = STV_HIDDEN,
|
|
|
|
uint8_t Binding = STB_GLOBAL) {
|
|
|
|
Symbol *S = Symtab->find(Name);
|
|
|
|
if (!S || S->isDefined())
|
|
|
|
return nullptr;
|
2017-12-24 01:21:39 +08:00
|
|
|
Symbol *Sym = Symtab->addRegular(Name, StOther, STT_NOTYPE, Val,
|
|
|
|
/*Size=*/0, Binding, Sec,
|
|
|
|
/*File=*/nullptr);
|
2017-12-09 03:13:27 +08:00
|
|
|
return cast<Defined>(Sym);
|
|
|
|
}
|
|
|
|
|
|
|
|
// The linker is expected to define some symbols depending on
|
|
|
|
// the linking result. This function defines such symbols.
|
2017-12-24 01:21:39 +08:00
|
|
|
void elf::addReservedSymbols() {
|
2017-12-09 03:13:27 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
|
|
|
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
|
|
|
|
// so that it points to an absolute address which by default is relative
|
|
|
|
// to GOT. Default offset is 0x7ff0.
|
|
|
|
// See "Global Data Symbols" in Chapter 6 in the following document:
|
|
|
|
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
2017-12-24 01:21:39 +08:00
|
|
|
ElfSym::MipsGp = Symtab->addAbsolute("_gp", STV_HIDDEN, STB_GLOBAL);
|
2017-12-09 03:13:27 +08:00
|
|
|
|
|
|
|
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
|
|
|
|
// start of function and 'gp' pointer into GOT.
|
|
|
|
if (Symtab->find("_gp_disp"))
|
|
|
|
ElfSym::MipsGpDisp =
|
2017-12-24 01:21:39 +08:00
|
|
|
Symtab->addAbsolute("_gp_disp", STV_HIDDEN, STB_GLOBAL);
|
2017-12-09 03:13:27 +08:00
|
|
|
|
|
|
|
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
|
|
|
|
// pointer. This symbol is used in the code generated by .cpload pseudo-op
|
|
|
|
// in case of using -mno-shared option.
|
|
|
|
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
|
|
|
|
if (Symtab->find("__gnu_local_gp"))
|
|
|
|
ElfSym::MipsLocalGp =
|
2017-12-24 01:21:39 +08:00
|
|
|
Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
|
2017-12-09 03:13:27 +08:00
|
|
|
}
|
|
|
|
|
2018-03-20 01:40:14 +08:00
|
|
|
// The 64-bit PowerOpen ABI defines a TableOfContents (TOC) which combines the
|
|
|
|
// typical ELF GOT with the small data sections. It commonly includes .got
|
|
|
|
// .toc .sdata .sbss. The .TOC. symbol replaces both _GLOBAL_OFFSET_TABLE_ and
|
|
|
|
// _SDA_BASE_ from the 32-bit ABI. It is used to represent the TOC base which
|
|
|
|
// is offset by 0x8000 bytes from the start of the .got section.
|
2017-12-24 01:21:39 +08:00
|
|
|
ElfSym::GlobalOffsetTable = addOptionalRegular(
|
2018-03-20 01:40:14 +08:00
|
|
|
(Config->EMachine == EM_PPC64) ? ".TOC." : "_GLOBAL_OFFSET_TABLE_",
|
|
|
|
Out::ElfHeader, Target->GotBaseSymOff);
|
2017-12-09 03:13:27 +08:00
|
|
|
|
|
|
|
// __ehdr_start is the location of ELF file headers. Note that we define
|
|
|
|
// this symbol unconditionally even when using a linker script, which
|
|
|
|
// differs from the behavior implemented by GNU linker which only define
|
|
|
|
// this symbol if ELF headers are in the memory mapped segment.
|
2018-03-29 06:09:40 +08:00
|
|
|
addOptionalRegular("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
|
|
|
|
|
2017-12-09 03:13:27 +08:00
|
|
|
// __executable_start is not documented, but the expectation of at
|
2018-03-29 06:09:40 +08:00
|
|
|
// least the Android libc is that it points to the ELF header.
|
|
|
|
addOptionalRegular("__executable_start", Out::ElfHeader, 0, STV_HIDDEN);
|
|
|
|
|
2017-12-09 03:13:27 +08:00
|
|
|
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
|
|
|
|
// each DSO. The address of the symbol doesn't matter as long as they are
|
|
|
|
// different in different DSOs, so we chose the start address of the DSO.
|
2018-03-29 06:09:40 +08:00
|
|
|
addOptionalRegular("__dso_handle", Out::ElfHeader, 0, STV_HIDDEN);
|
2017-12-09 03:13:27 +08:00
|
|
|
|
|
|
|
// If linker script do layout we do not need to create any standart symbols.
|
|
|
|
if (Script->HasSectionsCommand)
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto Add = [](StringRef S, int64_t Pos) {
|
2017-12-24 01:21:39 +08:00
|
|
|
return addOptionalRegular(S, Out::ElfHeader, Pos, STV_DEFAULT);
|
2017-12-09 03:13:27 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
ElfSym::Bss = Add("__bss_start", 0);
|
|
|
|
ElfSym::End1 = Add("end", -1);
|
|
|
|
ElfSym::End2 = Add("_end", -1);
|
|
|
|
ElfSym::Etext1 = Add("etext", -1);
|
|
|
|
ElfSym::Etext2 = Add("_etext", -1);
|
|
|
|
ElfSym::Edata1 = Add("edata", -1);
|
|
|
|
ElfSym::Edata2 = Add("_edata", -1);
|
|
|
|
}
|
|
|
|
|
2017-12-09 05:44:11 +08:00
|
|
|
static OutputSection *findSection(StringRef Name) {
|
|
|
|
for (BaseCommand *Base : Script->SectionCommands)
|
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
|
|
|
if (Sec->Name == Name)
|
|
|
|
return Sec;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-02-27 10:31:26 +08:00
|
|
|
// Initialize Out members.
|
2017-12-09 05:50:29 +08:00
|
|
|
template <class ELFT> static void createSyntheticSections() {
|
2016-11-02 07:17:45 +08:00
|
|
|
// Initialize all pointers with NULL. This is needed because
|
|
|
|
// you can call lld::elf::main more than once as a library.
|
2017-02-27 10:31:26 +08:00
|
|
|
memset(&Out::First, 0, sizeof(Out));
|
2016-11-02 07:17:45 +08:00
|
|
|
|
2017-02-27 10:32:08 +08:00
|
|
|
auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
|
2017-02-05 13:18:58 +08:00
|
|
|
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::DynStrTab = make<StringTableSection>(".dynstr", true);
|
2017-05-12 07:16:43 +08:00
|
|
|
InX::Dynamic = make<DynamicSection<ELFT>>();
|
2017-10-28 01:49:40 +08:00
|
|
|
if (Config->AndroidPackDynRelocs) {
|
2017-12-11 03:44:42 +08:00
|
|
|
InX::RelaDyn = make<AndroidPackedRelocationSection<ELFT>>(
|
2017-10-28 01:49:40 +08:00
|
|
|
Config->IsRela ? ".rela.dyn" : ".rel.dyn");
|
|
|
|
} else {
|
2017-12-11 03:44:42 +08:00
|
|
|
InX::RelaDyn = make<RelocationSection<ELFT>>(
|
2017-10-28 01:49:40 +08:00
|
|
|
Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
|
|
|
|
}
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
|
2016-11-02 07:17:45 +08:00
|
|
|
|
2017-02-27 10:31:26 +08:00
|
|
|
Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
|
2017-10-07 08:58:34 +08:00
|
|
|
Out::ProgramHeaders->Alignment = Config->Wordsize;
|
2016-11-02 07:17:45 +08:00
|
|
|
|
2017-09-19 17:20:54 +08:00
|
|
|
if (needsInterpSection()) {
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::Interp = createInterpSection();
|
|
|
|
Add(InX::Interp);
|
2016-11-06 07:05:47 +08:00
|
|
|
} else {
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::Interp = nullptr;
|
2016-11-06 07:05:47 +08:00
|
|
|
}
|
2016-11-02 07:17:45 +08:00
|
|
|
|
|
|
|
if (Config->Strip != StripPolicy::All) {
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::StrTab = make<StringTableSection>(".strtab", false);
|
2017-05-16 16:53:30 +08:00
|
|
|
InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
|
2016-11-02 07:17:45 +08:00
|
|
|
}
|
|
|
|
|
2016-11-22 08:54:15 +08:00
|
|
|
if (Config->BuildId != BuildIdKind::None) {
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::BuildId = make<BuildIdSection>();
|
|
|
|
Add(InX::BuildId);
|
2016-11-22 08:54:15 +08:00
|
|
|
}
|
2016-11-06 07:05:47 +08:00
|
|
|
|
2017-10-04 08:21:17 +08:00
|
|
|
InX::Bss = make<BssSection>(".bss", 0, 1);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::Bss);
|
2017-11-24 16:48:29 +08:00
|
|
|
|
|
|
|
// If there is a SECTIONS command and a .data.rel.ro section name use name
|
|
|
|
// .data.rel.ro.bss so that we match in the .data.rel.ro output section.
|
|
|
|
// This makes sure our relro is contiguous.
|
2018-03-22 21:47:56 +08:00
|
|
|
bool HasDataRelRo = Script->HasSectionsCommand && findSection(".data.rel.ro");
|
|
|
|
InX::BssRelRo =
|
|
|
|
make<BssSection>(HasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::BssRelRo);
|
2017-03-17 18:14:53 +08:00
|
|
|
|
2016-11-22 12:28:39 +08:00
|
|
|
// Add MIPS-specific sections.
|
2016-11-10 05:36:56 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
2017-09-16 02:05:02 +08:00
|
|
|
if (!Config->Shared && Config->HasDynSymTab) {
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::MipsRldMap = make<MipsRldMapSection>();
|
|
|
|
Add(InX::MipsRldMap);
|
2016-11-23 01:49:14 +08:00
|
|
|
}
|
2016-11-22 12:28:39 +08:00
|
|
|
if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(Sec);
|
2016-11-22 12:28:39 +08:00
|
|
|
if (auto *Sec = MipsOptionsSection<ELFT>::create())
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(Sec);
|
2016-11-22 12:28:39 +08:00
|
|
|
if (auto *Sec = MipsReginfoSection<ELFT>::create())
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(Sec);
|
2016-11-10 05:36:56 +08:00
|
|
|
}
|
2016-11-10 17:48:29 +08:00
|
|
|
|
2017-09-16 02:05:02 +08:00
|
|
|
if (Config->HasDynSymTab) {
|
2017-05-16 18:04:42 +08:00
|
|
|
InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
|
|
|
|
Add(InX::DynSymTab);
|
2016-11-25 16:05:41 +08:00
|
|
|
|
|
|
|
In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(In<ELFT>::VerSym);
|
2016-11-25 16:05:41 +08:00
|
|
|
|
|
|
|
if (!Config->VersionDefinitions.empty()) {
|
|
|
|
In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(In<ELFT>::VerDef);
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
|
2017-02-05 13:18:58 +08:00
|
|
|
Add(In<ELFT>::VerNeed);
|
2016-11-25 16:05:41 +08:00
|
|
|
|
|
|
|
if (Config->GnuHash) {
|
2017-05-16 18:04:42 +08:00
|
|
|
InX::GnuHashTab = make<GnuHashTableSection>();
|
|
|
|
Add(InX::GnuHashTab);
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Config->SysvHash) {
|
2017-09-27 17:14:59 +08:00
|
|
|
InX::HashTab = make<HashTableSection>();
|
|
|
|
Add(InX::HashTab);
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
|
|
|
|
2017-05-12 07:16:43 +08:00
|
|
|
Add(InX::Dynamic);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::DynStrTab);
|
2017-12-11 03:44:42 +08:00
|
|
|
Add(InX::RelaDyn);
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
|
|
|
|
2016-11-22 12:28:39 +08:00
|
|
|
// Add .got. MIPS' .got is so different from the other archs,
|
|
|
|
// it has its own class.
|
2016-11-25 16:05:41 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
2017-05-12 05:33:30 +08:00
|
|
|
InX::MipsGot = make<MipsGotSection>();
|
|
|
|
Add(InX::MipsGot);
|
2016-11-25 16:05:41 +08:00
|
|
|
} else {
|
2017-05-19 00:45:36 +08:00
|
|
|
InX::Got = make<GotSection>();
|
2017-05-12 07:26:03 +08:00
|
|
|
Add(InX::Got);
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
2016-11-17 05:01:02 +08:00
|
|
|
|
2017-05-12 05:23:38 +08:00
|
|
|
InX::GotPlt = make<GotPltSection>();
|
|
|
|
Add(InX::GotPlt);
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::IgotPlt = make<IgotPltSection>();
|
|
|
|
Add(InX::IgotPlt);
|
2016-11-30 00:05:27 +08:00
|
|
|
|
|
|
|
if (Config->GdbIndex) {
|
2017-07-13 07:56:53 +08:00
|
|
|
InX::GdbIndex = createGdbIndex<ELFT>();
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::GdbIndex);
|
2016-11-30 00:05:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// We always need to add rel[a].plt to output if it has entries.
|
|
|
|
// Even for static linking it can contain R_[*]_IRELATIVE relocations.
|
2017-12-11 04:07:03 +08:00
|
|
|
InX::RelaPlt = make<RelocationSection<ELFT>>(
|
2017-03-18 07:29:01 +08:00
|
|
|
Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
|
2017-12-11 04:07:03 +08:00
|
|
|
Add(InX::RelaPlt);
|
2016-11-30 00:05:27 +08:00
|
|
|
|
2016-12-08 20:58:55 +08:00
|
|
|
// The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
|
2017-10-28 01:49:40 +08:00
|
|
|
// that the IRelative relocations are processed last by the dynamic loader.
|
|
|
|
// We cannot place the iplt section in .rel.dyn when Android relocation
|
|
|
|
// packing is enabled because that would cause a section type mismatch.
|
|
|
|
// However, because the Android dynamic loader reads .rel.plt after .rel.dyn,
|
|
|
|
// we can get the desired behaviour by placing the iplt section in .rel.plt.
|
2017-12-11 04:07:03 +08:00
|
|
|
InX::RelaIplt = make<RelocationSection<ELFT>>(
|
2017-10-28 01:49:40 +08:00
|
|
|
(Config->EMachine == EM_ARM && !Config->AndroidPackDynRelocs)
|
|
|
|
? ".rel.dyn"
|
2017-12-11 04:07:03 +08:00
|
|
|
: InX::RelaPlt->Name,
|
2016-12-08 20:58:55 +08:00
|
|
|
false /*Sort*/);
|
2017-12-11 04:07:03 +08:00
|
|
|
Add(InX::RelaIplt);
|
2016-12-08 20:58:55 +08:00
|
|
|
|
2018-01-13 06:29:29 +08:00
|
|
|
InX::Plt = make<PltSection>(false);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::Plt);
|
2018-01-13 06:29:29 +08:00
|
|
|
InX::Iplt = make<PltSection>(true);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::Iplt);
|
2016-11-30 00:05:27 +08:00
|
|
|
|
2017-02-24 06:06:28 +08:00
|
|
|
if (!Config->Relocatable) {
|
2017-03-09 16:45:25 +08:00
|
|
|
if (Config->EhFrameHdr) {
|
2017-10-27 11:14:24 +08:00
|
|
|
InX::EhFrameHdr = make<EhFrameHeader>();
|
|
|
|
Add(InX::EhFrameHdr);
|
2017-03-09 16:45:25 +08:00
|
|
|
}
|
2017-10-27 11:13:39 +08:00
|
|
|
InX::EhFrame = make<EhFrameSection>();
|
|
|
|
Add(InX::EhFrame);
|
2017-02-24 06:06:28 +08:00
|
|
|
}
|
|
|
|
|
2017-05-16 18:04:42 +08:00
|
|
|
if (InX::SymTab)
|
|
|
|
Add(InX::SymTab);
|
2017-05-12 06:02:41 +08:00
|
|
|
Add(InX::ShStrTab);
|
|
|
|
if (InX::StrTab)
|
|
|
|
Add(InX::StrTab);
|
2017-12-20 16:56:10 +08:00
|
|
|
|
|
|
|
if (Config->EMachine == EM_ARM && !Config->Relocatable)
|
|
|
|
// Add a sentinel to terminate .ARM.exidx. It helps an unwinder
|
|
|
|
// to find the exact address range of the last entry.
|
|
|
|
Add(make<ARMExidxSentinelSection>());
|
2016-11-02 07:17:45 +08:00
|
|
|
}
|
|
|
|
|
2017-12-09 05:50:29 +08:00
|
|
|
// The main function of the writer.
|
|
|
|
template <class ELFT> void Writer<ELFT>::run() {
|
|
|
|
// Create linker-synthesized sections such as .got or .plt.
|
|
|
|
// Such sections are of type input section.
|
|
|
|
createSyntheticSections<ELFT>();
|
|
|
|
|
|
|
|
if (!Config->Relocatable)
|
|
|
|
combineEhFrameSections<ELFT>();
|
|
|
|
|
|
|
|
// We want to process linker script commands. When SECTIONS command
|
|
|
|
// is given we let it create sections.
|
|
|
|
Script->processSectionCommands();
|
|
|
|
|
|
|
|
// Linker scripts controls how input sections are assigned to output sections.
|
|
|
|
// Input sections that were not handled by scripts are called "orphans", and
|
|
|
|
// they are assigned to output sections by the default rule. Process that.
|
|
|
|
Script->addOrphanSections();
|
|
|
|
|
|
|
|
if (Config->Discard != DiscardPolicy::All)
|
|
|
|
copyLocalSymbols();
|
|
|
|
|
|
|
|
if (Config->CopyRelocs)
|
|
|
|
addSectionSymbols();
|
|
|
|
|
|
|
|
// Now that we have a complete set of output sections. This function
|
|
|
|
// completes section contents. For example, we need to add strings
|
|
|
|
// to the string table, and add entries to .got and .plt.
|
|
|
|
// finalizeSections does that.
|
|
|
|
finalizeSections();
|
|
|
|
if (errorCount())
|
|
|
|
return;
|
|
|
|
|
[ELF] Compress debug sections after assignAddresses and support custom layout
Previously, in r320472, I moved the calculation of section offsets and sizes
for compressed debug sections into maybeCompress, which happens before
assignAddresses, so that the compression had the required information. However,
I failed to take account of relocations that patch such sections. This had two
effects:
1. A race condition existed when a debug section referred to a different debug
section (see PR35788).
2. References to symbols in non-debug sections would be patched incorrectly.
This is because the addresses of such symbols are not calculated until after
assignAddresses (this was a partial regression caused by r320472, but they
could still have been broken before, in the event that a custom layout was used
in a linker script).
assignAddresses does not need to know about the output section size of
non-allocatable sections, because they do not affect the value of Dot. This
means that there is no longer a reason not to support custom layout of
compressed debug sections, as far as I'm aware. These two points allow for
delaying when maybeCompress can be called, removing the need for the loop I
previously added to calculate the section size, and therefore the race
condition. Furthermore, by delaying, we fix the issues of relocations getting
incorrect symbol values, because they have now all been finalized.
llvm-svn: 321986
2018-01-08 18:17:03 +08:00
|
|
|
Script->assignAddresses();
|
|
|
|
|
2017-12-09 05:50:29 +08:00
|
|
|
// If -compressed-debug-sections is specified, we need to compress
|
|
|
|
// .debug_* sections. Do it right now because it changes the size of
|
|
|
|
// output sections.
|
2018-01-09 07:12:42 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
Sec->maybeCompress<ELFT>();
|
2017-12-09 05:50:29 +08:00
|
|
|
|
|
|
|
Script->allocateHeaders(Phdrs);
|
|
|
|
|
|
|
|
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
|
|
|
|
// 0 sized region. This has to be done late since only after assignAddresses
|
|
|
|
// we know the size of the sections.
|
|
|
|
removeEmptyPTLoad();
|
|
|
|
|
|
|
|
if (!Config->OFormatBinary)
|
|
|
|
assignFileOffsets();
|
|
|
|
else
|
|
|
|
assignFileOffsetsBinary();
|
|
|
|
|
|
|
|
setPhdrs();
|
|
|
|
|
|
|
|
if (Config->Relocatable) {
|
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
Sec->Addr = 0;
|
|
|
|
}
|
|
|
|
|
2018-02-03 06:24:06 +08:00
|
|
|
if (Config->CheckSections)
|
2018-04-04 17:24:31 +08:00
|
|
|
checkSections();
|
2018-01-31 17:22:44 +08:00
|
|
|
|
2017-12-09 05:50:29 +08:00
|
|
|
// It does not make sense try to open the file if we have error already.
|
|
|
|
if (errorCount())
|
|
|
|
return;
|
|
|
|
// Write the result down to a file.
|
|
|
|
openFile();
|
|
|
|
if (errorCount())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!Config->OFormatBinary) {
|
|
|
|
writeTrapInstr();
|
|
|
|
writeHeader();
|
|
|
|
writeSections();
|
|
|
|
} else {
|
|
|
|
writeSectionsBinary();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Backfill .note.gnu.build-id section content. This is done at last
|
|
|
|
// because the content is usually a hash value of the entire output file.
|
|
|
|
writeBuildId();
|
|
|
|
if (errorCount())
|
|
|
|
return;
|
|
|
|
|
2018-03-15 04:29:45 +08:00
|
|
|
// Handle -Map and -cref options.
|
2017-12-09 05:50:29 +08:00
|
|
|
writeMapFile();
|
2018-03-15 04:29:45 +08:00
|
|
|
writeCrossReferenceTable();
|
2017-12-09 05:50:29 +08:00
|
|
|
if (errorCount())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (auto E = Buffer->commit())
|
|
|
|
error("failed to write to the output file: " + toString(std::move(E)));
|
|
|
|
}
|
|
|
|
|
2017-03-09 06:36:28 +08:00
|
|
|
static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
|
2017-11-04 05:21:47 +08:00
|
|
|
const Symbol &B) {
|
2018-04-09 19:43:52 +08:00
|
|
|
if (B.isSection())
|
2016-01-28 02:04:26 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// If sym references a section in a discarded group, don't keep it.
|
2017-02-24 00:49:07 +08:00
|
|
|
if (Sec == &InputSection::Discarded)
|
2016-01-28 02:04:26 +08:00
|
|
|
return false;
|
|
|
|
|
2016-08-31 16:46:30 +08:00
|
|
|
if (Config->Discard == DiscardPolicy::None)
|
2016-01-28 02:04:26 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// In ELF assembly .L symbols are normally discarded by the assembler.
|
|
|
|
// If the assembler fails to do so, the linker discards them if
|
|
|
|
// * --discard-locals is used.
|
|
|
|
// * The symbol is in a SHF_MERGE section, which is normally the reason for
|
|
|
|
// the assembler keeping the .L symbol.
|
|
|
|
if (!SymName.startswith(".L") && !SymName.empty())
|
|
|
|
return true;
|
|
|
|
|
2016-08-31 16:46:30 +08:00
|
|
|
if (Config->Discard == DiscardPolicy::Locals)
|
2016-01-28 02:04:26 +08:00
|
|
|
return false;
|
|
|
|
|
2016-10-26 20:36:56 +08:00
|
|
|
return !Sec || !(Sec->Flags & SHF_MERGE);
|
2016-01-28 02:04:26 +08:00
|
|
|
}
|
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
static bool includeInSymtab(const Symbol &B) {
|
2017-11-01 00:07:41 +08:00
|
|
|
if (!B.isLocal() && !B.IsUsedInRegularObj)
|
2016-05-06 00:40:28 +08:00
|
|
|
return false;
|
|
|
|
|
2017-11-06 12:35:31 +08:00
|
|
|
if (auto *D = dyn_cast<Defined>(&B)) {
|
2016-05-06 00:40:28 +08:00
|
|
|
// Always include absolute symbols.
|
2017-03-09 06:36:28 +08:00
|
|
|
SectionBase *Sec = D->Section;
|
|
|
|
if (!Sec)
|
2016-05-06 00:40:28 +08:00
|
|
|
return true;
|
2017-12-14 06:59:23 +08:00
|
|
|
Sec = Sec->Repl;
|
|
|
|
// Exclude symbols pointing to garbage-collected sections.
|
|
|
|
if (isa<InputSectionBase>(Sec) && !Sec->Live)
|
|
|
|
return false;
|
2017-03-09 06:36:28 +08:00
|
|
|
if (auto *S = dyn_cast<MergeInputSection>(Sec))
|
2016-05-22 08:41:38 +08:00
|
|
|
if (!S->getSectionPiece(D->Value)->Live)
|
2016-05-06 00:40:28 +08:00
|
|
|
return false;
|
2017-11-29 04:17:58 +08:00
|
|
|
return true;
|
2016-05-06 00:40:28 +08:00
|
|
|
}
|
2017-11-29 04:17:58 +08:00
|
|
|
return B.Used;
|
2016-05-06 00:40:28 +08:00
|
|
|
}
|
2016-05-06 00:38:46 +08:00
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
// Local symbols are not in the linker's symbol table. This function scans
|
|
|
|
// each object file's symbol table to copy local symbols to the output.
|
|
|
|
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
|
2017-05-16 18:04:42 +08:00
|
|
|
if (!InX::SymTab)
|
2016-01-21 11:07:38 +08:00
|
|
|
return;
|
2017-09-19 17:20:54 +08:00
|
|
|
for (InputFile *File : ObjectFiles) {
|
|
|
|
ObjFile<ELFT> *F = cast<ObjFile<ELFT>>(File);
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *B : F->getLocalSymbols()) {
|
2017-10-13 11:37:26 +08:00
|
|
|
if (!B->isLocal())
|
2016-11-24 02:07:33 +08:00
|
|
|
fatal(toString(F) +
|
2016-10-11 17:07:14 +08:00
|
|
|
": broken object: getLocalSymbols returns a non-local symbol");
|
2017-11-06 12:35:31 +08:00
|
|
|
auto *DR = dyn_cast<Defined>(B);
|
2016-11-24 02:07:33 +08:00
|
|
|
|
2016-04-04 22:04:16 +08:00
|
|
|
// No reason to keep local undefined symbol in symtab.
|
|
|
|
if (!DR)
|
|
|
|
continue;
|
2017-03-16 19:20:02 +08:00
|
|
|
if (!includeInSymtab(*B))
|
2016-05-06 00:38:46 +08:00
|
|
|
continue;
|
2016-11-24 02:07:33 +08:00
|
|
|
|
2017-03-09 06:36:28 +08:00
|
|
|
SectionBase *Sec = DR->Section;
|
2017-03-16 19:20:02 +08:00
|
|
|
if (!shouldKeepInSymtab(Sec, B->getName(), *B))
|
2015-10-10 03:25:07 +08:00
|
|
|
continue;
|
2017-05-16 18:04:42 +08:00
|
|
|
InX::SymTab->addSymbol(B);
|
2015-10-09 07:49:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-11 09:40:49 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
|
2017-11-16 20:33:36 +08:00
|
|
|
// Create a section symbol for each output section so that we can represent
|
|
|
|
// relocations that point to the section. If we know that no relocation is
|
|
|
|
// referring to a section (that happens if the section is a synthetic one), we
|
|
|
|
// don't create a section symbol for that section.
|
2017-10-11 09:50:56 +08:00
|
|
|
for (BaseCommand *Base : Script->SectionCommands) {
|
2017-07-28 03:22:43 +08:00
|
|
|
auto *Sec = dyn_cast<OutputSection>(Base);
|
|
|
|
if (!Sec)
|
2017-03-01 03:43:54 +08:00
|
|
|
continue;
|
2017-10-11 09:50:56 +08:00
|
|
|
auto I = llvm::find_if(Sec->SectionCommands, [](BaseCommand *Base) {
|
2017-07-05 03:08:40 +08:00
|
|
|
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
|
|
|
|
return !ISD->Sections.empty();
|
|
|
|
return false;
|
|
|
|
});
|
2017-10-11 09:50:56 +08:00
|
|
|
if (I == Sec->SectionCommands.end())
|
2017-07-05 03:08:40 +08:00
|
|
|
continue;
|
|
|
|
InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
|
2017-11-16 20:33:36 +08:00
|
|
|
|
|
|
|
// Relocations are not using REL[A] section symbols.
|
|
|
|
if (IS->Type == SHT_REL || IS->Type == SHT_RELA)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Unlike other synthetic sections, mergeable output sections contain data
|
|
|
|
// copied from input sections, and there may be a relocation pointing to its
|
2017-11-17 19:27:57 +08:00
|
|
|
// contents if -r or -emit-reloc are given.
|
2017-11-16 20:33:36 +08:00
|
|
|
if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE))
|
2017-02-11 09:40:49 +08:00
|
|
|
continue;
|
|
|
|
|
2017-11-30 06:47:35 +08:00
|
|
|
auto *Sym =
|
|
|
|
make<Defined>(IS->File, "", STB_LOCAL, /*StOther=*/0, STT_SECTION,
|
|
|
|
/*Value=*/0, /*Size=*/0, IS);
|
2017-05-16 18:04:42 +08:00
|
|
|
InX::SymTab->addSymbol(Sym);
|
2017-02-11 09:40:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-16 12:51:46 +08:00
|
|
|
// Today's loaders have a feature to make segments read-only after
|
|
|
|
// processing dynamic relocations to enhance security. PT_GNU_RELRO
|
|
|
|
// is defined for that.
|
|
|
|
//
|
|
|
|
// This function returns true if a section needs to be put into a
|
|
|
|
// PT_GNU_RELRO segment.
|
2017-07-25 07:55:33 +08:00
|
|
|
static bool isRelroSection(const OutputSection *Sec) {
|
2016-02-11 06:43:13 +08:00
|
|
|
if (!Config->ZRelro)
|
|
|
|
return false;
|
2017-02-16 12:51:46 +08:00
|
|
|
|
2016-11-10 07:23:45 +08:00
|
|
|
uint64_t Flags = Sec->Flags;
|
2017-04-13 13:40:07 +08:00
|
|
|
|
|
|
|
// Non-allocatable or non-writable sections don't need RELRO because
|
|
|
|
// they are not writable or not even mapped to memory in the first place.
|
|
|
|
// RELRO is for sections that are essentially read-only but need to
|
|
|
|
// be writable only at process startup to allow dynamic linker to
|
|
|
|
// apply relocations.
|
2015-11-24 18:15:50 +08:00
|
|
|
if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
|
|
|
|
return false;
|
2017-04-13 13:40:07 +08:00
|
|
|
|
|
|
|
// Once initialized, TLS data segments are used as data templates
|
|
|
|
// for a thread-local storage. For each new thread, runtime
|
|
|
|
// allocates memory for a TLS and copy templates there. No thread
|
|
|
|
// are supposed to use templates directly. Thus, it can be in RELRO.
|
2015-12-11 03:13:08 +08:00
|
|
|
if (Flags & SHF_TLS)
|
|
|
|
return true;
|
2017-02-16 12:51:46 +08:00
|
|
|
|
2017-04-13 13:40:07 +08:00
|
|
|
// .init_array, .preinit_array and .fini_array contain pointers to
|
|
|
|
// functions that are executed on process startup or exit. These
|
|
|
|
// pointers are set by the static linker, and they are not expected
|
|
|
|
// to change at runtime. But if you are an attacker, you could do
|
|
|
|
// interesting things by manipulating pointers in .fini_array, for
|
|
|
|
// example. So they are put into RELRO.
|
2016-11-09 09:42:41 +08:00
|
|
|
uint32_t Type = Sec->Type;
|
2015-12-11 03:13:08 +08:00
|
|
|
if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
|
|
|
|
Type == SHT_PREINIT_ARRAY)
|
2015-11-24 18:15:50 +08:00
|
|
|
return true;
|
2017-02-16 12:51:46 +08:00
|
|
|
|
2017-04-13 13:40:07 +08:00
|
|
|
// .got contains pointers to external symbols. They are resolved by
|
|
|
|
// the dynamic linker when a module is loaded into memory, and after
|
|
|
|
// that they are not expected to change. So, it can be in RELRO.
|
2017-06-01 04:17:44 +08:00
|
|
|
if (InX::Got && Sec == InX::Got->getParent())
|
2017-04-13 13:40:07 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// .got.plt contains pointers to external function symbols. They are
|
|
|
|
// by default resolved lazily, so we usually cannot put it into RELRO.
|
|
|
|
// However, if "-z now" is given, the lazy symbol resolution is
|
|
|
|
// disabled, which enables us to put it into RELRO.
|
2017-06-01 04:17:44 +08:00
|
|
|
if (Sec == InX::GotPlt->getParent())
|
2015-11-24 18:15:50 +08:00
|
|
|
return Config->ZNow;
|
2017-04-13 13:40:07 +08:00
|
|
|
|
|
|
|
// .dynamic section contains data for the dynamic linker, and
|
|
|
|
// there's no need to write to it at runtime, so it's better to put
|
|
|
|
// it into RELRO.
|
2017-06-01 04:17:44 +08:00
|
|
|
if (Sec == InX::Dynamic->getParent())
|
2016-11-17 05:01:02 +08:00
|
|
|
return true;
|
2017-04-13 13:40:07 +08:00
|
|
|
|
|
|
|
// Sections with some special names are put into RELRO. This is a
|
|
|
|
// bit unfortunate because section names shouldn't be significant in
|
|
|
|
// ELF in spirit. But in reality many linker features depend on
|
|
|
|
// magic section names.
|
2017-02-24 22:28:00 +08:00
|
|
|
StringRef S = Sec->Name;
|
2017-12-05 19:15:58 +08:00
|
|
|
return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" ||
|
|
|
|
S == ".dtors" || S == ".jcr" || S == ".eh_frame" ||
|
|
|
|
S == ".openbsd.randomdata";
|
2015-11-24 18:15:50 +08:00
|
|
|
}
|
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
// We compute a rank for each section. The rank indicates where the
|
|
|
|
// section should be placed in the file. Instead of using simple
|
|
|
|
// numbers (0,1,2...), we use a series of flags. One for each decision
|
|
|
|
// point when placing the section.
|
|
|
|
// Using flags has two key properties:
|
|
|
|
// * It is easy to check if a give branch was taken.
|
|
|
|
// * It is easy two see how similar two ranks are (see getRankProximity).
|
|
|
|
enum RankFlags {
|
2018-03-01 10:31:29 +08:00
|
|
|
RF_NOT_ADDR_SET = 1 << 18,
|
|
|
|
RF_NOT_INTERP = 1 << 17,
|
|
|
|
RF_NOT_ALLOC = 1 << 16,
|
|
|
|
RF_WRITE = 1 << 15,
|
|
|
|
RF_EXEC_WRITE = 1 << 13,
|
|
|
|
RF_EXEC = 1 << 12,
|
|
|
|
RF_NON_TLS_BSS = 1 << 11,
|
|
|
|
RF_NON_TLS_BSS_RO = 1 << 10,
|
|
|
|
RF_NOT_TLS = 1 << 9,
|
|
|
|
RF_BSS = 1 << 8,
|
|
|
|
RF_NOTE = 1 << 7,
|
2017-05-19 00:20:12 +08:00
|
|
|
RF_PPC_NOT_TOCBSS = 1 << 6,
|
|
|
|
RF_PPC_OPD = 1 << 5,
|
|
|
|
RF_PPC_TOCL = 1 << 4,
|
|
|
|
RF_PPC_TOC = 1 << 3,
|
|
|
|
RF_PPC_BRANCH_LT = 1 << 2,
|
|
|
|
RF_MIPS_GPREL = 1 << 1,
|
|
|
|
RF_MIPS_NOT_GOT = 1 << 0
|
2017-05-12 22:52:22 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static unsigned getSectionRank(const OutputSection *Sec) {
|
|
|
|
unsigned Rank = 0;
|
|
|
|
|
|
|
|
// We want to put section specified by -T option first, so we
|
|
|
|
// can start assigning VA starting from them later.
|
|
|
|
if (Config->SectionStartMap.count(Sec->Name))
|
|
|
|
return Rank;
|
|
|
|
Rank |= RF_NOT_ADDR_SET;
|
|
|
|
|
2016-11-03 02:58:44 +08:00
|
|
|
// Put .interp first because some loaders want to see that section
|
|
|
|
// on the first page of the executable file when loaded into memory.
|
2017-05-12 22:52:22 +08:00
|
|
|
if (Sec->Name == ".interp")
|
|
|
|
return Rank;
|
|
|
|
Rank |= RF_NOT_INTERP;
|
2016-11-03 02:58:44 +08:00
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
// Allocatable sections go first to reduce the total PT_LOAD size and
|
|
|
|
// so debug info doesn't change addresses in actual code.
|
2017-05-12 22:52:22 +08:00
|
|
|
if (!(Sec->Flags & SHF_ALLOC))
|
|
|
|
return Rank | RF_NOT_ALLOC;
|
2016-12-20 05:21:07 +08:00
|
|
|
|
2017-05-27 01:23:25 +08:00
|
|
|
// Sort sections based on their access permission in the following
|
|
|
|
// order: R, RX, RWX, RW. This order is based on the following
|
|
|
|
// considerations:
|
|
|
|
// * Read-only sections come first such that they go in the
|
|
|
|
// PT_LOAD covering the program headers at the start of the file.
|
|
|
|
// * Read-only, executable sections come next, unless the
|
|
|
|
// -no-rosegment option is used.
|
|
|
|
// * Writable, executable sections follow such that .plt on
|
|
|
|
// architectures where it needs to be writable will be placed
|
|
|
|
// between .text and .data.
|
|
|
|
// * Writable sections come last, such that .bss lands at the very
|
|
|
|
// end of the last PT_LOAD.
|
|
|
|
bool IsExec = Sec->Flags & SHF_EXECINSTR;
|
|
|
|
bool IsWrite = Sec->Flags & SHF_WRITE;
|
|
|
|
|
|
|
|
if (IsExec) {
|
|
|
|
if (IsWrite)
|
|
|
|
Rank |= RF_EXEC_WRITE;
|
|
|
|
else if (!Config->SingleRoRx)
|
2017-05-12 22:52:22 +08:00
|
|
|
Rank |= RF_EXEC;
|
2017-05-27 01:23:25 +08:00
|
|
|
} else {
|
|
|
|
if (IsWrite)
|
|
|
|
Rank |= RF_WRITE;
|
2016-09-30 06:48:55 +08:00
|
|
|
}
|
2015-10-09 07:49:30 +08:00
|
|
|
|
2015-10-14 01:57:46 +08:00
|
|
|
// If we got here we know that both A and B are in the same PT_LOAD.
|
2015-10-17 07:11:07 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
bool IsTls = Sec->Flags & SHF_TLS;
|
|
|
|
bool IsNoBits = Sec->Type == SHT_NOBITS;
|
2015-10-13 04:51:48 +08:00
|
|
|
|
2017-01-10 09:21:30 +08:00
|
|
|
// The first requirement we have is to put (non-TLS) nobits sections last. The
|
|
|
|
// reason is that the only thing the dynamic linker will see about them is a
|
|
|
|
// p_memsz that is larger than p_filesz. Seeing that it zeros the end of the
|
|
|
|
// PT_LOAD, so that has to correspond to the nobits sections.
|
2017-05-12 22:52:22 +08:00
|
|
|
bool IsNonTlsNoBits = IsNoBits && !IsTls;
|
|
|
|
if (IsNonTlsNoBits)
|
|
|
|
Rank |= RF_NON_TLS_BSS;
|
2017-01-10 09:21:30 +08:00
|
|
|
|
|
|
|
// We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo
|
|
|
|
// sections after r/w ones, so that the RelRo sections are contiguous.
|
2017-05-12 22:52:22 +08:00
|
|
|
bool IsRelRo = isRelroSection(Sec);
|
|
|
|
if (IsNonTlsNoBits && !IsRelRo)
|
|
|
|
Rank |= RF_NON_TLS_BSS_RO;
|
|
|
|
if (!IsNonTlsNoBits && IsRelRo)
|
|
|
|
Rank |= RF_NON_TLS_BSS_RO;
|
2017-01-10 09:21:30 +08:00
|
|
|
|
|
|
|
// The TLS initialization block needs to be a single contiguous block in a R/W
|
|
|
|
// PT_LOAD, so stick TLS sections directly before the other RelRo R/W
|
|
|
|
// sections. The TLS NOBITS sections are placed here as they don't take up
|
|
|
|
// virtual address space in the PT_LOAD.
|
2017-05-12 22:52:22 +08:00
|
|
|
if (!IsTls)
|
|
|
|
Rank |= RF_NOT_TLS;
|
2017-01-10 09:21:30 +08:00
|
|
|
|
|
|
|
// Within the TLS initialization block, the non-nobits sections need to appear
|
|
|
|
// first.
|
2017-05-12 22:52:22 +08:00
|
|
|
if (IsNoBits)
|
|
|
|
Rank |= RF_BSS;
|
|
|
|
|
2018-03-01 10:31:29 +08:00
|
|
|
// We create a NOTE segment for contiguous .note sections, so make
|
|
|
|
// them contigous if there are more than one .note section with the
|
|
|
|
// same attributes.
|
|
|
|
if (Sec->Type == SHT_NOTE)
|
|
|
|
Rank |= RF_NOTE;
|
|
|
|
|
2017-08-19 00:15:36 +08:00
|
|
|
// Some architectures have additional ordering restrictions for sections
|
|
|
|
// within the same PT_LOAD.
|
2017-05-12 22:52:22 +08:00
|
|
|
if (Config->EMachine == EM_PPC64) {
|
|
|
|
// PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections
|
|
|
|
// that we would like to make sure appear is a specific order to maximize
|
|
|
|
// their coverage by a single signed 16-bit offset from the TOC base
|
|
|
|
// pointer. Conversely, the special .tocbss section should be first among
|
|
|
|
// all SHT_NOBITS sections. This will put it next to the loaded special
|
|
|
|
// PPC64 sections (and, thus, within reach of the TOC base pointer).
|
|
|
|
StringRef Name = Sec->Name;
|
|
|
|
if (Name != ".tocbss")
|
|
|
|
Rank |= RF_PPC_NOT_TOCBSS;
|
|
|
|
|
|
|
|
if (Name == ".opd")
|
|
|
|
Rank |= RF_PPC_OPD;
|
|
|
|
|
|
|
|
if (Name == ".toc1")
|
|
|
|
Rank |= RF_PPC_TOCL;
|
|
|
|
|
|
|
|
if (Name == ".toc")
|
|
|
|
Rank |= RF_PPC_TOC;
|
|
|
|
|
|
|
|
if (Name == ".branch_lt")
|
|
|
|
Rank |= RF_PPC_BRANCH_LT;
|
|
|
|
}
|
2018-03-01 10:31:29 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
|
|
|
// All sections with SHF_MIPS_GPREL flag should be grouped together
|
|
|
|
// because data in these sections is addressable with a gp relative address.
|
|
|
|
if (Sec->Flags & SHF_MIPS_GPREL)
|
|
|
|
Rank |= RF_MIPS_GPREL;
|
2015-11-24 18:15:50 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
if (Sec->Name != ".got")
|
|
|
|
Rank |= RF_MIPS_NOT_GOT;
|
|
|
|
}
|
2015-10-14 03:07:29 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
return Rank;
|
|
|
|
}
|
|
|
|
|
2017-06-16 05:51:01 +08:00
|
|
|
static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
|
2017-07-28 03:22:43 +08:00
|
|
|
const OutputSection *A = cast<OutputSection>(ACmd);
|
|
|
|
const OutputSection *B = cast<OutputSection>(BCmd);
|
2017-05-12 22:52:22 +08:00
|
|
|
if (A->SortRank != B->SortRank)
|
|
|
|
return A->SortRank < B->SortRank;
|
|
|
|
if (!(A->SortRank & RF_NOT_ADDR_SET))
|
|
|
|
return Config->SectionStartMap.lookup(A->Name) <
|
|
|
|
Config->SectionStartMap.lookup(B->Name);
|
2016-09-22 06:36:19 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-02-24 23:07:30 +08:00
|
|
|
void PhdrEntry::add(OutputSection *Sec) {
|
2017-09-07 19:01:10 +08:00
|
|
|
LastSec = Sec;
|
|
|
|
if (!FirstSec)
|
|
|
|
FirstSec = Sec;
|
2017-03-07 22:55:52 +08:00
|
|
|
p_align = std::max(p_align, Sec->Alignment);
|
2016-12-20 01:01:01 +08:00
|
|
|
if (p_type == PT_LOAD)
|
2017-09-07 18:53:07 +08:00
|
|
|
Sec->PtLoad = this;
|
2016-07-19 17:25:43 +08:00
|
|
|
}
|
|
|
|
|
2015-12-26 17:47:57 +08:00
|
|
|
// The beginning and the ending of .rel[a].plt section are marked
|
|
|
|
// with __rel[a]_iplt_{start,end} symbols if it is a statically linked
|
|
|
|
// executable. The runtime needs these symbols in order to resolve
|
|
|
|
// all IRELATIVE relocs on startup. For dynamic executables, we don't
|
|
|
|
// need these symbols, since IRELATIVE relocs are resolved through GOT
|
|
|
|
// and PLT. For details, see http://www.airs.com/blog/archives/403.
|
2016-04-14 21:23:02 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
|
2018-02-07 06:59:24 +08:00
|
|
|
if (needsInterpSection())
|
2015-12-21 18:12:06 +08:00
|
|
|
return;
|
2017-03-18 07:29:01 +08:00
|
|
|
StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
|
2017-12-24 01:21:39 +08:00
|
|
|
addOptionalRegular(S, InX::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
|
2015-12-26 17:47:57 +08:00
|
|
|
|
2017-03-18 07:29:01 +08:00
|
|
|
S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
|
2017-12-24 01:21:39 +08:00
|
|
|
addOptionalRegular(S, InX::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
|
2015-12-21 18:12:06 +08:00
|
|
|
}
|
|
|
|
|
2016-07-21 01:58:07 +08:00
|
|
|
template <class ELFT>
|
2017-02-23 10:28:28 +08:00
|
|
|
void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) {
|
2017-09-13 15:54:47 +08:00
|
|
|
// Scan all relocations. Each relocation goes through a series
|
|
|
|
// of tests to determine if it needs special treatment, such as
|
|
|
|
// creating GOT, PLT, copy relocations, etc.
|
|
|
|
// Note that relocations for non-alloc sections are directly
|
|
|
|
// processed by InputSection::relocateNonAlloc.
|
|
|
|
for (InputSectionBase *IS : InputSections)
|
|
|
|
if (IS->Live && isa<InputSection>(IS) && (IS->Flags & SHF_ALLOC))
|
2016-11-10 22:53:24 +08:00
|
|
|
Fn(*IS);
|
2017-10-27 11:13:39 +08:00
|
|
|
for (EhInputSection *ES : InX::EhFrame->Sections)
|
2017-09-13 15:54:47 +08:00
|
|
|
Fn(*ES);
|
2016-07-21 01:58:07 +08:00
|
|
|
}
|
|
|
|
|
2017-09-01 10:23:31 +08:00
|
|
|
// This function generates assignments for predefined symbols (e.g. _end or
|
|
|
|
// _etext) and inserts them into the commands sequence to be processed at the
|
|
|
|
// appropriate time. This ensures that the value is going to be correct by the
|
|
|
|
// time any references to these symbols are processed and is equivalent to
|
|
|
|
// defining these symbols explicitly in the linker script.
|
2017-09-13 00:38:01 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
|
2017-12-12 01:23:28 +08:00
|
|
|
if (ElfSym::GlobalOffsetTable) {
|
2018-03-19 14:52:51 +08:00
|
|
|
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
|
|
|
|
// to the start of the .got or .got.plt section.
|
|
|
|
InputSection *GotSection = InX::GotPlt;
|
|
|
|
if (!Target->GotBaseSymInGotPlt)
|
|
|
|
GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
|
|
|
|
: cast<InputSection>(InX::Got);
|
2017-12-12 01:23:28 +08:00
|
|
|
ElfSym::GlobalOffsetTable->Section = GotSection;
|
|
|
|
}
|
|
|
|
|
2017-09-01 10:23:31 +08:00
|
|
|
PhdrEntry *Last = nullptr;
|
|
|
|
PhdrEntry *LastRO = nullptr;
|
2017-09-06 04:17:37 +08:00
|
|
|
|
2017-09-01 10:23:31 +08:00
|
|
|
for (PhdrEntry *P : Phdrs) {
|
|
|
|
if (P->p_type != PT_LOAD)
|
|
|
|
continue;
|
|
|
|
Last = P;
|
2017-11-03 19:51:58 +08:00
|
|
|
if (!(P->p_flags & PF_W))
|
2017-09-01 10:23:31 +08:00
|
|
|
LastRO = P;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LastRO) {
|
2017-10-30 06:31:48 +08:00
|
|
|
// _etext is the first location after the last read-only loadable segment.
|
2017-09-13 00:38:01 +08:00
|
|
|
if (ElfSym::Etext1)
|
|
|
|
ElfSym::Etext1->Section = LastRO->LastSec;
|
|
|
|
if (ElfSym::Etext2)
|
|
|
|
ElfSym::Etext2->Section = LastRO->LastSec;
|
2017-09-01 10:23:31 +08:00
|
|
|
}
|
2017-09-06 04:17:37 +08:00
|
|
|
|
2017-10-30 06:31:48 +08:00
|
|
|
if (Last) {
|
|
|
|
// _edata points to the end of the last mapped initialized section.
|
|
|
|
OutputSection *Edata = nullptr;
|
|
|
|
for (OutputSection *OS : OutputSections) {
|
|
|
|
if (OS->Type != SHT_NOBITS)
|
|
|
|
Edata = OS;
|
|
|
|
if (OS == Last->LastSec)
|
2017-10-17 22:31:29 +08:00
|
|
|
break;
|
2017-10-30 06:31:48 +08:00
|
|
|
}
|
2017-10-17 22:31:29 +08:00
|
|
|
|
2017-09-13 00:38:01 +08:00
|
|
|
if (ElfSym::Edata1)
|
2017-10-30 06:31:48 +08:00
|
|
|
ElfSym::Edata1->Section = Edata;
|
2017-09-13 00:38:01 +08:00
|
|
|
if (ElfSym::Edata2)
|
2017-10-30 06:31:48 +08:00
|
|
|
ElfSym::Edata2->Section = Edata;
|
|
|
|
|
|
|
|
// _end is the first location after the uninitialized data region.
|
|
|
|
if (ElfSym::End1)
|
|
|
|
ElfSym::End1->Section = Last->LastSec;
|
|
|
|
if (ElfSym::End2)
|
|
|
|
ElfSym::End2->Section = Last->LastSec;
|
2017-09-13 00:38:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ElfSym::Bss)
|
|
|
|
ElfSym::Bss->Section = findSection(".bss");
|
|
|
|
|
|
|
|
// Setup MIPS _gp_disp/__gnu_local_gp symbols which should
|
|
|
|
// be equal to the _gp symbol's value.
|
2017-09-21 02:30:57 +08:00
|
|
|
if (ElfSym::MipsGp) {
|
2017-09-13 00:38:01 +08:00
|
|
|
// Find GP-relative section with the lowest address
|
|
|
|
// and use this address to calculate default _gp value.
|
|
|
|
for (OutputSection *OS : OutputSections) {
|
|
|
|
if (OS->Flags & SHF_MIPS_GPREL) {
|
|
|
|
ElfSym::MipsGp->Section = OS;
|
|
|
|
ElfSym::MipsGp->Value = 0x7ff0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-09-01 10:23:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
// We want to find how similar two ranks are.
|
|
|
|
// The more branches in getSectionRank that match, the more similar they are.
|
|
|
|
// Since each branch corresponds to a bit flag, we can just use
|
|
|
|
// countLeadingZeros.
|
2017-07-28 03:22:43 +08:00
|
|
|
static int getRankProximityAux(OutputSection *A, OutputSection *B) {
|
2017-05-12 22:52:22 +08:00
|
|
|
return countLeadingZeros(A->SortRank ^ B->SortRank);
|
2016-11-08 18:44:48 +08:00
|
|
|
}
|
|
|
|
|
2017-06-16 05:51:01 +08:00
|
|
|
static int getRankProximity(OutputSection *A, BaseCommand *B) {
|
2017-07-28 03:22:43 +08:00
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(B))
|
2018-02-23 18:53:04 +08:00
|
|
|
return getRankProximityAux(A, Sec);
|
2017-06-16 05:51:01 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 findOrphanPos is the
|
|
|
|
// one in charge of deciding the order of the sections.
|
|
|
|
// We don't want to go over changes to '.', 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(BaseCommand *Cmd) {
|
2017-07-28 03:22:43 +08:00
|
|
|
if (isa<OutputSection>(Cmd))
|
2017-06-16 05:51:01 +08:00
|
|
|
return false;
|
|
|
|
if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
|
|
|
|
return Assign->Name != ".";
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
// We want to place orphan sections so that they share as much
|
|
|
|
// characteristics with their neighbors as possible. For example, if
|
|
|
|
// both are rw, or both are tls.
|
2017-05-09 21:58:46 +08:00
|
|
|
template <typename ELFT>
|
2017-06-16 05:51:01 +08:00
|
|
|
static std::vector<BaseCommand *>::iterator
|
|
|
|
findOrphanPos(std::vector<BaseCommand *>::iterator B,
|
|
|
|
std::vector<BaseCommand *>::iterator E) {
|
2017-07-28 03:22:43 +08:00
|
|
|
OutputSection *Sec = cast<OutputSection>(*E);
|
2017-05-09 21:58:46 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
// Find the first element that has as close a rank as possible.
|
2017-06-16 05:51:01 +08:00
|
|
|
auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) {
|
2017-05-12 22:52:22 +08:00
|
|
|
return getRankProximity(Sec, A) < getRankProximity(Sec, B);
|
|
|
|
});
|
|
|
|
if (I == E)
|
2017-05-09 21:58:46 +08:00
|
|
|
return E;
|
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
// Consider all existing sections with the same proximity.
|
2017-06-16 05:51:01 +08:00
|
|
|
int Proximity = getRankProximity(Sec, *I);
|
|
|
|
for (; I != E; ++I) {
|
2017-07-28 03:22:43 +08:00
|
|
|
auto *CurSec = dyn_cast<OutputSection>(*I);
|
2018-02-23 18:53:04 +08:00
|
|
|
if (!CurSec)
|
2017-06-16 05:51:01 +08:00
|
|
|
continue;
|
2017-07-28 03:22:43 +08:00
|
|
|
if (getRankProximity(Sec, CurSec) != Proximity ||
|
|
|
|
Sec->SortRank < CurSec->SortRank)
|
2017-06-16 05:51:01 +08:00
|
|
|
break;
|
|
|
|
}
|
2017-10-23 08:51:08 +08:00
|
|
|
|
2018-02-23 18:53:04 +08:00
|
|
|
auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); };
|
2017-10-10 18:05:52 +08:00
|
|
|
auto J = std::find_if(llvm::make_reverse_iterator(I),
|
2018-02-23 18:53:04 +08:00
|
|
|
llvm::make_reverse_iterator(B), IsOutputSec);
|
2017-06-16 05:51:01 +08:00
|
|
|
I = J.base();
|
2017-09-20 01:29:58 +08:00
|
|
|
|
|
|
|
// As a special case, if the orphan section is the last section, put
|
|
|
|
// it at the very end, past any other commands.
|
|
|
|
// This matches bfd's behavior and is convenient when the linker script fully
|
|
|
|
// specifies the start of the file, but doesn't care about the end (the non
|
|
|
|
// alloc sections for example).
|
2018-02-23 18:53:04 +08:00
|
|
|
auto NextSec = std::find_if(I, E, IsOutputSec);
|
2017-09-20 01:29:58 +08:00
|
|
|
if (NextSec == E)
|
|
|
|
return E;
|
|
|
|
|
2017-06-16 05:51:01 +08:00
|
|
|
while (I != E && shouldSkip(*I))
|
2017-05-12 22:52:22 +08:00
|
|
|
++I;
|
|
|
|
return I;
|
2017-05-09 21:58:46 +08:00
|
|
|
}
|
|
|
|
|
2018-01-31 00:24:04 +08:00
|
|
|
// Builds section order for handling --symbol-ordering-file.
|
2018-02-14 09:42:26 +08:00
|
|
|
static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
|
|
|
|
DenseMap<const InputSectionBase *, int> SectionOrder;
|
2018-01-31 00:24:04 +08:00
|
|
|
if (Config->SymbolOrderingFile.empty())
|
|
|
|
return SectionOrder;
|
|
|
|
|
2018-02-14 21:36:22 +08:00
|
|
|
struct SymbolOrderEntry {
|
|
|
|
int Priority;
|
|
|
|
bool Present;
|
|
|
|
};
|
|
|
|
|
2018-01-31 00:24:04 +08:00
|
|
|
// Build a map from symbols to their priorities. Symbols that didn't
|
|
|
|
// appear in the symbol ordering file have the lowest priority 0.
|
|
|
|
// All explicitly mentioned symbols have negative (higher) priorities.
|
2018-02-14 21:36:22 +08:00
|
|
|
DenseMap<StringRef, SymbolOrderEntry> SymbolOrder;
|
2018-01-31 00:24:04 +08:00
|
|
|
int Priority = -Config->SymbolOrderingFile.size();
|
|
|
|
for (StringRef S : Config->SymbolOrderingFile)
|
2018-02-14 21:36:22 +08:00
|
|
|
SymbolOrder.insert({S, {Priority++, false}});
|
2018-01-31 00:24:04 +08:00
|
|
|
|
|
|
|
// Build a map from sections to their priorities.
|
2018-04-06 11:36:19 +08:00
|
|
|
auto AddSym = [&](Symbol &Sym) {
|
|
|
|
auto It = SymbolOrder.find(Sym.getName());
|
|
|
|
if (It == SymbolOrder.end())
|
|
|
|
return;
|
|
|
|
SymbolOrderEntry &Ent = It->second;
|
|
|
|
Ent.Present = true;
|
|
|
|
|
|
|
|
if (Config->WarnSymbolOrdering) {
|
|
|
|
auto *D = dyn_cast<Defined>(&Sym);
|
|
|
|
InputFile *File = Sym.File;
|
|
|
|
if (Sym.isUndefined())
|
2018-04-10 17:44:44 +08:00
|
|
|
warn(toString(File) +
|
2018-04-06 11:36:19 +08:00
|
|
|
": unable to order undefined symbol: " + Sym.getName());
|
|
|
|
else if (Sym.isShared())
|
2018-04-10 17:44:44 +08:00
|
|
|
warn(toString(File) +
|
2018-04-06 11:36:19 +08:00
|
|
|
": unable to order shared symbol: " + Sym.getName());
|
|
|
|
else if (D && !D->Section)
|
2018-04-10 17:44:44 +08:00
|
|
|
warn(toString(File) +
|
2018-04-06 11:36:19 +08:00
|
|
|
": unable to order absolute symbol: " + Sym.getName());
|
2018-04-11 05:13:52 +08:00
|
|
|
else if (D && isa<OutputSection>(D->Section))
|
|
|
|
warn(toString(File) +
|
|
|
|
": unable to order synthetic symbol: " + Sym.getName());
|
|
|
|
else if (D && !D->Section->Repl->Live)
|
2018-04-10 17:44:44 +08:00
|
|
|
warn(toString(File) +
|
2018-04-06 11:36:19 +08:00
|
|
|
": unable to order discarded symbol: " + Sym.getName());
|
|
|
|
}
|
2018-02-14 21:36:22 +08:00
|
|
|
|
2018-04-06 11:36:19 +08:00
|
|
|
if (auto *D = dyn_cast<Defined>(&Sym)) {
|
2018-03-08 01:24:46 +08:00
|
|
|
if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
|
|
|
|
int &Priority = SectionOrder[cast<InputSectionBase>(Sec->Repl)];
|
|
|
|
Priority = std::min(Priority, Ent.Priority);
|
2018-02-14 09:42:26 +08:00
|
|
|
}
|
2018-01-31 00:24:04 +08:00
|
|
|
}
|
2018-04-06 11:36:19 +08:00
|
|
|
};
|
|
|
|
// We want both global and local symbols. We get the global ones from the
|
|
|
|
// symbol table and iterate the object files for the local ones.
|
|
|
|
for (Symbol *Sym : Symtab->getSymbols())
|
|
|
|
if (!Sym->isLazy())
|
|
|
|
AddSym(*Sym);
|
|
|
|
for (InputFile *File : ObjectFiles)
|
|
|
|
for (Symbol *Sym : File->getSymbols())
|
|
|
|
if (Sym->isLocal())
|
|
|
|
AddSym(*Sym);
|
2018-02-14 21:36:22 +08:00
|
|
|
|
|
|
|
if (Config->WarnSymbolOrdering)
|
|
|
|
for (auto OrderEntry : SymbolOrder)
|
|
|
|
if (!OrderEntry.second.Present)
|
|
|
|
warn("symbol ordering file: no such symbol: " + OrderEntry.first);
|
|
|
|
|
2018-01-31 00:24:04 +08:00
|
|
|
return SectionOrder;
|
|
|
|
}
|
|
|
|
|
2018-03-31 05:36:54 +08:00
|
|
|
// Sorts the sections in ISD according to the provided section order.
|
|
|
|
static void
|
|
|
|
sortISDBySectionOrder(InputSectionDescription *ISD,
|
|
|
|
const DenseMap<const InputSectionBase *, int> &Order) {
|
|
|
|
std::vector<InputSection *> UnorderedSections;
|
2018-04-04 03:45:10 +08:00
|
|
|
std::vector<std::pair<InputSection *, int>> OrderedSections;
|
2018-03-31 05:36:54 +08:00
|
|
|
uint64_t UnorderedSize = 0;
|
|
|
|
|
|
|
|
for (InputSection *IS : ISD->Sections) {
|
2018-04-04 03:45:10 +08:00
|
|
|
auto I = Order.find(IS);
|
|
|
|
if (I == Order.end()) {
|
2018-03-31 05:36:54 +08:00
|
|
|
UnorderedSections.push_back(IS);
|
|
|
|
UnorderedSize += IS->getSize();
|
|
|
|
continue;
|
|
|
|
}
|
2018-04-04 03:45:10 +08:00
|
|
|
OrderedSections.push_back({IS, I->second});
|
2018-03-31 05:36:54 +08:00
|
|
|
}
|
2018-04-04 03:45:10 +08:00
|
|
|
std::sort(
|
|
|
|
OrderedSections.begin(), OrderedSections.end(),
|
|
|
|
[&](std::pair<InputSection *, int> A, std::pair<InputSection *, int> B) {
|
|
|
|
return A.second < B.second;
|
|
|
|
});
|
2018-03-31 05:36:54 +08:00
|
|
|
|
|
|
|
// Find an insertion point for the ordered section list in the unordered
|
|
|
|
// section list. On targets with limited-range branches, this is the mid-point
|
|
|
|
// of the unordered section list. This decreases the likelihood that a range
|
|
|
|
// extension thunk will be needed to enter or exit the ordered region. If the
|
|
|
|
// ordered section list is a list of hot functions, we can generally expect
|
|
|
|
// the ordered functions to be called more often than the unordered functions,
|
|
|
|
// making it more likely that any particular call will be within range, and
|
|
|
|
// therefore reducing the number of thunks required.
|
|
|
|
//
|
|
|
|
// For example, imagine that you have 8MB of hot code and 32MB of cold code.
|
|
|
|
// If the layout is:
|
|
|
|
//
|
|
|
|
// 8MB hot
|
|
|
|
// 32MB cold
|
|
|
|
//
|
|
|
|
// only the first 8-16MB of the cold code (depending on which hot function it
|
|
|
|
// is actually calling) can call the hot code without a range extension thunk.
|
|
|
|
// However, if we use this layout:
|
|
|
|
//
|
|
|
|
// 16MB cold
|
|
|
|
// 8MB hot
|
|
|
|
// 16MB cold
|
|
|
|
//
|
|
|
|
// both the last 8-16MB of the first block of cold code and the first 8-16MB
|
|
|
|
// of the second block of cold code can call the hot code without a thunk. So
|
|
|
|
// we effectively double the amount of code that could potentially call into
|
|
|
|
// the hot code without a thunk.
|
2018-04-04 04:08:45 +08:00
|
|
|
size_t InsPt = 0;
|
2018-03-31 05:36:54 +08:00
|
|
|
if (Target->ThunkSectionSpacing && !OrderedSections.empty()) {
|
|
|
|
uint64_t UnorderedPos = 0;
|
2018-04-04 04:08:45 +08:00
|
|
|
for (; InsPt != UnorderedSections.size(); ++InsPt) {
|
|
|
|
UnorderedPos += UnorderedSections[InsPt]->getSize();
|
2018-03-31 05:36:54 +08:00
|
|
|
if (UnorderedPos > UnorderedSize / 2)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-04 04:08:45 +08:00
|
|
|
ISD->Sections.clear();
|
|
|
|
for (InputSection *IS : makeArrayRef(UnorderedSections).slice(0, InsPt))
|
|
|
|
ISD->Sections.push_back(IS);
|
2018-04-04 03:45:10 +08:00
|
|
|
for (std::pair<InputSection *, int> P : OrderedSections)
|
2018-04-04 04:08:45 +08:00
|
|
|
ISD->Sections.push_back(P.first);
|
|
|
|
for (InputSection *IS : makeArrayRef(UnorderedSections).slice(InsPt))
|
|
|
|
ISD->Sections.push_back(IS);
|
2018-03-31 05:36:54 +08:00
|
|
|
}
|
|
|
|
|
2018-02-10 00:09:22 +08:00
|
|
|
static void sortSection(OutputSection *Sec,
|
2018-02-14 09:42:26 +08:00
|
|
|
const DenseMap<const InputSectionBase *, int> &Order) {
|
2018-02-10 00:09:22 +08:00
|
|
|
StringRef Name = Sec->Name;
|
2018-01-31 00:20:08 +08:00
|
|
|
|
2017-10-30 18:12:49 +08:00
|
|
|
// Sort input sections by section name suffixes for
|
|
|
|
// __attribute__((init_priority(N))).
|
2018-02-10 00:09:22 +08:00
|
|
|
if (Name == ".init_array" || Name == ".fini_array") {
|
|
|
|
if (!Script->HasSectionsCommand)
|
|
|
|
Sec->sortInitFini();
|
|
|
|
return;
|
|
|
|
}
|
2017-10-30 18:12:49 +08:00
|
|
|
|
|
|
|
// Sort input sections by the special rule for .ctors and .dtors.
|
2018-02-10 00:09:22 +08:00
|
|
|
if (Name == ".ctors" || Name == ".dtors") {
|
|
|
|
if (!Script->HasSectionsCommand)
|
|
|
|
Sec->sortCtorsDtors();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Never sort these.
|
|
|
|
if (Name == ".init" || Name == ".fini")
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Sort input sections by priority using the list provided
|
|
|
|
// by --symbol-ordering-file.
|
|
|
|
if (!Order.empty())
|
2018-03-31 05:36:54 +08:00
|
|
|
for (BaseCommand *B : Sec->SectionCommands)
|
|
|
|
if (auto *ISD = dyn_cast<InputSectionDescription>(B))
|
|
|
|
sortISDBySectionOrder(ISD, Order);
|
2018-02-10 00:09:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If no layout was provided by linker script, we want to apply default
|
|
|
|
// sorting for special input sections. This also handles --symbol-ordering-file.
|
|
|
|
template <class ELFT> void Writer<ELFT>::sortInputSections() {
|
|
|
|
// Build the order once since it is expensive.
|
2018-02-14 09:42:26 +08:00
|
|
|
DenseMap<const InputSectionBase *, int> Order = buildSectionOrder();
|
2018-02-10 00:09:22 +08:00
|
|
|
for (BaseCommand *Base : Script->SectionCommands)
|
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
|
|
|
sortSection(Sec, Order);
|
2017-10-30 18:12:49 +08:00
|
|
|
}
|
|
|
|
|
2016-09-22 06:36:19 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::sortSections() {
|
2017-10-02 17:11:13 +08:00
|
|
|
Script->adjustSectionsBeforeSorting();
|
2017-06-28 17:59:34 +08:00
|
|
|
|
2016-11-12 06:43:27 +08:00
|
|
|
// Don't sort if using -r. It is not necessary and we want to preserve the
|
|
|
|
// relative order for SHF_LINK_ORDER sections.
|
|
|
|
if (Config->Relocatable)
|
2017-06-29 06:44:11 +08:00
|
|
|
return;
|
2017-05-12 22:52:22 +08:00
|
|
|
|
2018-01-31 00:20:08 +08:00
|
|
|
sortInputSections();
|
2017-10-30 18:12:49 +08:00
|
|
|
|
2018-04-09 21:01:50 +08:00
|
|
|
for (BaseCommand *Base : Script->SectionCommands) {
|
|
|
|
auto *OS = dyn_cast<OutputSection>(Base);
|
|
|
|
if (!OS)
|
|
|
|
continue;
|
|
|
|
OS->SortRank = getSectionRank(OS);
|
|
|
|
|
|
|
|
// We want to assign rude approximation values to OutSecOff fields
|
|
|
|
// to know the relative order of the input sections. We use it for
|
|
|
|
// sorting SHF_LINK_ORDER sections. See resolveShfLinkOrder().
|
|
|
|
uint64_t I = 0;
|
|
|
|
for (InputSection *Sec : getInputSections(OS))
|
|
|
|
Sec->OutSecOff = I++;
|
|
|
|
}
|
|
|
|
|
2018-01-31 00:20:08 +08:00
|
|
|
if (!Script->HasSectionsCommand) {
|
2017-10-30 18:12:49 +08:00
|
|
|
// We know that all the OutputSections are contiguous in this case.
|
2017-07-28 03:22:43 +08:00
|
|
|
auto IsSection = [](BaseCommand *Base) { return isa<OutputSection>(Base); };
|
2018-04-11 17:03:02 +08:00
|
|
|
std::stable_sort(
|
|
|
|
llvm::find_if(Script->SectionCommands, IsSection),
|
|
|
|
llvm::find_if(llvm::reverse(Script->SectionCommands), IsSection).base(),
|
|
|
|
compareSections);
|
2016-09-22 06:36:19 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-16 05:51:01 +08:00
|
|
|
// Orphan sections are sections present in the input files which are
|
|
|
|
// not explicitly placed into the output file by the linker script.
|
|
|
|
//
|
|
|
|
// The sections in the linker script are already in the correct
|
|
|
|
// order. We have to figuere out where to insert the orphan
|
|
|
|
// sections.
|
|
|
|
//
|
2016-09-22 06:36:19 +08:00
|
|
|
// The order of the sections in the script is arbitrary and may not agree with
|
2017-06-16 05:51:01 +08:00
|
|
|
// compareSections. This means that we cannot easily define a strict weak
|
|
|
|
// ordering. To see why, consider a comparison of a section in the script and
|
|
|
|
// one not in the script. We have a two simple options:
|
2016-09-22 06:36:19 +08:00
|
|
|
// * Make them equivalent (a is not less than b, and b is not less than a).
|
|
|
|
// The problem is then that equivalence has to be transitive and we can
|
|
|
|
// have sections a, b and c with only b in a script and a less than c
|
|
|
|
// which breaks this property.
|
|
|
|
// * Use compareSectionsNonScript. Given that the script order doesn't have
|
|
|
|
// to match, we can end up with sections a, b, c, d where b and c are in the
|
|
|
|
// script and c is compareSectionsNonScript less than b. In which case d
|
|
|
|
// can be equivalent to c, a to b and d < a. As a concrete example:
|
|
|
|
// .a (rx) # not in script
|
|
|
|
// .b (rx) # in script
|
|
|
|
// .c (ro) # in script
|
|
|
|
// .d (ro) # not in script
|
|
|
|
//
|
|
|
|
// The way we define an order then is:
|
2017-06-16 05:51:01 +08:00
|
|
|
// * Sort only the orphan sections. They are in the end right now.
|
|
|
|
// * Move each orphan section to its preferred position. We try
|
2018-02-23 10:05:48 +08:00
|
|
|
// to put each section in the last position where it can share
|
2016-11-08 18:44:48 +08:00
|
|
|
// a PT_LOAD.
|
2017-06-16 05:51:01 +08:00
|
|
|
//
|
|
|
|
// There is some ambiguity as to where exactly a new entry should be
|
2017-10-11 09:19:33 +08:00
|
|
|
// inserted, because Commands contains not only output section
|
2017-06-16 05:51:01 +08:00
|
|
|
// commands but also other types of commands such as symbol assignment
|
|
|
|
// expressions. There's no correct answer here due to the lack of the
|
|
|
|
// formal specification of the linker script. We use heuristics to
|
|
|
|
// determine whether a new output command should be added before or
|
|
|
|
// after another commands. For the details, look at shouldSkip
|
|
|
|
// function.
|
|
|
|
|
2017-10-11 09:50:56 +08:00
|
|
|
auto I = Script->SectionCommands.begin();
|
|
|
|
auto E = Script->SectionCommands.end();
|
2017-06-16 05:51:01 +08:00
|
|
|
auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
|
2017-07-28 03:22:43 +08:00
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
2018-03-08 03:25:36 +08:00
|
|
|
return Sec->SectionIndex == UINT32_MAX;
|
2017-06-16 05:51:01 +08:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
// Sort the orphan sections.
|
|
|
|
std::stable_sort(NonScriptI, E, compareSections);
|
2016-09-22 06:36:19 +08:00
|
|
|
|
2017-06-16 05:51:01 +08:00
|
|
|
// As a horrible special case, skip the first . assignment if it is before any
|
|
|
|
// section. We do this because it is common to set a load address by starting
|
|
|
|
// the script with ". = 0xabcd" and the expectation is that every section is
|
|
|
|
// after that.
|
|
|
|
auto FirstSectionOrDotAssignment =
|
|
|
|
std::find_if(I, E, [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
|
|
|
|
if (FirstSectionOrDotAssignment != E &&
|
|
|
|
isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
|
|
|
|
++FirstSectionOrDotAssignment;
|
|
|
|
I = FirstSectionOrDotAssignment;
|
2016-09-22 06:36:19 +08:00
|
|
|
|
2017-05-12 22:52:22 +08:00
|
|
|
while (NonScriptI != E) {
|
|
|
|
auto Pos = findOrphanPos<ELFT>(I, NonScriptI);
|
2017-07-28 03:22:43 +08:00
|
|
|
OutputSection *Orphan = cast<OutputSection>(*NonScriptI);
|
2017-05-12 22:52:22 +08:00
|
|
|
|
|
|
|
// As an optimization, find all sections with the same sort rank
|
|
|
|
// and insert them with one rotate.
|
2017-06-16 05:51:01 +08:00
|
|
|
unsigned Rank = Orphan->SortRank;
|
|
|
|
auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) {
|
2017-07-28 03:22:43 +08:00
|
|
|
return cast<OutputSection>(Cmd)->SortRank != Rank;
|
2017-05-12 22:52:22 +08:00
|
|
|
});
|
|
|
|
std::rotate(Pos, NonScriptI, End);
|
|
|
|
NonScriptI = End;
|
|
|
|
}
|
2016-11-14 23:39:38 +08:00
|
|
|
|
2017-03-20 18:09:58 +08:00
|
|
|
Script->adjustSectionsAfterSorting();
|
2016-09-22 06:36:19 +08:00
|
|
|
}
|
|
|
|
|
2017-12-12 21:30:44 +08:00
|
|
|
static bool compareByFilePosition(InputSection *A, InputSection *B) {
|
2017-12-20 16:56:10 +08:00
|
|
|
// Synthetic, i. e. a sentinel section, should go last.
|
2017-12-12 21:30:44 +08:00
|
|
|
if (A->kind() == InputSectionBase::Synthetic ||
|
|
|
|
B->kind() == InputSectionBase::Synthetic)
|
2017-12-20 16:56:10 +08:00
|
|
|
return A->kind() != InputSectionBase::Synthetic;
|
2017-12-12 21:30:44 +08:00
|
|
|
InputSection *LA = A->getLinkOrderDep();
|
|
|
|
InputSection *LB = B->getLinkOrderDep();
|
|
|
|
OutputSection *AOut = LA->getParent();
|
|
|
|
OutputSection *BOut = LB->getParent();
|
|
|
|
if (AOut != BOut)
|
|
|
|
return AOut->SectionIndex < BOut->SectionIndex;
|
|
|
|
return LA->OutSecOff < LB->OutSecOff;
|
|
|
|
}
|
|
|
|
|
2017-12-15 19:09:41 +08:00
|
|
|
// This function is used by the --merge-exidx-entries to detect duplicate
|
|
|
|
// .ARM.exidx sections. It is Arm only.
|
|
|
|
//
|
|
|
|
// The .ARM.exidx section is of the form:
|
|
|
|
// | PREL31 offset to function | Unwind instructions for function |
|
|
|
|
// where the unwind instructions are either a small number of unwind
|
|
|
|
// instructions inlined into the table entry, the special CANT_UNWIND value of
|
|
|
|
// 0x1 or a PREL31 offset into a .ARM.extab Section that contains unwind
|
|
|
|
// instructions.
|
|
|
|
//
|
|
|
|
// We return true if all the unwind instructions in the .ARM.exidx entries of
|
|
|
|
// Cur can be merged into the last entry of Prev.
|
|
|
|
static bool isDuplicateArmExidxSec(InputSection *Prev, InputSection *Cur) {
|
|
|
|
|
|
|
|
// References to .ARM.Extab Sections have bit 31 clear and are not the
|
|
|
|
// special EXIDX_CANTUNWIND bit-pattern.
|
|
|
|
auto IsExtabRef = [](uint32_t Unwind) {
|
|
|
|
return (Unwind & 0x80000000) == 0 && Unwind != 0x1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ExidxEntry {
|
|
|
|
ulittle32_t Fn;
|
|
|
|
ulittle32_t Unwind;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get the last table Entry from the previous .ARM.exidx section.
|
|
|
|
const ExidxEntry &PrevEntry = *reinterpret_cast<const ExidxEntry *>(
|
|
|
|
Prev->Data.data() + Prev->getSize() - sizeof(ExidxEntry));
|
|
|
|
if (IsExtabRef(PrevEntry.Unwind))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// We consider the unwind instructions of an .ARM.exidx table entry
|
|
|
|
// a duplicate if the previous unwind instructions if:
|
|
|
|
// - Both are the special EXIDX_CANTUNWIND.
|
|
|
|
// - Both are the same inline unwind instructions.
|
|
|
|
// We do not attempt to follow and check links into .ARM.extab tables as
|
|
|
|
// consecutive identical entries are rare and the effort to check that they
|
|
|
|
// are identical is high.
|
|
|
|
|
|
|
|
if (isa<SyntheticSection>(Cur))
|
|
|
|
// Exidx sentinel section has implicit EXIDX_CANTUNWIND;
|
|
|
|
return PrevEntry.Unwind == 0x1;
|
|
|
|
|
|
|
|
ArrayRef<const ExidxEntry> Entries(
|
|
|
|
reinterpret_cast<const ExidxEntry *>(Cur->Data.data()),
|
|
|
|
Cur->getSize() / sizeof(ExidxEntry));
|
|
|
|
for (const ExidxEntry &Entry : Entries)
|
|
|
|
if (IsExtabRef(Entry.Unwind) || Entry.Unwind != PrevEntry.Unwind)
|
|
|
|
return false;
|
|
|
|
// All table entries in this .ARM.exidx Section can be merged into the
|
|
|
|
// previous Section.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-12 21:30:44 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
|
|
|
|
for (OutputSection *Sec : OutputSections) {
|
|
|
|
if (!(Sec->Flags & SHF_LINK_ORDER))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Link order may be distributed across several InputSectionDescriptions
|
|
|
|
// but sort must consider them all at once.
|
|
|
|
std::vector<InputSection **> ScriptSections;
|
|
|
|
std::vector<InputSection *> Sections;
|
|
|
|
for (BaseCommand *Base : Sec->SectionCommands) {
|
|
|
|
if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) {
|
|
|
|
for (InputSection *&IS : ISD->Sections) {
|
|
|
|
ScriptSections.push_back(&IS);
|
|
|
|
Sections.push_back(IS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition);
|
2017-12-15 19:09:41 +08:00
|
|
|
|
2017-12-20 16:56:10 +08:00
|
|
|
if (!Config->Relocatable && Config->EMachine == EM_ARM &&
|
|
|
|
Sec->Type == SHT_ARM_EXIDX) {
|
|
|
|
|
|
|
|
if (!Sections.empty() && isa<ARMExidxSentinelSection>(Sections.back())) {
|
|
|
|
assert(Sections.size() >= 2 &&
|
|
|
|
"We should create a sentinel section only if there are "
|
|
|
|
"alive regular exidx sections.");
|
|
|
|
// The last executable section is required to fill the sentinel.
|
|
|
|
// Remember it here so that we don't have to find it again.
|
|
|
|
auto *Sentinel = cast<ARMExidxSentinelSection>(Sections.back());
|
|
|
|
Sentinel->Highest = Sections[Sections.size() - 2]->getLinkOrderDep();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Config->MergeArmExidx) {
|
|
|
|
// The EHABI for the Arm Architecture permits consecutive identical
|
|
|
|
// table entries to be merged. We use a simple implementation that
|
|
|
|
// removes a .ARM.exidx Input Section if it can be merged into the
|
|
|
|
// previous one. This does not require any rewriting of InputSection
|
|
|
|
// contents but misses opportunities for fine grained deduplication
|
|
|
|
// where only a subset of the InputSection contents can be merged.
|
|
|
|
int Cur = 1;
|
|
|
|
int Prev = 0;
|
|
|
|
// The last one is a sentinel entry which should not be removed.
|
|
|
|
int N = Sections.size() - 1;
|
|
|
|
while (Cur < N) {
|
|
|
|
if (isDuplicateArmExidxSec(Sections[Prev], Sections[Cur]))
|
|
|
|
Sections[Cur] = nullptr;
|
|
|
|
else
|
|
|
|
Prev = Cur;
|
|
|
|
++Cur;
|
|
|
|
}
|
2017-12-15 19:09:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-12 21:30:44 +08:00
|
|
|
for (int I = 0, N = Sections.size(); I < N; ++I)
|
|
|
|
*ScriptSections[I] = Sections[I];
|
2017-12-15 19:09:41 +08:00
|
|
|
|
|
|
|
// Remove the Sections we marked as duplicate earlier.
|
|
|
|
for (BaseCommand *Base : Sec->SectionCommands)
|
|
|
|
if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
|
2018-02-21 22:21:23 +08:00
|
|
|
llvm::erase_if(ISD->Sections, [](InputSection *IS) { return !IS; });
|
2017-12-12 21:30:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-08 22:06:24 +08:00
|
|
|
static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
|
|
|
|
std::function<void(SyntheticSection *)> Fn) {
|
2017-02-27 10:56:02 +08:00
|
|
|
for (SyntheticSection *SS : Sections)
|
2017-06-07 10:31:19 +08:00
|
|
|
if (SS && SS->getParent() && !SS->empty())
|
2017-03-08 22:06:24 +08:00
|
|
|
Fn(SS);
|
2016-11-15 20:26:55 +08:00
|
|
|
}
|
|
|
|
|
2017-10-03 02:54:59 +08:00
|
|
|
// In order to allow users to manipulate linker-synthesized sections,
|
|
|
|
// we had to add synthetic sections to the input section list early,
|
|
|
|
// even before we make decisions whether they are needed. This allows
|
|
|
|
// users to write scripts like this: ".mygot : { .got }".
|
|
|
|
//
|
|
|
|
// Doing it has an unintended side effects. If it turns out that we
|
|
|
|
// don't need a .got (for example) at all because there's no
|
|
|
|
// relocation that needs a .got, we don't want to emit .got.
|
|
|
|
//
|
|
|
|
// To deal with the above problem, this function is called after
|
|
|
|
// scanRelocations is called to remove synthetic sections that turn
|
|
|
|
// out to be empty.
|
2017-07-04 00:54:39 +08:00
|
|
|
static void removeUnusedSyntheticSections() {
|
2017-02-03 21:06:18 +08:00
|
|
|
// All input synthetic sections that can be empty are placed after
|
|
|
|
// all regular ones. We iterate over them all and exit at first
|
|
|
|
// non-synthetic.
|
2017-02-27 10:32:08 +08:00
|
|
|
for (InputSectionBase *S : llvm::reverse(InputSections)) {
|
2017-02-27 10:56:02 +08:00
|
|
|
SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
|
2016-12-06 05:39:35 +08:00
|
|
|
if (!SS)
|
2016-11-25 16:05:41 +08:00
|
|
|
return;
|
2017-06-01 04:17:44 +08:00
|
|
|
OutputSection *OS = SS->getParent();
|
2018-01-25 03:16:31 +08:00
|
|
|
if (!OS || !SS->empty())
|
2016-11-25 16:05:41 +08:00
|
|
|
continue;
|
2017-07-04 00:54:39 +08:00
|
|
|
|
2018-02-07 17:11:07 +08:00
|
|
|
// If we reach here, then SS is an unused synthetic section and we want to
|
|
|
|
// remove it from corresponding input section description of output section.
|
|
|
|
for (BaseCommand *B : OS->SectionCommands)
|
|
|
|
if (auto *ISD = dyn_cast<InputSectionDescription>(B))
|
2017-09-08 21:26:45 +08:00
|
|
|
llvm::erase_if(ISD->Sections,
|
|
|
|
[=](InputSection *IS) { return IS == SS; });
|
2016-11-25 16:05:41 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-10 23:05:37 +08:00
|
|
|
// Returns true if a symbol can be replaced at load-time by a symbol
|
|
|
|
// with the same name defined in other ELF executable or DSO.
|
2017-11-04 05:21:47 +08:00
|
|
|
static bool computeIsPreemptible(const Symbol &B) {
|
2017-08-10 23:05:37 +08:00
|
|
|
assert(!B.isLocal());
|
|
|
|
// Only symbols that appear in dynsym can be preempted.
|
2017-11-01 00:07:41 +08:00
|
|
|
if (!B.includeInDynsym())
|
2017-08-10 23:05:37 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Only default visibility symbols can be preempted.
|
2017-11-01 00:07:41 +08:00
|
|
|
if (B.Visibility != STV_DEFAULT)
|
2017-08-10 23:05:37 +08:00
|
|
|
return false;
|
|
|
|
|
2017-09-13 01:18:03 +08:00
|
|
|
// At this point copy relocations have not been created yet, so any
|
|
|
|
// symbol that is not defined locally is preemptible.
|
2017-11-06 12:39:07 +08:00
|
|
|
if (!B.isDefined())
|
2017-09-09 02:16:59 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// If we have a dynamic list it specifies which local symbols are preemptible.
|
2017-09-09 02:53:43 +08:00
|
|
|
if (Config->HasDynamicList)
|
2017-09-09 02:16:59 +08:00
|
|
|
return false;
|
|
|
|
|
2017-08-10 23:05:37 +08:00
|
|
|
if (!Config->Shared)
|
2017-09-09 02:16:59 +08:00
|
|
|
return false;
|
2017-08-10 23:05:37 +08:00
|
|
|
|
|
|
|
// -Bsymbolic means that definitions are not preempted.
|
|
|
|
if (Config->Bsymbolic || (Config->BsymbolicFunctions && B.isFunc()))
|
2017-09-09 02:23:25 +08:00
|
|
|
return false;
|
2017-08-10 23:05:37 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-07-20 22:43:20 +08:00
|
|
|
// Create output section objects and add them to OutputSections.
|
|
|
|
template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
2017-07-28 03:22:43 +08:00
|
|
|
Out::DebugInfo = findSection(".debug_info");
|
|
|
|
Out::PreinitArray = findSection(".preinit_array");
|
|
|
|
Out::InitArray = findSection(".init_array");
|
|
|
|
Out::FiniArray = findSection(".fini_array");
|
2015-10-03 03:37:55 +08:00
|
|
|
|
2015-12-26 17:48:00 +08:00
|
|
|
// The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
|
|
|
|
// symbols for sections, so that the runtime can get the start and end
|
|
|
|
// addresses of each section by section name. Add such symbols.
|
2016-03-02 03:12:35 +08:00
|
|
|
if (!Config->Relocatable) {
|
|
|
|
addStartEndSymbols();
|
2017-10-11 09:50:56 +08:00
|
|
|
for (BaseCommand *Base : Script->SectionCommands)
|
2017-07-28 03:22:43 +08:00
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
|
|
|
addStartStopSymbols(Sec);
|
2016-03-02 03:12:35 +08:00
|
|
|
}
|
2016-03-05 02:34:14 +08:00
|
|
|
|
|
|
|
// Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type.
|
|
|
|
// It should be okay as no one seems to care about the type.
|
|
|
|
// Even the author of gold doesn't remember why gold behaves that way.
|
|
|
|
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
|
2017-05-16 18:04:42 +08:00
|
|
|
if (InX::DynSymTab)
|
2017-12-24 01:21:39 +08:00
|
|
|
Symtab->addRegular("_DYNAMIC", STV_HIDDEN, STT_NOTYPE, 0 /*Value*/,
|
|
|
|
/*Size=*/0, STB_WEAK, InX::Dynamic,
|
|
|
|
/*File=*/nullptr);
|
2015-10-19 23:21:42 +08:00
|
|
|
|
2016-02-05 05:33:05 +08:00
|
|
|
// Define __rel[a]_iplt_{start,end} symbols if needed.
|
|
|
|
addRelIpltSymbols();
|
|
|
|
|
2017-02-24 06:06:28 +08:00
|
|
|
// This responsible for splitting up .eh_frame section into
|
2017-03-08 22:06:24 +08:00
|
|
|
// pieces. The relocation scan uses those pieces, so this has to be
|
2017-02-24 06:06:28 +08:00
|
|
|
// earlier.
|
2017-10-27 11:13:39 +08:00
|
|
|
applySynthetic({InX::EhFrame},
|
2017-03-16 18:29:44 +08:00
|
|
|
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
2016-04-07 22:22:09 +08:00
|
|
|
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *S : Symtab->getSymbols())
|
2017-11-01 00:07:41 +08:00
|
|
|
S->IsPreemptible |= computeIsPreemptible(*S);
|
2017-08-10 23:05:37 +08:00
|
|
|
|
2016-07-21 01:58:07 +08:00
|
|
|
// Scan relocations. This must be done after every symbol is declared so that
|
|
|
|
// we can correctly decide if a dynamic relocation is needed.
|
2017-09-13 15:54:47 +08:00
|
|
|
if (!Config->Relocatable)
|
|
|
|
forEachRelSec(scanRelocations<ELFT>);
|
2016-07-21 01:58:07 +08:00
|
|
|
|
2017-05-12 06:02:41 +08:00
|
|
|
if (InX::Plt && !InX::Plt->empty())
|
|
|
|
InX::Plt->addSymbols();
|
|
|
|
if (InX::Iplt && !InX::Iplt->empty())
|
|
|
|
InX::Iplt->addSymbols();
|
2017-01-25 18:31:16 +08:00
|
|
|
|
2017-02-20 19:12:33 +08:00
|
|
|
// Now that we have defined all possible global symbols including linker-
|
2015-12-26 18:22:16 +08:00
|
|
|
// synthesized ones. Visit all symbols to give the finishing touches.
|
2017-11-04 05:21:47 +08:00
|
|
|
for (Symbol *Sym : Symtab->getSymbols()) {
|
2017-11-01 00:07:41 +08:00
|
|
|
if (!includeInSymtab(*Sym))
|
2015-09-23 07:38:23 +08:00
|
|
|
continue;
|
2017-05-16 18:04:42 +08:00
|
|
|
if (InX::SymTab)
|
2017-11-01 00:07:41 +08:00
|
|
|
InX::SymTab->addSymbol(Sym);
|
2015-09-23 07:38:23 +08:00
|
|
|
|
2017-11-01 00:07:41 +08:00
|
|
|
if (InX::DynSymTab && Sym->includeInDynsym()) {
|
|
|
|
InX::DynSymTab->addSymbol(Sym);
|
|
|
|
if (auto *SS = dyn_cast<SharedSymbol>(Sym))
|
2017-11-23 01:50:42 +08:00
|
|
|
if (cast<SharedFile<ELFT>>(Sym->File)->IsNeeded)
|
2016-11-22 00:59:33 +08:00
|
|
|
In<ELFT>::VerNeed->addSymbol(SS);
|
2016-04-28 04:22:31 +08:00
|
|
|
}
|
2015-09-23 07:38:23 +08:00
|
|
|
}
|
2016-01-29 06:56:29 +08:00
|
|
|
|
|
|
|
// Do not proceed if there was an undefined symbol.
|
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
2017-10-26 06:28:38 +08:00
|
|
|
if (errorCount())
|
2016-04-02 01:24:19 +08:00
|
|
|
return;
|
2016-01-29 06:56:29 +08:00
|
|
|
|
2017-07-04 00:54:39 +08:00
|
|
|
removeUnusedSyntheticSections();
|
|
|
|
|
2016-09-22 06:36:19 +08:00
|
|
|
sortSections();
|
2017-06-16 05:51:01 +08:00
|
|
|
|
|
|
|
// Now that we have the final list, create a list of all the
|
2017-07-28 03:22:43 +08:00
|
|
|
// OutputSections for convenience.
|
2017-10-11 09:50:56 +08:00
|
|
|
for (BaseCommand *Base : Script->SectionCommands)
|
2017-07-28 03:22:43 +08:00
|
|
|
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
|
|
|
OutputSections.push_back(Sec);
|
2015-12-26 15:50:41 +08:00
|
|
|
|
2017-06-20 09:51:50 +08:00
|
|
|
// Prefer command line supplied address over other constraints.
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections) {
|
|
|
|
auto I = Config->SectionStartMap.find(Sec->Name);
|
2017-06-20 09:51:50 +08:00
|
|
|
if (I != Config->SectionStartMap.end())
|
2017-07-28 03:22:43 +08:00
|
|
|
Sec->AddrExpr = [=] { return I->second; };
|
2017-06-20 09:51:50 +08:00
|
|
|
}
|
|
|
|
|
2017-01-29 01:48:21 +08:00
|
|
|
// This is a bit of a hack. A value of 0 means undef, so we set it
|
|
|
|
// to 1 t make __ehdr_start defined. The section number is not
|
|
|
|
// particularly relevant.
|
2017-02-27 10:31:26 +08:00
|
|
|
Out::ElfHeader->SectionIndex = 1;
|
2017-01-29 01:48:21 +08:00
|
|
|
|
2016-04-06 15:20:45 +08:00
|
|
|
unsigned I = 1;
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections) {
|
2016-04-06 15:20:45 +08:00
|
|
|
Sec->SectionIndex = I++;
|
2017-05-12 06:02:41 +08:00
|
|
|
Sec->ShName = InX::ShStrTab->addString(Sec->Name);
|
2016-04-06 15:20:45 +08:00
|
|
|
}
|
2015-12-26 15:50:41 +08:00
|
|
|
|
2016-12-20 05:21:07 +08:00
|
|
|
// Binary and relocatable output does not have PHDRS.
|
|
|
|
// The headers have to be created before finalize as that can influence the
|
|
|
|
// image base and the dynamic section on mips includes the image base.
|
|
|
|
if (!Config->Relocatable && !Config->OFormatBinary) {
|
2017-06-14 07:26:31 +08:00
|
|
|
Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
|
2016-12-20 05:21:07 +08:00
|
|
|
addPtArmExid(Phdrs);
|
2017-05-05 03:34:17 +08:00
|
|
|
Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
|
2016-12-20 05:21:07 +08:00
|
|
|
}
|
|
|
|
|
2017-09-13 00:38:01 +08:00
|
|
|
// Some symbols are defined in term of program headers. Now that we
|
|
|
|
// have the headers, we can find out which sections they point to.
|
|
|
|
setReservedSymbolSections();
|
|
|
|
|
2016-11-18 14:44:18 +08:00
|
|
|
// Dynamic section must be the last one in this list and dynamic
|
|
|
|
// symbol table section (DynSymTab) must be the first one.
|
2017-12-11 03:44:42 +08:00
|
|
|
applySynthetic(
|
2017-12-11 04:07:03 +08:00
|
|
|
{InX::DynSymTab, InX::Bss, InX::BssRelRo, InX::GnuHashTab,
|
|
|
|
InX::HashTab, InX::SymTab, InX::ShStrTab, InX::StrTab,
|
|
|
|
In<ELFT>::VerDef, InX::DynStrTab, InX::Got, InX::MipsGot,
|
|
|
|
InX::IgotPlt, InX::GotPlt, InX::RelaDyn, InX::RelaIplt,
|
|
|
|
InX::RelaPlt, InX::Plt, InX::Iplt, InX::EhFrameHdr,
|
|
|
|
In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic},
|
2017-12-11 03:44:42 +08:00
|
|
|
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
2017-03-08 22:06:24 +08:00
|
|
|
|
2017-10-11 09:34:51 +08:00
|
|
|
if (!Script->HasSectionsCommand && !Config->Relocatable)
|
2017-09-06 22:02:14 +08:00
|
|
|
fixSectionAlignments();
|
|
|
|
|
2017-12-12 21:30:44 +08:00
|
|
|
// After link order processing .ARM.exidx sections can be deduplicated, which
|
|
|
|
// needs to be resolved before any other address dependent operation.
|
|
|
|
resolveShfLinkOrder();
|
|
|
|
|
2017-12-05 23:59:05 +08:00
|
|
|
// Some architectures need to generate content that depends on the address
|
|
|
|
// of InputSections. For example some architectures use small displacements
|
2018-02-23 10:05:48 +08:00
|
|
|
// for jump instructions that is the linker's responsibility for creating
|
2017-12-05 23:59:05 +08:00
|
|
|
// range extension thunks for. As the generation of the content may also
|
|
|
|
// alter InputSection addresses we must converge to a fixed point.
|
2017-10-28 01:49:40 +08:00
|
|
|
if (Target->NeedsThunks || Config->AndroidPackDynRelocs) {
|
2017-05-17 15:10:59 +08:00
|
|
|
ThunkCreator TC;
|
2017-12-15 18:32:34 +08:00
|
|
|
AArch64Err843419Patcher A64P;
|
2017-10-28 01:49:40 +08:00
|
|
|
bool Changed;
|
|
|
|
do {
|
2017-10-27 17:04:11 +08:00
|
|
|
Script->assignAddresses();
|
2017-10-28 01:49:40 +08:00
|
|
|
Changed = false;
|
|
|
|
if (Target->NeedsThunks)
|
|
|
|
Changed |= TC.createThunks(OutputSections);
|
2017-12-05 23:59:05 +08:00
|
|
|
if (Config->FixCortexA53Errata843419) {
|
|
|
|
if (Changed)
|
|
|
|
Script->assignAddresses();
|
2017-12-15 18:32:34 +08:00
|
|
|
Changed |= A64P.createFixes();
|
2017-12-05 23:59:05 +08:00
|
|
|
}
|
2017-10-28 01:49:40 +08:00
|
|
|
if (InX::MipsGot)
|
|
|
|
InX::MipsGot->updateAllocSize();
|
2017-12-11 03:44:42 +08:00
|
|
|
Changed |= InX::RelaDyn->updateAllocSize();
|
2017-10-28 01:49:40 +08:00
|
|
|
} while (Changed);
|
2017-03-08 22:06:24 +08:00
|
|
|
}
|
2017-06-05 16:51:15 +08:00
|
|
|
|
2018-04-11 17:24:27 +08:00
|
|
|
// createThunks may have added local symbols to the static symbol table
|
|
|
|
applySynthetic({InX::SymTab},
|
|
|
|
[](SyntheticSection *SS) { SS->postThunkContents(); });
|
|
|
|
|
2017-03-08 22:06:24 +08:00
|
|
|
// Fill other section headers. The dynamic table is finalized
|
|
|
|
// at the end because some tags like RELSZ depend on result
|
|
|
|
// of finalizing other sections.
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
Sec->finalize<ELFT>();
|
2015-12-26 15:50:41 +08:00
|
|
|
}
|
|
|
|
|
2015-12-26 17:48:00 +08:00
|
|
|
// The linker is expected to define SECNAME_start and SECNAME_end
|
|
|
|
// symbols for a few sections. This function defines them.
|
|
|
|
template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
|
2017-02-24 23:07:30 +08:00
|
|
|
auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
|
2016-10-25 04:46:21 +08:00
|
|
|
// These symbols resolve to the image base if the section does not exist.
|
2016-12-21 16:40:09 +08:00
|
|
|
// A special value -1 indicates end of the section.
|
2017-03-14 00:40:20 +08:00
|
|
|
if (OS) {
|
2017-12-24 01:21:39 +08:00
|
|
|
addOptionalRegular(Start, OS, 0);
|
|
|
|
addOptionalRegular(End, OS, -1);
|
2017-03-14 00:40:20 +08:00
|
|
|
} else {
|
2017-03-18 07:29:01 +08:00
|
|
|
if (Config->Pic)
|
2017-03-14 00:40:20 +08:00
|
|
|
OS = Out::ElfHeader;
|
2017-12-24 01:21:39 +08:00
|
|
|
addOptionalRegular(Start, OS, 0);
|
|
|
|
addOptionalRegular(End, OS, 0);
|
2017-03-14 00:40:20 +08:00
|
|
|
}
|
2015-12-26 17:48:00 +08:00
|
|
|
};
|
|
|
|
|
2017-02-27 10:31:26 +08:00
|
|
|
Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
|
|
|
|
Define("__init_array_start", "__init_array_end", Out::InitArray);
|
|
|
|
Define("__fini_array_start", "__fini_array_end", Out::FiniArray);
|
2016-10-27 18:28:53 +08:00
|
|
|
|
2017-07-28 03:22:43 +08:00
|
|
|
if (OutputSection *Sec = findSection(".ARM.exidx"))
|
2016-10-27 18:28:53 +08:00
|
|
|
Define("__exidx_start", "__exidx_end", Sec);
|
2015-12-26 17:48:00 +08:00
|
|
|
}
|
|
|
|
|
2015-10-16 01:11:03 +08:00
|
|
|
// If a section name is valid as a C identifier (which is rare because of
|
|
|
|
// the leading '.'), linkers are expected to define __start_<secname> and
|
|
|
|
// __stop_<secname> symbols. They are at beginning and end of the section,
|
|
|
|
// respectively. This is not requested by the ELF standard, but GNU ld and
|
|
|
|
// gold provide the feature, and used by many programs.
|
|
|
|
template <class ELFT>
|
2017-02-24 23:07:30 +08:00
|
|
|
void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
|
2017-02-24 22:28:00 +08:00
|
|
|
StringRef S = Sec->Name;
|
2015-10-16 01:11:03 +08:00
|
|
|
if (!isValidCIdentifier(S))
|
|
|
|
return;
|
2018-03-20 22:22:10 +08:00
|
|
|
addOptionalRegular(Saver.save("__start_" + S), Sec, 0, STV_PROTECTED);
|
|
|
|
addOptionalRegular(Saver.save("__stop_" + S), Sec, -1, STV_PROTECTED);
|
2015-10-16 01:11:03 +08:00
|
|
|
}
|
|
|
|
|
2017-03-16 19:20:02 +08:00
|
|
|
static bool needsPtLoad(OutputSection *Sec) {
|
2018-04-05 21:23:59 +08:00
|
|
|
if (!(Sec->Flags & SHF_ALLOC) || Sec->Noload)
|
2016-02-11 07:29:38 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
|
|
|
|
// responsible for allocating space for them, not the PT_LOAD that
|
|
|
|
// contains the TLS initialization image.
|
2016-11-09 09:42:41 +08:00
|
|
|
if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS)
|
2016-02-11 07:29:38 +08:00
|
|
|
return false;
|
|
|
|
return true;
|
2015-09-10 04:48:09 +08:00
|
|
|
}
|
|
|
|
|
2016-09-20 23:22:27 +08:00
|
|
|
// 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.
|
2017-04-06 05:37:09 +08:00
|
|
|
static uint64_t computeFlags(uint64_t Flags) {
|
2017-02-25 09:52:03 +08:00
|
|
|
if (Config->Omagic)
|
2016-11-29 17:43:51 +08:00
|
|
|
return PF_R | PF_W | PF_X;
|
2017-04-06 05:37:09 +08:00
|
|
|
if (Config->SingleRoRx && !(Flags & PF_W))
|
|
|
|
return Flags | PF_X;
|
|
|
|
return Flags;
|
2016-09-20 23:22:27 +08:00
|
|
|
}
|
|
|
|
|
2016-02-11 06:43:13 +08:00
|
|
|
// Decide which program headers to create and which sections to include in each
|
|
|
|
// one.
|
2017-07-27 15:46:50 +08:00
|
|
|
template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
|
|
|
|
std::vector<PhdrEntry *> Ret;
|
2016-12-20 01:01:01 +08:00
|
|
|
auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * {
|
2017-07-27 15:46:50 +08:00
|
|
|
Ret.push_back(make<PhdrEntry>(Type, Flags));
|
|
|
|
return Ret.back();
|
2016-02-11 06:43:13 +08:00
|
|
|
};
|
2015-09-10 04:48:09 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// The first phdr entry is PT_PHDR which describes the program header itself.
|
2017-02-27 10:31:26 +08:00
|
|
|
AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders);
|
2015-08-13 23:23:46 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// PT_INTERP must be the second entry if exists.
|
2017-07-28 03:22:43 +08:00
|
|
|
if (OutputSection *Cmd = findSection(".interp"))
|
|
|
|
AddHdr(PT_INTERP, Cmd->getPhdrFlags())->add(Cmd);
|
2015-09-12 02:49:42 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Add the first PT_LOAD segment for regular output sections.
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t Flags = computeFlags(PF_R);
|
2016-12-20 01:01:01 +08:00
|
|
|
PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
|
2017-05-05 03:34:17 +08:00
|
|
|
|
|
|
|
// Add the headers. We will remove them if they don't fit.
|
|
|
|
Load->add(Out::ElfHeader);
|
|
|
|
Load->add(Out::ProgramHeaders);
|
|
|
|
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections) {
|
2016-11-09 09:42:41 +08:00
|
|
|
if (!(Sec->Flags & SHF_ALLOC))
|
2016-09-17 05:29:07 +08:00
|
|
|
break;
|
2017-03-16 19:20:02 +08:00
|
|
|
if (!needsPtLoad(Sec))
|
2016-02-11 07:29:38 +08:00
|
|
|
continue;
|
|
|
|
|
2016-08-17 15:44:19 +08:00
|
|
|
// Segments are contiguous memory regions that has the same attributes
|
|
|
|
// (e.g. executable or writable). There is one phdr for each segment.
|
|
|
|
// 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
|
2018-02-15 14:13:52 +08:00
|
|
|
// script command. At the same time, we don't want to create a separate
|
|
|
|
// load segment for the headers, even if the first output section has
|
|
|
|
// an AT attribute.
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
|
2018-02-15 14:13:52 +08:00
|
|
|
if ((Sec->LMAExpr && Load->LastSec != Out::ProgramHeaders) ||
|
2018-01-29 11:44:44 +08:00
|
|
|
Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) {
|
|
|
|
|
2016-03-10 05:37:22 +08:00
|
|
|
Load = AddHdr(PT_LOAD, NewFlags);
|
2016-02-11 06:43:13 +08:00
|
|
|
Flags = NewFlags;
|
2015-08-13 23:31:17 +08:00
|
|
|
}
|
2015-08-12 08:00:24 +08:00
|
|
|
|
2016-07-21 03:36:41 +08:00
|
|
|
Load->add(Sec);
|
2015-11-05 10:00:35 +08:00
|
|
|
}
|
2015-11-03 08:34:39 +08:00
|
|
|
|
2017-02-02 06:42:17 +08:00
|
|
|
// Add a TLS segment if any.
|
2017-07-27 15:46:50 +08:00
|
|
|
PhdrEntry *TlsHdr = make<PhdrEntry>(PT_TLS, PF_R);
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
2017-02-02 06:42:17 +08:00
|
|
|
if (Sec->Flags & SHF_TLS)
|
2017-07-27 15:46:50 +08:00
|
|
|
TlsHdr->add(Sec);
|
2017-09-07 19:01:10 +08:00
|
|
|
if (TlsHdr->FirstSec)
|
2017-07-27 15:46:50 +08:00
|
|
|
Ret.push_back(TlsHdr);
|
2016-02-11 06:43:13 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Add an entry for .dynamic.
|
2017-05-16 18:04:42 +08:00
|
|
|
if (InX::DynSymTab)
|
2017-06-01 04:17:44 +08:00
|
|
|
AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
|
|
|
|
->add(InX::Dynamic->getParent());
|
2015-08-12 09:45:28 +08:00
|
|
|
|
2016-02-11 06:43:13 +08:00
|
|
|
// PT_GNU_RELRO includes all sections that should be marked as
|
|
|
|
// read-only by dynamic linker after proccessing relocations.
|
2017-11-23 22:53:10 +08:00
|
|
|
// Current dynamic loaders only support one PT_GNU_RELRO PHDR, give
|
|
|
|
// an error message if more than one PT_GNU_RELRO PHDR is required.
|
2017-07-27 15:46:50 +08:00
|
|
|
PhdrEntry *RelRo = make<PhdrEntry>(PT_GNU_RELRO, PF_R);
|
2017-11-23 22:53:10 +08:00
|
|
|
bool InRelroPhdr = false;
|
|
|
|
bool IsRelroFinished = false;
|
|
|
|
for (OutputSection *Sec : OutputSections) {
|
Revert r318924 Skip over empty sections when checking for contiguous relro
PR35478 https://bugs.llvm.org/show_bug.cgi?id=35478 points out a flaw
in the implementation of r318924 from D40364. The implementation
depends on the Size field being set or the SyntheticSection::empty()
being accurate. These functions are not reliable as some linker script
commands that have yet to be processed may affect the results, causing
some non-zero size sections to be reported as zero size.
I think the first step is to revert r318924 and come up with a better
solution for the underlying problem rather than trying to layer more
heuristics onto the zero sized output section.
Chances are I'll be out of office by the time anyone sees this so feel
free to commit the revert if you agree with me.
Fixes PR35478
Current thoughts on the underlying problem:
Revisiting the motivation for adding the zero size check in the first
place; it was to prevent 0 sized SyntheticSections that a user does
not have full control over from needlessly breaking the PT_GNU_RELRO,
rather than trying to accommodate arbitrarily complex linker
scripts. Looking at the code, it looks like
removeUnusedSyntheticSections() should remove zero sized synthetic
sections. It does, but it doesn't set the Parent to nullptr, this has
the side effect that Sec == InX::BssRelRo->getParent() will make the
parent OutputSection of InX::BssRelRo RelRo even if there is no
InX::BssRelRo.
I tried a quick experiment with setting the Parent to nullptr and this
flushed out a few interesting test failures, it feels like playing
Jenga with every change:
In the isRelroSection() we have to consider the case where there
is no .plt and .plt.got but there is a ifunc plt with accompanying
(ifunc .got or .plt.got)
The PPC64 has PltHeaderSize == 0. Unfortunately HeaderSize == 0 is
used to choose between the ifunc plt or normal plt. We seem to get
away with this at the moment, but tests start to fail when Parent
is set to nullptr for the .got.plt.
The InX::BssRelRo and InX::Bss never get their sizes set and they
are always removed by removeUnusedSyntheticSections(), their
purpose seems to be as some kind of proxy for add .bss or
.bss.relro InputSections into their parent OutputSections, they
therefore don't behave like other SyntheticSections anyway.
My thinking is that some work is needed to make sure that the Sec ==
SyntheticSection->getParent() does a bit more checking before
returning true, particularly for InX::BssRelRo as that has special
behaviour. I'll hope to post something for review as soon as possible.
Patch by Peter Smith!
llvm-svn: 319563
2017-12-02 02:14:14 +08:00
|
|
|
if (!needsPtLoad(Sec))
|
2017-11-23 22:53:10 +08:00
|
|
|
continue;
|
|
|
|
if (isRelroSection(Sec)) {
|
|
|
|
InRelroPhdr = true;
|
|
|
|
if (!IsRelroFinished)
|
|
|
|
RelRo->add(Sec);
|
|
|
|
else
|
|
|
|
error("section: " + Sec->Name + " is not contiguous with other relro" +
|
|
|
|
" sections");
|
|
|
|
} else if (InRelroPhdr) {
|
|
|
|
InRelroPhdr = false;
|
|
|
|
IsRelroFinished = true;
|
|
|
|
}
|
|
|
|
}
|
2017-09-07 19:01:10 +08:00
|
|
|
if (RelRo->FirstSec)
|
2017-07-27 15:46:50 +08:00
|
|
|
Ret.push_back(RelRo);
|
2015-11-24 18:15:50 +08:00
|
|
|
|
2016-02-11 06:43:13 +08:00
|
|
|
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
|
2017-10-27 11:14:24 +08:00
|
|
|
if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() &&
|
|
|
|
InX::EhFrameHdr->getParent())
|
|
|
|
AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags())
|
|
|
|
->add(InX::EhFrameHdr->getParent());
|
2016-01-15 21:34:52 +08:00
|
|
|
|
2017-03-24 08:15:57 +08:00
|
|
|
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
|
|
|
|
// the dynamic linker fill the segment with random data.
|
2017-07-28 03:22:43 +08:00
|
|
|
if (OutputSection *Cmd = findSection(".openbsd.randomdata"))
|
|
|
|
AddHdr(PT_OPENBSD_RANDOMIZE, Cmd->getPhdrFlags())->add(Cmd);
|
2016-10-14 21:02:22 +08:00
|
|
|
|
2015-11-22 06:19:32 +08:00
|
|
|
// PT_GNU_STACK is a special section to tell the loader to make the
|
2017-02-23 16:09:51 +08:00
|
|
|
// pages for the stack non-executable. If you really want an executable
|
|
|
|
// stack, you can pass -z execstack, but that's not recommended for
|
|
|
|
// security reasons.
|
2018-03-23 22:43:51 +08:00
|
|
|
unsigned Perm = PF_R | PF_W;
|
2017-02-23 16:09:51 +08:00
|
|
|
if (Config->ZExecstack)
|
2018-03-23 22:43:51 +08:00
|
|
|
Perm |= PF_X;
|
2017-02-23 16:09:51 +08:00
|
|
|
AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
|
2016-03-01 21:23:29 +08:00
|
|
|
|
2016-10-14 18:34:36 +08:00
|
|
|
// PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
|
|
|
|
// is expected to perform W^X violations, such as calling mprotect(2) or
|
|
|
|
// mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
|
|
|
|
// OpenBSD.
|
|
|
|
if (Config->ZWxneeded)
|
|
|
|
AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
|
|
|
|
|
2017-02-02 04:58:41 +08:00
|
|
|
// Create one PT_NOTE per a group of contiguous .note sections.
|
|
|
|
PhdrEntry *Note = nullptr;
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections) {
|
2017-02-02 04:58:41 +08:00
|
|
|
if (Sec->Type == SHT_NOTE) {
|
2017-07-28 03:22:43 +08:00
|
|
|
if (!Note || Sec->LMAExpr)
|
2017-02-02 04:58:41 +08:00
|
|
|
Note = AddHdr(PT_NOTE, PF_R);
|
|
|
|
Note->add(Sec);
|
|
|
|
} else {
|
|
|
|
Note = nullptr;
|
|
|
|
}
|
|
|
|
}
|
2016-07-21 03:36:39 +08:00
|
|
|
return Ret;
|
2016-02-11 06:43:13 +08:00
|
|
|
}
|
|
|
|
|
2016-11-28 08:40:21 +08:00
|
|
|
template <class ELFT>
|
2017-07-27 15:46:50 +08:00
|
|
|
void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry *> &Phdrs) {
|
2016-11-28 08:40:21 +08:00
|
|
|
if (Config->EMachine != EM_ARM)
|
|
|
|
return;
|
2017-07-28 03:22:43 +08:00
|
|
|
auto I = llvm::find_if(OutputSections, [](OutputSection *Cmd) {
|
|
|
|
return Cmd->Type == SHT_ARM_EXIDX;
|
2017-07-04 21:10:37 +08:00
|
|
|
});
|
2017-07-28 03:22:43 +08:00
|
|
|
if (I == OutputSections.end())
|
2016-11-28 08:40:21 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
// PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
|
2017-07-27 15:46:50 +08:00
|
|
|
PhdrEntry *ARMExidx = make<PhdrEntry>(PT_ARM_EXIDX, PF_R);
|
2017-07-28 03:22:43 +08:00
|
|
|
ARMExidx->add(*I);
|
2016-11-28 08:40:21 +08:00
|
|
|
Phdrs.push_back(ARMExidx);
|
|
|
|
}
|
|
|
|
|
2017-01-10 09:21:30 +08:00
|
|
|
// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
|
|
|
|
// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
|
|
|
|
// linker can set the permissions.
|
2016-03-31 03:41:51 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
|
2017-07-28 03:22:43 +08:00
|
|
|
auto PageAlign = [](OutputSection *Cmd) {
|
2017-06-02 09:37:58 +08:00
|
|
|
if (Cmd && !Cmd->AddrExpr)
|
|
|
|
Cmd->AddrExpr = [=] {
|
|
|
|
return alignTo(Script->getDot(), Config->MaxPageSize);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2017-07-27 15:46:50 +08:00
|
|
|
for (const PhdrEntry *P : Phdrs)
|
2017-09-07 19:01:10 +08:00
|
|
|
if (P->p_type == PT_LOAD && P->FirstSec)
|
|
|
|
PageAlign(P->FirstSec);
|
2016-03-31 03:41:51 +08:00
|
|
|
|
2017-07-27 15:46:50 +08:00
|
|
|
for (const PhdrEntry *P : Phdrs) {
|
|
|
|
if (P->p_type != PT_GNU_RELRO)
|
2016-03-31 03:41:51 +08:00
|
|
|
continue;
|
2017-09-07 19:01:10 +08:00
|
|
|
if (P->FirstSec)
|
|
|
|
PageAlign(P->FirstSec);
|
2016-03-31 03:41:51 +08:00
|
|
|
// Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
|
|
|
|
// have to align it to a page.
|
2017-07-28 03:22:43 +08:00
|
|
|
auto End = OutputSections.end();
|
2017-09-07 19:01:10 +08:00
|
|
|
auto I = std::find(OutputSections.begin(), End, P->LastSec);
|
2016-03-31 03:41:51 +08:00
|
|
|
if (I == End || (I + 1) == End)
|
|
|
|
continue;
|
2017-07-28 03:22:43 +08:00
|
|
|
OutputSection *Cmd = (*(I + 1));
|
|
|
|
if (needsPtLoad(Cmd))
|
|
|
|
PageAlign(Cmd);
|
2016-03-31 03:41:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-27 17:16:28 +08:00
|
|
|
// Adjusts the file alignment for a given output section and returns
|
|
|
|
// its new file offset. The file offset must be the same with its
|
|
|
|
// virtual address (modulo the page size) so that the loader can load
|
|
|
|
// executables without any address adjustment.
|
2017-07-28 03:22:43 +08:00
|
|
|
static uint64_t getFileAlignment(uint64_t Off, OutputSection *Cmd) {
|
2018-01-03 00:46:30 +08:00
|
|
|
OutputSection *First = Cmd->PtLoad ? Cmd->PtLoad->FirstSec : nullptr;
|
2016-12-08 04:20:39 +08:00
|
|
|
// The first section in a PT_LOAD has to have congruent offset and address
|
|
|
|
// module the page size.
|
2017-07-28 03:22:43 +08:00
|
|
|
if (Cmd == First)
|
|
|
|
return alignTo(Off, std::max<uint64_t>(Cmd->Alignment, Config->MaxPageSize),
|
|
|
|
Cmd->Addr);
|
2016-12-08 04:20:39 +08:00
|
|
|
|
2018-01-03 00:46:30 +08:00
|
|
|
// For SHT_NOBITS we don't want the alignment of the section to impact the
|
|
|
|
// offset of the sections that follow. Since nothing seems to care about the
|
|
|
|
// sh_offset of the SHT_NOBITS section itself, just ignore it.
|
|
|
|
if (Cmd->Type == SHT_NOBITS)
|
|
|
|
return Off;
|
|
|
|
|
|
|
|
// If the section is not in a PT_LOAD, we just have to align it.
|
|
|
|
if (!Cmd->PtLoad)
|
|
|
|
return alignTo(Off, Cmd->Alignment);
|
|
|
|
|
2016-12-08 04:20:39 +08:00
|
|
|
// If two sections share the same PT_LOAD the file offset is calculated
|
|
|
|
// using this formula: Off2 = Off1 + (VA2 - VA1).
|
2017-07-28 03:22:43 +08:00
|
|
|
return First->Offset + Cmd->Addr - First->Addr;
|
2016-04-27 17:16:28 +08:00
|
|
|
}
|
|
|
|
|
2017-07-28 03:22:43 +08:00
|
|
|
static uint64_t setOffset(OutputSection *Cmd, uint64_t Off) {
|
|
|
|
Off = getFileAlignment(Off, Cmd);
|
|
|
|
Cmd->Offset = Off;
|
2018-01-03 00:46:30 +08:00
|
|
|
|
|
|
|
// For SHT_NOBITS we should not count the size.
|
|
|
|
if (Cmd->Type == SHT_NOBITS)
|
|
|
|
return Off;
|
|
|
|
|
2017-07-28 03:22:43 +08:00
|
|
|
return Off + Cmd->Size;
|
2016-08-25 17:05:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t Off = 0;
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
2016-11-09 09:42:41 +08:00
|
|
|
if (Sec->Flags & SHF_ALLOC)
|
2017-04-06 05:37:09 +08:00
|
|
|
Off = setOffset(Sec, Off);
|
|
|
|
FileSize = alignTo(Off, Config->Wordsize);
|
2016-08-25 17:05:47 +08:00
|
|
|
}
|
|
|
|
|
2018-03-13 16:47:17 +08:00
|
|
|
static std::string rangeToString(uint64_t Addr, uint64_t Len) {
|
|
|
|
if (Len == 0)
|
|
|
|
return "<empty range at 0x" + utohexstr(Addr) + ">";
|
|
|
|
return "[0x" + utohexstr(Addr) + ", 0x" + utohexstr(Addr + Len - 1) + "]";
|
|
|
|
}
|
|
|
|
|
2016-04-02 01:07:17 +08:00
|
|
|
// Assign file offsets to output sections.
|
|
|
|
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
|
2017-04-06 05:37:09 +08:00
|
|
|
uint64_t Off = 0;
|
|
|
|
Off = setOffset(Out::ElfHeader, Off);
|
|
|
|
Off = setOffset(Out::ProgramHeaders, Off);
|
2016-04-06 15:20:45 +08:00
|
|
|
|
2017-08-03 00:35:00 +08:00
|
|
|
PhdrEntry *LastRX = nullptr;
|
|
|
|
for (PhdrEntry *P : Phdrs)
|
|
|
|
if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
|
|
|
|
LastRX = P;
|
|
|
|
|
|
|
|
for (OutputSection *Sec : OutputSections) {
|
2017-07-28 03:22:43 +08:00
|
|
|
Off = setOffset(Sec, Off);
|
2017-10-11 09:34:51 +08:00
|
|
|
if (Script->HasSectionsCommand)
|
2017-08-03 00:35:00 +08:00
|
|
|
continue;
|
|
|
|
// If this is a last section of the last executable segment and that
|
|
|
|
// segment is the last loadable segment, align the offset of the
|
|
|
|
// following section to avoid loading non-segments parts of the file.
|
2017-09-07 19:01:10 +08:00
|
|
|
if (LastRX && LastRX->LastSec == Sec)
|
2017-08-03 00:35:00 +08:00
|
|
|
Off = alignTo(Off, Target->PageSize);
|
|
|
|
}
|
2016-07-01 18:27:36 +08:00
|
|
|
|
2017-04-06 05:37:09 +08:00
|
|
|
SectionHeaderOff = alignTo(Off, Config->Wordsize);
|
2017-07-28 03:22:43 +08:00
|
|
|
FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
|
2018-03-13 16:47:17 +08:00
|
|
|
|
|
|
|
// Our logic assumes that sections have rising VA within the same segment.
|
|
|
|
// With use of linker scripts it is possible to violate this rule and get file
|
|
|
|
// offset overlaps or overflows. That should never happen with a valid script
|
|
|
|
// which does not move the location counter backwards and usually scripts do
|
|
|
|
// not do that. Unfortunately, there are apps in the wild, for example, Linux
|
|
|
|
// kernel, which control segment distribution explicitly and move the counter
|
|
|
|
// backwards, so we have to allow doing that to support linking them. We
|
2018-04-03 20:28:53 +08:00
|
|
|
// perform non-critical checks for overlaps in checkSectionOverlap(), but here
|
|
|
|
// we want to prevent file size overflows because it would crash the linker.
|
2018-03-13 16:47:17 +08:00
|
|
|
for (OutputSection *Sec : OutputSections) {
|
|
|
|
if (Sec->Type == SHT_NOBITS)
|
|
|
|
continue;
|
|
|
|
if ((Sec->Offset > FileSize) || (Sec->Offset + Sec->Size > FileSize))
|
|
|
|
error("unable to place section " + Sec->Name + " at file offset " +
|
|
|
|
rangeToString(Sec->Offset, Sec->Offset + Sec->Size) +
|
|
|
|
"; check your linker script for overflows");
|
|
|
|
}
|
2016-04-01 18:49:14 +08:00
|
|
|
}
|
|
|
|
|
2016-04-02 01:07:17 +08:00
|
|
|
// Finalize the program headers. We call this function after we assign
|
|
|
|
// file offsets and VAs to all sections.
|
|
|
|
template <class ELFT> void Writer<ELFT>::setPhdrs() {
|
2017-07-27 15:46:50 +08:00
|
|
|
for (PhdrEntry *P : Phdrs) {
|
2017-09-07 19:01:10 +08:00
|
|
|
OutputSection *First = P->FirstSec;
|
|
|
|
OutputSection *Last = P->LastSec;
|
2016-04-02 06:42:04 +08:00
|
|
|
if (First) {
|
2017-07-27 15:46:50 +08:00
|
|
|
P->p_filesz = Last->Offset - First->Offset;
|
2016-11-09 09:42:41 +08:00
|
|
|
if (Last->Type != SHT_NOBITS)
|
2017-07-27 15:46:50 +08:00
|
|
|
P->p_filesz += Last->Size;
|
|
|
|
P->p_memsz = Last->Addr + Last->Size - First->Addr;
|
|
|
|
P->p_offset = First->Offset;
|
|
|
|
P->p_vaddr = First->Addr;
|
|
|
|
if (!P->HasLMA)
|
|
|
|
P->p_paddr = First->getLMA();
|
2016-02-11 06:43:13 +08:00
|
|
|
}
|
2017-07-27 15:46:50 +08:00
|
|
|
if (P->p_type == PT_LOAD)
|
|
|
|
P->p_align = std::max<uint64_t>(P->p_align, Config->MaxPageSize);
|
|
|
|
else if (P->p_type == PT_GNU_RELRO) {
|
|
|
|
P->p_align = 1;
|
2017-01-05 02:56:15 +08:00
|
|
|
// The glibc dynamic loader rounds the size down, so we need to round up
|
|
|
|
// to protect the last page. This is a no-op on FreeBSD which always
|
|
|
|
// rounds up.
|
2017-07-27 15:46:50 +08:00
|
|
|
P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
|
2017-01-05 02:56:15 +08:00
|
|
|
}
|
2016-08-17 15:44:19 +08:00
|
|
|
|
2016-02-11 06:43:13 +08:00
|
|
|
// The TLS pointer goes after PT_TLS. At least glibc will align it,
|
|
|
|
// so round up the size to make sure the offsets are correct.
|
2017-07-27 15:46:50 +08:00
|
|
|
if (P->p_type == PT_TLS) {
|
|
|
|
Out::TlsPhdr = P;
|
|
|
|
if (P->p_memsz)
|
|
|
|
P->p_memsz = alignTo(P->p_memsz, P->p_align);
|
2015-10-24 05:45:59 +08:00
|
|
|
}
|
|
|
|
}
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2018-03-30 02:24:01 +08:00
|
|
|
// A helper struct for checkSectionOverlap.
|
|
|
|
namespace {
|
|
|
|
struct SectionOffset {
|
|
|
|
OutputSection *Sec;
|
|
|
|
uint64_t Offset;
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
2018-01-31 17:22:44 +08:00
|
|
|
// Check whether sections overlap for a specific address range (file offsets,
|
|
|
|
// load and virtual adresses).
|
2018-03-30 02:24:01 +08:00
|
|
|
static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections) {
|
2018-01-31 17:22:44 +08:00
|
|
|
std::sort(Sections.begin(), Sections.end(),
|
2018-03-30 02:24:01 +08:00
|
|
|
[=](const SectionOffset &A, const SectionOffset &B) {
|
|
|
|
return A.Offset < B.Offset;
|
2018-01-31 17:22:44 +08:00
|
|
|
});
|
2018-03-30 02:24:01 +08:00
|
|
|
|
2018-03-30 03:51:53 +08:00
|
|
|
// Finding overlap is easy given a vector is sorted by start position.
|
|
|
|
// If an element starts before the end of the previous element, they overlap.
|
|
|
|
for (size_t I = 1, End = Sections.size(); I < End; ++I) {
|
|
|
|
SectionOffset A = Sections[I - 1];
|
|
|
|
SectionOffset B = Sections[I];
|
|
|
|
if (B.Offset < A.Offset + A.Sec->Size)
|
|
|
|
errorOrWarn(
|
|
|
|
"section " + A.Sec->Name + " " + Name + " range overlaps with " +
|
|
|
|
B.Sec->Name + "\n>>> " + A.Sec->Name + " range is " +
|
|
|
|
rangeToString(A.Offset, A.Sec->Size) + "\n>>> " + B.Sec->Name +
|
|
|
|
" range is " + rangeToString(B.Offset, B.Sec->Size));
|
2018-01-31 17:22:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-03 20:39:28 +08:00
|
|
|
// Check for overlapping sections and address overflows.
|
2018-01-31 17:22:44 +08:00
|
|
|
//
|
|
|
|
// In this function we check that none of the output sections have overlapping
|
|
|
|
// file offsets. For SHF_ALLOC sections we also check that the load address
|
|
|
|
// ranges and the virtual address ranges don't overlap
|
2018-04-04 17:24:31 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::checkSections() {
|
2018-04-03 20:39:28 +08:00
|
|
|
// First, check that section's VAs fit in available address space for target.
|
|
|
|
for (OutputSection *OS : OutputSections)
|
|
|
|
if ((OS->Addr + OS->Size < OS->Addr) ||
|
|
|
|
(!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
|
|
|
|
errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
|
|
|
|
" of size 0x" + utohexstr(OS->Size) +
|
|
|
|
" exceeds available address space");
|
|
|
|
|
|
|
|
// Check for overlapping file offsets. In this case we need to skip any
|
|
|
|
// section marked as SHT_NOBITS. These sections don't actually occupy space in
|
|
|
|
// the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
|
|
|
|
// binary is specified only add SHF_ALLOC sections are added to the output
|
|
|
|
// file so we skip any non-allocated sections in that case.
|
2018-03-30 02:24:01 +08:00
|
|
|
std::vector<SectionOffset> FileOffs;
|
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
if (0 < Sec->Size && Sec->Type != SHT_NOBITS &&
|
|
|
|
(!Config->OFormatBinary || (Sec->Flags & SHF_ALLOC)))
|
|
|
|
FileOffs.push_back({Sec, Sec->Offset});
|
|
|
|
checkOverlap("file", FileOffs);
|
2018-01-31 17:22:44 +08:00
|
|
|
|
|
|
|
// When linking with -r there is no need to check for overlapping virtual/load
|
|
|
|
// addresses since those addresses will only be assigned when the final
|
|
|
|
// executable/shared object is created.
|
|
|
|
if (Config->Relocatable)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Checking for overlapping virtual and load addresses only needs to take
|
2018-02-23 10:05:48 +08:00
|
|
|
// into account SHF_ALLOC sections since others will not be loaded.
|
2018-01-31 17:22:44 +08:00
|
|
|
// Furthermore, we also need to skip SHF_TLS sections since these will be
|
|
|
|
// mapped to other addresses at runtime and can therefore have overlapping
|
|
|
|
// ranges in the file.
|
2018-03-30 02:24:01 +08:00
|
|
|
std::vector<SectionOffset> VMAs;
|
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
|
|
|
|
VMAs.push_back({Sec, Sec->Addr});
|
|
|
|
checkOverlap("virtual address", VMAs);
|
2018-01-31 17:22:44 +08:00
|
|
|
|
|
|
|
// Finally, check that the load addresses don't overlap. This will usually be
|
|
|
|
// the same as the virtual addresses but can be different when using a linker
|
|
|
|
// script with AT().
|
2018-03-30 02:24:01 +08:00
|
|
|
std::vector<SectionOffset> LMAs;
|
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
if (0 < Sec->Size && (Sec->Flags & SHF_ALLOC) && !(Sec->Flags & SHF_TLS))
|
|
|
|
LMAs.push_back({Sec, Sec->getLMA()});
|
|
|
|
checkOverlap("load address", LMAs);
|
2018-01-31 17:22:44 +08:00
|
|
|
}
|
|
|
|
|
2016-11-24 06:41:00 +08:00
|
|
|
// The entry point address is chosen in the following ways.
|
|
|
|
//
|
|
|
|
// 1. the '-e' entry command-line option;
|
|
|
|
// 2. the ENTRY(symbol) command in a linker control script;
|
2017-11-30 09:04:26 +08:00
|
|
|
// 3. the value of the symbol _start, if present;
|
2017-10-25 03:53:51 +08:00
|
|
|
// 4. the number represented by the entry symbol, if it is a number;
|
|
|
|
// 5. the address of the first byte of the .text section, if present;
|
|
|
|
// 6. the address 0.
|
2017-04-06 05:37:09 +08:00
|
|
|
template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {
|
2017-10-25 03:53:51 +08:00
|
|
|
// Case 1, 2 or 3
|
2017-11-04 05:21:47 +08:00
|
|
|
if (Symbol *B = Symtab->find(Config->Entry))
|
2017-03-17 19:56:54 +08:00
|
|
|
return B->getVA();
|
2017-10-25 03:53:51 +08:00
|
|
|
|
|
|
|
// Case 4
|
2016-12-07 11:23:06 +08:00
|
|
|
uint64_t Addr;
|
2017-05-16 16:19:25 +08:00
|
|
|
if (to_integer(Config->Entry, Addr))
|
2016-12-07 11:23:06 +08:00
|
|
|
return Addr;
|
2016-11-24 06:41:00 +08:00
|
|
|
|
2017-10-25 03:53:51 +08:00
|
|
|
// Case 5
|
2017-07-28 03:22:43 +08:00
|
|
|
if (OutputSection *Sec = findSection(".text")) {
|
2016-12-07 12:06:21 +08:00
|
|
|
if (Config->WarnMissingEntry)
|
2016-12-07 10:26:16 +08:00
|
|
|
warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
|
|
|
|
utohexstr(Sec->Addr));
|
2016-11-24 06:41:00 +08:00
|
|
|
return Sec->Addr;
|
|
|
|
}
|
|
|
|
|
2017-10-25 03:53:51 +08:00
|
|
|
// Case 6
|
2016-12-07 12:06:21 +08:00
|
|
|
if (Config->WarnMissingEntry)
|
2016-12-07 10:26:16 +08:00
|
|
|
warn("cannot find entry symbol " + Config->Entry +
|
|
|
|
"; not setting start address");
|
2016-10-20 08:07:36 +08:00
|
|
|
return 0;
|
2015-12-24 16:37:34 +08:00
|
|
|
}
|
|
|
|
|
2016-02-26 03:28:37 +08:00
|
|
|
static uint16_t getELFType() {
|
2017-03-18 07:29:01 +08:00
|
|
|
if (Config->Pic)
|
2016-02-26 03:28:37 +08:00
|
|
|
return ET_DYN;
|
|
|
|
if (Config->Relocatable)
|
|
|
|
return ET_REL;
|
|
|
|
return ET_EXEC;
|
|
|
|
}
|
|
|
|
|
2018-02-23 19:28:57 +08:00
|
|
|
static uint8_t getAbiVersion() {
|
2018-03-29 05:53:10 +08:00
|
|
|
// MIPS non-PIC executable gets ABI version 1.
|
|
|
|
if (Config->EMachine == EM_MIPS && getELFType() == ET_EXEC &&
|
|
|
|
(Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
|
|
|
|
return 1;
|
2018-02-23 19:28:57 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::writeHeader() {
|
|
|
|
uint8_t *Buf = Buffer->getBufferStart();
|
2018-03-31 04:49:34 +08:00
|
|
|
// For executable segments, the trap instructions are written before writing
|
|
|
|
// the header. Setting Elf header bytes to zero ensures that any unused bytes
|
|
|
|
// in header are zero-cleared, instead of having trap instructions.
|
|
|
|
memset(Buf, 0, sizeof(Elf_Ehdr));
|
2015-10-24 06:44:39 +08:00
|
|
|
memcpy(Buf, "\177ELF", 4);
|
|
|
|
|
2015-10-25 01:57:40 +08:00
|
|
|
// Write the ELF header.
|
2015-09-09 05:57:31 +08:00
|
|
|
auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf);
|
2017-04-06 05:08:47 +08:00
|
|
|
EHdr->e_ident[EI_CLASS] = Config->Is64 ? ELFCLASS64 : ELFCLASS32;
|
|
|
|
EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB;
|
2015-07-25 05:03:07 +08:00
|
|
|
EHdr->e_ident[EI_VERSION] = EV_CURRENT;
|
2016-10-27 22:00:51 +08:00
|
|
|
EHdr->e_ident[EI_OSABI] = Config->OSABI;
|
2018-02-23 19:28:57 +08:00
|
|
|
EHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
|
2016-02-26 03:28:37 +08:00
|
|
|
EHdr->e_type = getELFType();
|
2016-10-27 22:00:51 +08:00
|
|
|
EHdr->e_machine = Config->EMachine;
|
2015-07-25 05:03:07 +08:00
|
|
|
EHdr->e_version = EV_CURRENT;
|
2016-11-24 06:41:00 +08:00
|
|
|
EHdr->e_entry = getEntryAddr();
|
2015-07-29 08:30:10 +08:00
|
|
|
EHdr->e_shoff = SectionHeaderOff;
|
2017-10-25 01:01:40 +08:00
|
|
|
EHdr->e_flags = Config->EFlags;
|
2015-09-09 05:57:31 +08:00
|
|
|
EHdr->e_ehsize = sizeof(Elf_Ehdr);
|
2015-10-11 06:34:30 +08:00
|
|
|
EHdr->e_phnum = Phdrs.size();
|
2015-09-09 05:57:31 +08:00
|
|
|
EHdr->e_shentsize = sizeof(Elf_Shdr);
|
2017-07-28 03:22:43 +08:00
|
|
|
EHdr->e_shnum = OutputSections.size() + 1;
|
2017-06-01 04:17:44 +08:00
|
|
|
EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
|
2015-10-25 01:57:40 +08:00
|
|
|
|
2016-02-25 16:23:37 +08:00
|
|
|
if (!Config->Relocatable) {
|
|
|
|
EHdr->e_phoff = sizeof(Elf_Ehdr);
|
|
|
|
EHdr->e_phentsize = sizeof(Elf_Phdr);
|
|
|
|
}
|
|
|
|
|
2015-10-25 01:57:40 +08:00
|
|
|
// Write the program header table.
|
2016-02-11 06:43:13 +08:00
|
|
|
auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
|
2017-07-27 15:46:50 +08:00
|
|
|
for (PhdrEntry *P : Phdrs) {
|
|
|
|
HBuf->p_type = P->p_type;
|
|
|
|
HBuf->p_flags = P->p_flags;
|
|
|
|
HBuf->p_offset = P->p_offset;
|
|
|
|
HBuf->p_vaddr = P->p_vaddr;
|
|
|
|
HBuf->p_paddr = P->p_paddr;
|
|
|
|
HBuf->p_filesz = P->p_filesz;
|
|
|
|
HBuf->p_memsz = P->p_memsz;
|
|
|
|
HBuf->p_align = P->p_align;
|
2016-12-20 01:01:01 +08:00
|
|
|
++HBuf;
|
|
|
|
}
|
2015-09-09 06:55:28 +08:00
|
|
|
|
2015-10-25 01:57:40 +08:00
|
|
|
// Write the section header table. Note that the first table entry is null.
|
2016-02-26 07:58:21 +08:00
|
|
|
auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
|
|
|
Sec->writeHeaderTo<ELFT>(++SHdrs);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:40:37 +08:00
|
|
|
// Open a result file.
|
2016-04-02 01:24:19 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::openFile() {
|
2017-04-06 05:37:09 +08:00
|
|
|
if (!Config->Is64 && FileSize > UINT32_MAX) {
|
|
|
|
error("output file too large: " + Twine(FileSize) + " bytes");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-06 01:40:37 +08:00
|
|
|
unlinkAsync(Config->OutputFile);
|
2017-12-12 07:30:54 +08:00
|
|
|
unsigned Flags = 0;
|
|
|
|
if (!Config->Relocatable)
|
|
|
|
Flags = FileOutputBuffer::F_executable;
|
2017-11-08 09:05:52 +08:00
|
|
|
Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
2017-12-12 07:30:54 +08:00
|
|
|
FileOutputBuffer::create(Config->OutputFile, FileSize, Flags);
|
2016-12-06 01:40:37 +08:00
|
|
|
|
2017-11-08 09:05:52 +08:00
|
|
|
if (!BufferOrErr)
|
|
|
|
error("failed to open " + Config->OutputFile + ": " +
|
|
|
|
llvm::toString(BufferOrErr.takeError()));
|
2016-04-02 01:24:19 +08:00
|
|
|
else
|
2016-07-15 09:38:54 +08:00
|
|
|
Buffer = std::move(*BufferOrErr);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2016-08-25 17:05:47 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
|
|
|
|
uint8_t *Buf = Buffer->getBufferStart();
|
2017-07-28 03:22:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
2016-11-09 09:42:41 +08:00
|
|
|
if (Sec->Flags & SHF_ALLOC)
|
2017-07-28 03:22:43 +08:00
|
|
|
Sec->writeTo<ELFT>(Buf + Sec->Offset);
|
2016-08-25 17:05:47 +08:00
|
|
|
}
|
|
|
|
|
2017-08-15 05:18:12 +08:00
|
|
|
static void fillTrap(uint8_t *I, uint8_t *End) {
|
2017-08-21 16:31:14 +08:00
|
|
|
for (; I + 4 <= End; I += 4)
|
2017-08-03 00:35:00 +08:00
|
|
|
memcpy(I, &Target->TrapInstr, 4);
|
|
|
|
}
|
|
|
|
|
2017-08-15 05:18:12 +08:00
|
|
|
// Fill the last page of executable segments with trap instructions
|
|
|
|
// instead of leaving them as zero. Even though it is not required by any
|
|
|
|
// standard, it is in general a good thing to do for security reasons.
|
|
|
|
//
|
|
|
|
// We'll leave other pages in segments as-is because the rest will be
|
|
|
|
// overwritten by output sections.
|
2017-08-03 00:35:00 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
|
2017-10-11 09:34:51 +08:00
|
|
|
if (Script->HasSectionsCommand)
|
2017-08-03 00:35:00 +08:00
|
|
|
return;
|
|
|
|
|
2017-08-15 05:18:12 +08:00
|
|
|
// Fill the last page.
|
2017-08-03 00:35:00 +08:00
|
|
|
uint8_t *Buf = Buffer->getBufferStart();
|
2017-08-15 05:18:12 +08:00
|
|
|
for (PhdrEntry *P : Phdrs)
|
|
|
|
if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
|
|
|
|
fillTrap(Buf + alignDown(P->p_offset + P->p_filesz, Target->PageSize),
|
|
|
|
Buf + alignTo(P->p_offset + P->p_filesz, Target->PageSize));
|
2017-08-03 00:35:00 +08:00
|
|
|
|
2017-08-15 05:18:12 +08:00
|
|
|
// Round up the file size of the last segment to the page boundary iff it is
|
2017-10-27 12:59:33 +08:00
|
|
|
// an executable segment to ensure that other tools don't accidentally
|
2017-08-15 05:18:12 +08:00
|
|
|
// trim the instruction padding (e.g. when stripping the file).
|
2017-10-27 13:08:39 +08:00
|
|
|
PhdrEntry *Last = nullptr;
|
|
|
|
for (PhdrEntry *P : Phdrs)
|
|
|
|
if (P->p_type == PT_LOAD)
|
|
|
|
Last = P;
|
|
|
|
|
|
|
|
if (Last && (Last->p_flags & PF_X))
|
|
|
|
Last->p_memsz = Last->p_filesz = alignTo(Last->p_filesz, Target->PageSize);
|
2017-08-03 00:35:00 +08:00
|
|
|
}
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
// Write section contents to a mmap'ed file.
|
|
|
|
template <class ELFT> void Writer<ELFT>::writeSections() {
|
|
|
|
uint8_t *Buf = Buffer->getBufferStart();
|
[ELF2/PPC64] Resolve local-call relocations using the correct function-descriptor values
Under PPC64 ELF v1 ABI, the symbols associated with each function name don't
point directly to the code in the .text section (or similar), but rather to a
function descriptor structure in a special data section named .opd. The
elements in the .opd structure include a pointer to the actual code, and a the
relevant TOC base value. Both of these are themselves set by relocations.
When we have a local call, we need the relevant relocation to refer directly to
the target code, not to the function-descriptor in the .opd section. Only when
we have a .plt stub do we care about the address of the .opd function
descriptor itself.
So we make a few changes here:
1. Always write .opd first, so that its relocated data values are available
for later use when writing the text sections. Record a pointer to the .opd
structure, and its corresponding buffer.
2. When processing a relative branch relocation under ppc64, if the
destination points into the .opd section, read the code pointer out of the
function descriptor structure and use that instead.
This this, I can link, and run, a dynamically-compiled "hello world"
application on big-Endian PPC64/Linux (ELF v1 ABI) using lld.
llvm-svn: 250122
2015-10-13 07:16:53 +08:00
|
|
|
|
2016-08-09 09:35:37 +08:00
|
|
|
// PPC64 needs to process relocations in the .opd section
|
|
|
|
// before processing relocations in code-containing sections.
|
2017-07-28 03:22:43 +08:00
|
|
|
if (auto *OpdCmd = findSection(".opd")) {
|
|
|
|
Out::Opd = OpdCmd;
|
2017-02-27 10:31:26 +08:00
|
|
|
Out::OpdBuf = Buf + Out::Opd->Offset;
|
2017-05-25 02:08:04 +08:00
|
|
|
OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset);
|
2015-10-13 22:45:51 +08:00
|
|
|
}
|
[ELF2/PPC64] Resolve local-call relocations using the correct function-descriptor values
Under PPC64 ELF v1 ABI, the symbols associated with each function name don't
point directly to the code in the .text section (or similar), but rather to a
function descriptor structure in a special data section named .opd. The
elements in the .opd structure include a pointer to the actual code, and a the
relevant TOC base value. Both of these are themselves set by relocations.
When we have a local call, we need the relevant relocation to refer directly to
the target code, not to the function-descriptor in the .opd section. Only when
we have a .plt stub do we care about the address of the .opd function
descriptor itself.
So we make a few changes here:
1. Always write .opd first, so that its relocated data values are available
for later use when writing the text sections. Record a pointer to the .opd
structure, and its corresponding buffer.
2. When processing a relative branch relocation under ppc64, if the
destination points into the .opd section, read the code pointer out of the
function descriptor structure and use that instead.
This this, I can link, and run, a dynamically-compiled "hello world"
application on big-Endian PPC64/Linux (ELF v1 ABI) using lld.
llvm-svn: 250122
2015-10-13 07:16:53 +08:00
|
|
|
|
2017-10-27 11:14:24 +08:00
|
|
|
OutputSection *EhFrameHdr = nullptr;
|
|
|
|
if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
|
|
|
|
EhFrameHdr = InX::EhFrameHdr->getParent();
|
2017-02-11 09:40:49 +08:00
|
|
|
|
|
|
|
// 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.
|
2017-10-07 04:12:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
2017-02-11 09:40:49 +08:00
|
|
|
if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
|
2017-07-28 03:22:43 +08:00
|
|
|
Sec->writeTo<ELFT>(Buf + Sec->Offset);
|
2017-02-11 09:40:49 +08:00
|
|
|
|
2017-10-07 04:12:43 +08:00
|
|
|
for (OutputSection *Sec : OutputSections)
|
2017-02-27 10:31:26 +08:00
|
|
|
if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
|
2017-02-11 09:40:49 +08:00
|
|
|
Sec->Type != SHT_RELA)
|
2017-07-28 03:22:43 +08:00
|
|
|
Sec->writeTo<ELFT>(Buf + Sec->Offset);
|
2016-08-31 15:43:50 +08:00
|
|
|
|
|
|
|
// The .eh_frame_hdr depends on .eh_frame section contents, therefore
|
|
|
|
// it should be written after .eh_frame is written.
|
2017-07-28 03:22:43 +08:00
|
|
|
if (EhFrameHdr)
|
|
|
|
EhFrameHdr->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
2015-10-10 05:07:25 +08:00
|
|
|
|
ELF: Implement --build-id.
This patch implements --build-id. After the linker creates an output file
in the memory buffer, it computes the FNV1 hash of the resulting file
and set the hash to the .note section as a build-id.
GNU ld and gold have the same feature, but their default choice of the
hash function is different. Their default is SHA1.
We made a deliberate choice to not use a secure hash function for the
sake of performance. Computing a secure hash is slow -- for example,
MD5 throughput is usually 400 MB/s or so. SHA1 is slower than that.
As a result, if you pass --build-id to gold, then the linker becomes about
10% slower than that without the option. We observed a similar degradation
in an experimental implementation of build-id for LLD. On the other hand,
we observed only 1-2% performance degradation with the FNV hash.
Since build-id is not for digital certificate or anything, we think that
a very small probability of collision is acceptable.
We considered using other signals such as using input file timestamps as
inputs to a secure hash function. But such signals would have an issue
with build reproducibility (if you build a binary from the same source
tree using the same toolchain, the build id should become the same.)
GNU linkers accepts --build-id=<style> option where style is one of
"MD5", "SHA1", or an arbitrary hex string. That option is out of scope
of this patch.
http://reviews.llvm.org/D18091
llvm-svn: 263292
2016-03-12 04:51:53 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::writeBuildId() {
|
2017-06-01 04:17:44 +08:00
|
|
|
if (!InX::BuildId || !InX::BuildId->getParent())
|
ELF: Implement --build-id.
This patch implements --build-id. After the linker creates an output file
in the memory buffer, it computes the FNV1 hash of the resulting file
and set the hash to the .note section as a build-id.
GNU ld and gold have the same feature, but their default choice of the
hash function is different. Their default is SHA1.
We made a deliberate choice to not use a secure hash function for the
sake of performance. Computing a secure hash is slow -- for example,
MD5 throughput is usually 400 MB/s or so. SHA1 is slower than that.
As a result, if you pass --build-id to gold, then the linker becomes about
10% slower than that without the option. We observed a similar degradation
in an experimental implementation of build-id for LLD. On the other hand,
we observed only 1-2% performance degradation with the FNV hash.
Since build-id is not for digital certificate or anything, we think that
a very small probability of collision is acceptable.
We considered using other signals such as using input file timestamps as
inputs to a secure hash function. But such signals would have an issue
with build reproducibility (if you build a binary from the same source
tree using the same toolchain, the build id should become the same.)
GNU linkers accepts --build-id=<style> option where style is one of
"MD5", "SHA1", or an arbitrary hex string. That option is out of scope
of this patch.
http://reviews.llvm.org/D18091
llvm-svn: 263292
2016-03-12 04:51:53 +08:00
|
|
|
return;
|
|
|
|
|
2016-09-02 06:43:03 +08:00
|
|
|
// Compute a hash of all sections of the output file.
|
ELF: Implement --build-id.
This patch implements --build-id. After the linker creates an output file
in the memory buffer, it computes the FNV1 hash of the resulting file
and set the hash to the .note section as a build-id.
GNU ld and gold have the same feature, but their default choice of the
hash function is different. Their default is SHA1.
We made a deliberate choice to not use a secure hash function for the
sake of performance. Computing a secure hash is slow -- for example,
MD5 throughput is usually 400 MB/s or so. SHA1 is slower than that.
As a result, if you pass --build-id to gold, then the linker becomes about
10% slower than that without the option. We observed a similar degradation
in an experimental implementation of build-id for LLD. On the other hand,
we observed only 1-2% performance degradation with the FNV hash.
Since build-id is not for digital certificate or anything, we think that
a very small probability of collision is acceptable.
We considered using other signals such as using input file timestamps as
inputs to a secure hash function. But such signals would have an issue
with build reproducibility (if you build a binary from the same source
tree using the same toolchain, the build id should become the same.)
GNU linkers accepts --build-id=<style> option where style is one of
"MD5", "SHA1", or an arbitrary hex string. That option is out of scope
of this patch.
http://reviews.llvm.org/D18091
llvm-svn: 263292
2016-03-12 04:51:53 +08:00
|
|
|
uint8_t *Start = Buffer->getBufferStart();
|
2016-09-02 06:43:03 +08:00
|
|
|
uint8_t *End = Start + FileSize;
|
2017-05-12 06:02:41 +08:00
|
|
|
InX::BuildId->writeBuildId({Start, End});
|
ELF: Implement --build-id.
This patch implements --build-id. After the linker creates an output file
in the memory buffer, it computes the FNV1 hash of the resulting file
and set the hash to the .note section as a build-id.
GNU ld and gold have the same feature, but their default choice of the
hash function is different. Their default is SHA1.
We made a deliberate choice to not use a secure hash function for the
sake of performance. Computing a secure hash is slow -- for example,
MD5 throughput is usually 400 MB/s or so. SHA1 is slower than that.
As a result, if you pass --build-id to gold, then the linker becomes about
10% slower than that without the option. We observed a similar degradation
in an experimental implementation of build-id for LLD. On the other hand,
we observed only 1-2% performance degradation with the FNV hash.
Since build-id is not for digital certificate or anything, we think that
a very small probability of collision is acceptable.
We considered using other signals such as using input file timestamps as
inputs to a secure hash function. But such signals would have an issue
with build reproducibility (if you build a binary from the same source
tree using the same toolchain, the build id should become the same.)
GNU linkers accepts --build-id=<style> option where style is one of
"MD5", "SHA1", or an arbitrary hex string. That option is out of scope
of this patch.
http://reviews.llvm.org/D18091
llvm-svn: 263292
2016-03-12 04:51:53 +08:00
|
|
|
}
|
|
|
|
|
2016-08-09 11:38:23 +08:00
|
|
|
template void elf::writeResult<ELF32LE>();
|
|
|
|
template void elf::writeResult<ELF32BE>();
|
|
|
|
template void elf::writeResult<ELF64LE>();
|
|
|
|
template void elf::writeResult<ELF64BE>();
|