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"
|
2015-08-06 07:51:50 +08:00
|
|
|
#include "Config.h"
|
2015-09-22 05:38:08 +08:00
|
|
|
#include "OutputSections.h"
|
2015-08-06 07:24:46 +08:00
|
|
|
#include "SymbolTable.h"
|
2015-09-23 02:19:46 +08:00
|
|
|
#include "Target.h"
|
2015-08-12 08:00:24 +08:00
|
|
|
|
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"
|
2015-08-06 07:24:46 +08:00
|
|
|
#include "llvm/Support/FileOutputBuffer.h"
|
2015-12-10 17:12:18 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2015-10-16 01:11:03 +08:00
|
|
|
#include "llvm/Support/StringSaver.h"
|
2015-07-25 05:03:07 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::ELF;
|
|
|
|
using namespace llvm::object;
|
|
|
|
|
|
|
|
using namespace lld;
|
|
|
|
using namespace lld::elf2;
|
|
|
|
|
2015-08-06 07:24:46 +08:00
|
|
|
namespace {
|
|
|
|
// The writer writes a SymbolTable result to a file.
|
|
|
|
template <class ELFT> class Writer {
|
|
|
|
public:
|
2015-09-09 05:57:31 +08:00
|
|
|
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
|
2015-09-17 04:45:57 +08:00
|
|
|
typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range;
|
2015-09-16 23:54:15 +08:00
|
|
|
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
|
2015-10-10 05:07:25 +08:00
|
|
|
Writer(SymbolTable<ELFT> &S) : Symtab(S) {}
|
2015-08-06 07:24:46 +08:00
|
|
|
void run();
|
|
|
|
|
|
|
|
private:
|
2015-10-09 07:49:30 +08:00
|
|
|
void copyLocalSymbols();
|
2015-12-26 15:50:39 +08:00
|
|
|
void addReservedSymbols();
|
2016-01-29 06:56:29 +08:00
|
|
|
bool createSections();
|
2015-12-26 15:50:41 +08:00
|
|
|
void addPredefinedSections();
|
2015-12-25 15:38:58 +08:00
|
|
|
|
2015-09-17 22:02:10 +08:00
|
|
|
template <bool isRela>
|
2015-11-12 03:54:14 +08:00
|
|
|
void scanRelocs(InputSectionBase<ELFT> &C,
|
2015-09-17 22:02:10 +08:00
|
|
|
iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels);
|
2015-12-25 15:38:58 +08:00
|
|
|
|
2015-11-11 23:29:50 +08:00
|
|
|
void scanRelocs(InputSection<ELFT> &C);
|
2015-11-12 03:54:14 +08:00
|
|
|
void scanRelocs(InputSectionBase<ELFT> &S, const Elf_Shdr &RelSec);
|
2015-12-23 23:20:38 +08:00
|
|
|
void updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr, uintX_t VA);
|
2015-08-06 07:24:46 +08:00
|
|
|
void assignAddresses();
|
2015-11-12 17:52:08 +08:00
|
|
|
void buildSectionMap();
|
2015-12-26 18:52:26 +08:00
|
|
|
void fixAbsoluteSymbols();
|
2016-02-03 06:48:04 +08:00
|
|
|
bool openFile();
|
2015-08-06 07:24:46 +08:00
|
|
|
void writeHeader();
|
|
|
|
void writeSections();
|
2015-11-12 17:52:08 +08:00
|
|
|
bool isDiscarded(InputSectionBase<ELFT> *IS) const;
|
|
|
|
StringRef getOutputSectionName(StringRef S) const;
|
2015-09-12 02:49:42 +08:00
|
|
|
bool needsInterpSection() const {
|
2015-10-08 05:25:39 +08:00
|
|
|
return !Symtab.getSharedFiles().empty() && !Config->DynamicLinker.empty();
|
2015-09-12 02:49:42 +08:00
|
|
|
}
|
2015-10-07 04:39:09 +08:00
|
|
|
bool isOutputDynamic() const {
|
2015-10-08 05:25:39 +08:00
|
|
|
return !Symtab.getSharedFiles().empty() || Config->Shared;
|
2015-09-12 06:42:45 +08:00
|
|
|
}
|
2015-10-24 05:45:59 +08:00
|
|
|
int getPhdrsNum() const;
|
2015-08-06 07:24:46 +08:00
|
|
|
|
2016-01-06 00:35:43 +08:00
|
|
|
OutputSection<ELFT> *getBss();
|
2015-12-25 00:23:37 +08:00
|
|
|
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
|
2015-12-26 18:07:03 +08:00
|
|
|
void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
|
2015-11-04 05:35:14 +08:00
|
|
|
|
2015-08-06 07:24:46 +08:00
|
|
|
std::unique_ptr<llvm::FileOutputBuffer> Buffer;
|
2015-09-18 03:58:07 +08:00
|
|
|
|
2015-10-16 01:11:03 +08:00
|
|
|
BumpPtrAllocator Alloc;
|
2015-10-16 06:27:29 +08:00
|
|
|
std::vector<OutputSectionBase<ELFT> *> OutputSections;
|
2015-12-26 15:01:26 +08:00
|
|
|
std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
|
2015-09-09 01:39:39 +08:00
|
|
|
unsigned getNumSections() const { return OutputSections.size() + 1; }
|
2015-08-06 07:24:46 +08:00
|
|
|
|
2015-12-26 17:47:57 +08:00
|
|
|
void addRelIpltSymbols();
|
2015-12-26 17:48:00 +08:00
|
|
|
void addStartEndSymbols();
|
2015-10-16 06:27:29 +08:00
|
|
|
void addStartStopSymbols(OutputSectionBase<ELFT> *Sec);
|
2015-10-12 03:45:58 +08:00
|
|
|
void setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t FileOff,
|
2015-10-24 05:45:59 +08:00
|
|
|
uintX_t VA, uintX_t Size, uintX_t Align);
|
2015-10-16 06:27:29 +08:00
|
|
|
void copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT> *From);
|
2015-10-11 06:34:30 +08:00
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
bool HasRelro = false;
|
2015-10-10 05:07:25 +08:00
|
|
|
SymbolTable<ELFT> &Symtab;
|
2015-10-11 07:59:57 +08:00
|
|
|
std::vector<Elf_Phdr> Phdrs;
|
2015-09-18 03:58:07 +08:00
|
|
|
|
2015-08-12 07:14:13 +08:00
|
|
|
uintX_t FileSize;
|
2015-08-06 07:24:46 +08:00
|
|
|
uintX_t SectionHeaderOff;
|
2015-11-12 17:52:08 +08:00
|
|
|
|
|
|
|
llvm::StringMap<llvm::StringRef> InputToOutputSection;
|
2016-01-23 09:49:37 +08:00
|
|
|
|
|
|
|
// Flag to force GOT to be in output if we have relocations
|
|
|
|
// that relies on its address.
|
|
|
|
bool HasGotOffRel = false;
|
2015-08-06 07:24:46 +08:00
|
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
|
2016-01-12 09:33:23 +08:00
|
|
|
template <class ELFT> static bool shouldUseRela() { return ELFT::Is64Bits; }
|
2015-12-17 07:33:56 +08:00
|
|
|
|
2016-01-07 04:11:55 +08:00
|
|
|
template <class ELFT> void elf2::writeResult(SymbolTable<ELFT> *Symtab) {
|
2015-10-08 03:18:16 +08:00
|
|
|
// Initialize output sections that are handled by Writer specially.
|
|
|
|
// Don't reorder because the order of initialization matters.
|
2015-10-16 06:27:29 +08:00
|
|
|
InterpSection<ELFT> Interp;
|
2015-10-08 03:18:16 +08:00
|
|
|
Out<ELFT>::Interp = &Interp;
|
2015-10-21 01:21:35 +08:00
|
|
|
StringTableSection<ELFT> ShStrTab(".shstrtab", false);
|
|
|
|
Out<ELFT>::ShStrTab = &ShStrTab;
|
|
|
|
StringTableSection<ELFT> StrTab(".strtab", false);
|
2015-10-24 16:52:46 +08:00
|
|
|
if (!Config->StripAll)
|
|
|
|
Out<ELFT>::StrTab = &StrTab;
|
2016-02-02 08:35:49 +08:00
|
|
|
else
|
|
|
|
Out<ELFT>::StrTab = nullptr;
|
2015-10-21 01:21:35 +08:00
|
|
|
StringTableSection<ELFT> DynStrTab(".dynstr", true);
|
2015-10-08 03:18:16 +08:00
|
|
|
Out<ELFT>::DynStrTab = &DynStrTab;
|
|
|
|
GotSection<ELFT> Got;
|
|
|
|
Out<ELFT>::Got = &Got;
|
2015-10-20 16:54:27 +08:00
|
|
|
GotPltSection<ELFT> GotPlt;
|
2016-01-29 09:49:32 +08:00
|
|
|
if (Target->UseLazyBinding)
|
2015-10-20 16:54:27 +08:00
|
|
|
Out<ELFT>::GotPlt = &GotPlt;
|
2016-02-02 08:35:49 +08:00
|
|
|
else
|
|
|
|
Out<ELFT>::GotPlt = nullptr;
|
2015-10-08 03:18:16 +08:00
|
|
|
PltSection<ELFT> Plt;
|
|
|
|
Out<ELFT>::Plt = &Plt;
|
2015-10-24 16:52:46 +08:00
|
|
|
std::unique_ptr<SymbolTableSection<ELFT>> SymTab;
|
|
|
|
if (!Config->StripAll) {
|
|
|
|
SymTab.reset(new SymbolTableSection<ELFT>(*Symtab, *Out<ELFT>::StrTab));
|
|
|
|
Out<ELFT>::SymTab = SymTab.get();
|
2016-02-02 08:35:49 +08:00
|
|
|
} else {
|
|
|
|
Out<ELFT>::SymTab = nullptr;
|
2015-10-24 16:52:46 +08:00
|
|
|
}
|
2015-10-08 03:18:16 +08:00
|
|
|
SymbolTableSection<ELFT> DynSymTab(*Symtab, *Out<ELFT>::DynStrTab);
|
|
|
|
Out<ELFT>::DynSymTab = &DynSymTab;
|
|
|
|
HashTableSection<ELFT> HashTab;
|
2015-10-22 16:21:35 +08:00
|
|
|
if (Config->SysvHash)
|
|
|
|
Out<ELFT>::HashTab = &HashTab;
|
2016-02-02 08:35:49 +08:00
|
|
|
else
|
|
|
|
Out<ELFT>::HashTab = nullptr;
|
2015-10-22 16:21:35 +08:00
|
|
|
GnuHashTableSection<ELFT> GnuHashTab;
|
|
|
|
if (Config->GnuHash)
|
|
|
|
Out<ELFT>::GnuHashTab = &GnuHashTab;
|
2016-02-02 08:35:49 +08:00
|
|
|
else
|
|
|
|
Out<ELFT>::GnuHashTab = nullptr;
|
2015-12-17 07:33:56 +08:00
|
|
|
bool IsRela = shouldUseRela<ELFT>();
|
2015-10-20 16:54:27 +08:00
|
|
|
RelocationSection<ELFT> RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela);
|
2015-10-08 03:18:16 +08:00
|
|
|
Out<ELFT>::RelaDyn = &RelaDyn;
|
2015-10-20 16:54:27 +08:00
|
|
|
RelocationSection<ELFT> RelaPlt(IsRela ? ".rela.plt" : ".rel.plt", IsRela);
|
2016-01-29 09:49:32 +08:00
|
|
|
if (Target->UseLazyBinding)
|
2015-10-20 16:54:27 +08:00
|
|
|
Out<ELFT>::RelaPlt = &RelaPlt;
|
2016-02-02 08:35:49 +08:00
|
|
|
else
|
|
|
|
Out<ELFT>::RelaPlt = nullptr;
|
2015-10-08 03:18:16 +08:00
|
|
|
DynamicSection<ELFT> Dynamic(*Symtab);
|
|
|
|
Out<ELFT>::Dynamic = &Dynamic;
|
2016-01-15 21:34:52 +08:00
|
|
|
EhFrameHeader<ELFT> EhFrameHdr;
|
|
|
|
Out<ELFT>::EhFrameHdr = &EhFrameHdr;
|
2015-10-08 03:18:16 +08:00
|
|
|
|
2015-10-08 05:25:39 +08:00
|
|
|
Writer<ELFT>(*Symtab).run();
|
2015-10-08 03:18:16 +08:00
|
|
|
}
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
// The main function of the writer.
|
2015-08-06 07:24:46 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::run() {
|
2015-11-12 17:52:08 +08:00
|
|
|
buildSectionMap();
|
2015-10-09 07:49:30 +08:00
|
|
|
if (!Config->DiscardAll)
|
|
|
|
copyLocalSymbols();
|
2015-12-26 15:50:39 +08:00
|
|
|
addReservedSymbols();
|
2016-01-29 06:56:29 +08:00
|
|
|
if (!createSections())
|
|
|
|
return;
|
2015-07-25 05:03:07 +08:00
|
|
|
assignAddresses();
|
2015-12-26 18:52:26 +08:00
|
|
|
fixAbsoluteSymbols();
|
2016-02-03 06:48:04 +08:00
|
|
|
if (!openFile())
|
|
|
|
return;
|
2015-07-25 05:03:07 +08:00
|
|
|
writeHeader();
|
|
|
|
writeSections();
|
2016-02-02 07:28:21 +08:00
|
|
|
if (HasError)
|
|
|
|
return;
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
fatal(Buffer->commit());
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2015-08-14 01:04:50 +08:00
|
|
|
namespace {
|
|
|
|
template <bool Is64Bits> struct SectionKey {
|
|
|
|
typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;
|
|
|
|
StringRef Name;
|
2015-10-03 05:13:19 +08:00
|
|
|
uint32_t Type;
|
|
|
|
uintX_t Flags;
|
2015-10-20 05:00:02 +08:00
|
|
|
uintX_t EntSize;
|
2015-08-14 01:04:50 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
namespace llvm {
|
|
|
|
template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> {
|
|
|
|
static SectionKey<Is64Bits> getEmptyKey() {
|
2015-10-20 05:00:02 +08:00
|
|
|
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0,
|
|
|
|
0};
|
2015-08-14 01:04:50 +08:00
|
|
|
}
|
|
|
|
static SectionKey<Is64Bits> getTombstoneKey() {
|
|
|
|
return SectionKey<Is64Bits>{DenseMapInfo<StringRef>::getTombstoneKey(), 0,
|
2015-10-20 05:00:02 +08:00
|
|
|
0, 0};
|
2015-08-14 01:04:50 +08:00
|
|
|
}
|
|
|
|
static unsigned getHashValue(const SectionKey<Is64Bits> &Val) {
|
2015-10-20 05:00:02 +08:00
|
|
|
return hash_combine(Val.Name, Val.Type, Val.Flags, Val.EntSize);
|
2015-08-14 01:04:50 +08:00
|
|
|
}
|
|
|
|
static bool isEqual(const SectionKey<Is64Bits> &LHS,
|
|
|
|
const SectionKey<Is64Bits> &RHS) {
|
|
|
|
return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
|
2015-10-20 05:00:02 +08:00
|
|
|
LHS.Type == RHS.Type && LHS.Flags == RHS.Flags &&
|
|
|
|
LHS.EntSize == RHS.EntSize;
|
2015-08-14 01:04:50 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-01-21 17:14:22 +08:00
|
|
|
template <class ELFT, class RelT>
|
|
|
|
static bool handleTlsRelocation(unsigned Type, SymbolBody *Body,
|
|
|
|
InputSectionBase<ELFT> &C, RelT &RI) {
|
2016-01-29 10:33:45 +08:00
|
|
|
if (Target->isTlsLocalDynamicRel(Type)) {
|
2016-01-29 08:20:12 +08:00
|
|
|
if (Target->canRelaxTls(Type, nullptr))
|
2016-01-21 17:14:22 +08:00
|
|
|
return true;
|
2016-02-05 08:10:02 +08:00
|
|
|
if (Out<ELFT>::Got->addTlsIndex())
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel,
|
|
|
|
DynamicReloc<ELFT>::Off_LTlsIndex,
|
|
|
|
nullptr});
|
2016-01-21 17:14:22 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Body || !Body->isTls())
|
|
|
|
return false;
|
|
|
|
|
2016-01-29 10:33:45 +08:00
|
|
|
if (Target->isTlsGlobalDynamicRel(Type)) {
|
2016-02-05 08:10:02 +08:00
|
|
|
if (!Target->canRelaxTls(Type, Body) &&
|
|
|
|
Out<ELFT>::Got->addDynTlsEntry(Body)) {
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->TlsModuleIndexRel, DynamicReloc<ELFT>::Off_GTlsIndex, Body});
|
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, Body});
|
2016-01-21 17:14:22 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (!canBePreempted(Body, true))
|
|
|
|
return true;
|
|
|
|
}
|
2016-01-29 10:33:45 +08:00
|
|
|
return !Target->isTlsDynRel(Type, *Body);
|
2016-01-21 17:14:22 +08:00
|
|
|
}
|
|
|
|
|
2015-09-16 23:54:15 +08:00
|
|
|
// The reason we have to do this early scan is as follows
|
|
|
|
// * To mmap the output file, we need to know the size
|
|
|
|
// * For that, we need to know how many dynamic relocs we will have.
|
|
|
|
// It might be possible to avoid this by outputting the file with write:
|
|
|
|
// * Write the allocated output sections, computing addresses.
|
|
|
|
// * Apply relocations, recording which ones require a dynamic reloc.
|
|
|
|
// * Write the dynamic relocations.
|
|
|
|
// * Write the rest of the file.
|
2016-02-02 23:45:37 +08:00
|
|
|
// This would have some drawbacks. For example, we would only know if .rela.dyn
|
|
|
|
// is needed after applying relocations. If it is, it will go after rw and rx
|
|
|
|
// sections. Given that it is ro, we will need an extra PT_LOAD. This
|
|
|
|
// complicates things for the dynamic linker and means we would have to reserve
|
|
|
|
// space for the extra PT_LOAD even if we end up not using it.
|
2015-09-17 22:02:10 +08:00
|
|
|
template <class ELFT>
|
|
|
|
template <bool isRela>
|
|
|
|
void Writer<ELFT>::scanRelocs(
|
2015-11-12 03:54:14 +08:00
|
|
|
InputSectionBase<ELFT> &C,
|
2015-09-17 22:02:10 +08:00
|
|
|
iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) {
|
|
|
|
typedef Elf_Rel_Impl<ELFT, isRela> RelType;
|
|
|
|
const ObjectFile<ELFT> &File = *C.getFile();
|
|
|
|
for (const RelType &RI : Rels) {
|
2015-10-17 06:51:43 +08:00
|
|
|
uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
|
2015-09-18 22:40:19 +08:00
|
|
|
SymbolBody *Body = File.getSymbolBody(SymIndex);
|
2015-10-17 06:51:43 +08:00
|
|
|
uint32_t Type = RI.getType(Config->Mips64EL);
|
2015-10-12 04:59:12 +08:00
|
|
|
|
2016-01-15 04:42:09 +08:00
|
|
|
// Ignore "hint" relocation because it is for optional code optimization.
|
2016-01-29 10:33:45 +08:00
|
|
|
if (Target->isHintRel(Type))
|
2016-01-15 04:42:09 +08:00
|
|
|
continue;
|
|
|
|
|
2015-12-21 18:00:12 +08:00
|
|
|
if (Target->isGotRelative(Type))
|
|
|
|
HasGotOffRel = true;
|
|
|
|
|
2015-10-12 04:59:12 +08:00
|
|
|
// Set "used" bit for --as-needed.
|
|
|
|
if (Body && Body->isUndefined() && !Body->isWeak())
|
|
|
|
if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
|
|
|
|
S->File->IsUsed = true;
|
|
|
|
|
|
|
|
if (Body)
|
|
|
|
Body = Body->repl();
|
2015-11-13 08:28:34 +08:00
|
|
|
|
2016-01-21 17:14:22 +08:00
|
|
|
if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
|
2015-11-14 00:28:53 +08:00
|
|
|
continue;
|
|
|
|
|
2016-02-05 05:33:05 +08:00
|
|
|
if (Target->needsDynRelative(Type))
|
|
|
|
Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
|
|
|
|
Body, getAddend<ELFT>(RI)});
|
2015-12-17 17:32:21 +08:00
|
|
|
|
2016-02-02 13:55:28 +08:00
|
|
|
// MIPS has a special rule to create GOTs for local symbols.
|
2016-02-05 07:18:22 +08:00
|
|
|
if (Config->EMachine == EM_MIPS && !canBePreempted(Body, true) &&
|
|
|
|
(Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16)) {
|
|
|
|
// FIXME (simon): Do not add so many redundant entries.
|
|
|
|
Out<ELFT>::Got->addMipsLocalEntry();
|
|
|
|
continue;
|
2016-02-02 13:55:28 +08:00
|
|
|
}
|
|
|
|
|
2016-02-02 14:08:08 +08:00
|
|
|
// If a symbol in a DSO is referenced directly instead of through GOT,
|
|
|
|
// we need to create a copy relocation for the symbol.
|
|
|
|
if (auto *B = dyn_cast_or_null<SharedSymbol<ELFT>>(Body)) {
|
|
|
|
if (B->NeedsCopy)
|
|
|
|
continue;
|
|
|
|
if (Target->needsCopyRel(Type, *B)) {
|
|
|
|
B->NeedsCopy = true;
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->CopyRel, DynamicReloc<ELFT>::Off_Bss, B});
|
2016-02-02 14:08:08 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 14:29:10 +08:00
|
|
|
// An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
|
|
|
|
// to the symbol go through the PLT. This is true even for a local
|
|
|
|
// symbol, although local symbols normally do not require PLT entries.
|
|
|
|
if (Body && isGnuIFunc<ELFT>(*Body)) {
|
|
|
|
if (Body->isInGot())
|
|
|
|
continue;
|
|
|
|
Out<ELFT>::Plt->addEntry(Body);
|
2016-02-05 05:33:05 +08:00
|
|
|
bool CBP = canBePreempted(Body, /*NeedsGot=*/true);
|
2016-02-02 14:29:10 +08:00
|
|
|
if (Target->UseLazyBinding) {
|
|
|
|
Out<ELFT>::GotPlt->addEntry(Body);
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaPlt->addReloc(
|
|
|
|
{CBP ? Target->PltRel : Target->IRelativeRel,
|
|
|
|
DynamicReloc<ELFT>::Off_GotPlt, !CBP, Body});
|
2016-02-02 14:29:10 +08:00
|
|
|
} else {
|
|
|
|
Out<ELFT>::Got->addEntry(Body);
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{CBP ? Target->PltRel : Target->IRelativeRel,
|
|
|
|
DynamicReloc<ELFT>::Off_Got, !CBP, Body});
|
2016-02-02 14:29:10 +08:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-02-02 15:07:34 +08:00
|
|
|
// If a relocation needs PLT, we create a PLT and a GOT slot
|
|
|
|
// for the symbol.
|
|
|
|
if (Body && Target->needsPlt(Type, *Body)) {
|
|
|
|
if (Body->isInPlt())
|
|
|
|
continue;
|
|
|
|
Out<ELFT>::Plt->addEntry(Body);
|
2016-02-02 13:55:28 +08:00
|
|
|
|
2016-02-02 15:07:34 +08:00
|
|
|
if (Target->UseLazyBinding) {
|
|
|
|
Out<ELFT>::GotPlt->addEntry(Body);
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaPlt->addReloc(
|
|
|
|
{Target->PltRel, DynamicReloc<ELFT>::Off_GotPlt, Body});
|
2016-02-02 15:07:34 +08:00
|
|
|
} else {
|
|
|
|
if (Body->isInGot())
|
2015-10-06 03:30:12 +08:00
|
|
|
continue;
|
2016-02-02 15:07:34 +08:00
|
|
|
Out<ELFT>::Got->addEntry(Body);
|
2016-02-05 05:33:05 +08:00
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->GotRel, DynamicReloc<ELFT>::Off_Got, Body});
|
2015-10-14 00:59:30 +08:00
|
|
|
}
|
2016-02-02 15:07:34 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-02-02 15:07:35 +08:00
|
|
|
// If a relocation needs GOT, we create a GOT slot for the symbol.
|
|
|
|
if (Body && Target->needsGot(Type, *Body)) {
|
|
|
|
if (Body->isInGot())
|
|
|
|
continue;
|
|
|
|
Out<ELFT>::Got->addEntry(Body);
|
2016-02-02 15:07:34 +08:00
|
|
|
|
2016-02-04 19:51:39 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
2016-02-02 15:07:35 +08:00
|
|
|
// MIPS ABI has special rules to process GOT entries
|
|
|
|
// and doesn't require relocation entries for them.
|
|
|
|
// See "Global Offset Table" in Chapter 5 in the following document
|
|
|
|
// for detailed description:
|
|
|
|
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
2016-02-05 23:27:15 +08:00
|
|
|
Body->MustBeInDynSym = true;
|
2016-02-02 15:07:35 +08:00
|
|
|
continue;
|
2016-02-04 19:51:39 +08:00
|
|
|
}
|
2016-02-02 15:07:35 +08:00
|
|
|
|
|
|
|
bool CBP = canBePreempted(Body, /*NeedsGot=*/true);
|
|
|
|
bool Dynrel = Config->Shared && !Target->isRelRelative(Type) &&
|
|
|
|
!Target->isSizeRel(Type);
|
2016-02-05 05:33:05 +08:00
|
|
|
if (CBP || Dynrel) {
|
|
|
|
uint32_t DynType;
|
|
|
|
if (CBP)
|
|
|
|
DynType = Body->isTls() ? Target->getTlsGotRel() : Target->GotRel;
|
|
|
|
else
|
|
|
|
DynType = Target->RelativeRel;
|
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{DynType, DynamicReloc<ELFT>::Off_Got, !CBP, Body});
|
|
|
|
}
|
2016-02-02 15:07:35 +08:00
|
|
|
continue;
|
2015-10-06 03:30:12 +08:00
|
|
|
}
|
2015-10-12 04:59:12 +08:00
|
|
|
|
2016-01-13 01:31:45 +08:00
|
|
|
if (Config->EMachine == EM_MIPS) {
|
2016-01-21 13:33:23 +08:00
|
|
|
if (Type == R_MIPS_LO16)
|
|
|
|
// Ignore R_MIPS_LO16 relocation. If it is a pair for R_MIPS_GOT16 we
|
|
|
|
// already completed all required action (GOT entry allocation) when
|
|
|
|
// handle R_MIPS_GOT16a. If it is a pair for R_MIPS_HI16 against
|
|
|
|
// _gp_disp it does not require dynamic relocation. If its a pair for
|
|
|
|
// R_MIPS_HI16 against a regular symbol it does not require dynamic
|
|
|
|
// relocation too because that case is possible for executable file
|
|
|
|
// linking only.
|
|
|
|
continue;
|
2016-02-04 20:09:49 +08:00
|
|
|
if (Body == Config->MipsGpDisp || Body == Config->MipsLocalGp)
|
2016-01-13 01:31:45 +08:00
|
|
|
// MIPS _gp_disp designates offset between start of function and gp
|
|
|
|
// pointer into GOT therefore any relocations against it do not require
|
|
|
|
// dynamic relocation.
|
|
|
|
continue;
|
2015-11-06 15:43:03 +08:00
|
|
|
}
|
2016-01-08 11:25:26 +08:00
|
|
|
|
2016-02-02 15:50:18 +08:00
|
|
|
if (canBePreempted(Body, /*NeedsGot=*/false)) {
|
2016-02-05 05:33:05 +08:00
|
|
|
// We don't know anything about the finaly symbol. Just ask the dynamic
|
|
|
|
// linker to handle the relocation for us.
|
|
|
|
Out<ELFT>::RelaDyn->addReloc({Target->getDynRel(Type), &C, RI.r_offset,
|
|
|
|
false, Body, getAddend<ELFT>(RI)});
|
2016-02-02 15:50:18 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-02-05 05:33:05 +08:00
|
|
|
// We know that this is the final symbol. If the program being produced
|
|
|
|
// is position independent, the final value is still not known.
|
|
|
|
// If the relocation depends on the symbol value (not the size or distances
|
|
|
|
// in the output), we still need some help from the dynamic linker.
|
|
|
|
// We can however do better than just copying the incoming relocation. We
|
|
|
|
// can process some of it and and just ask the dynamic linker to add the
|
|
|
|
// load address.
|
|
|
|
if (!Config->Shared || Target->isRelRelative(Type) ||
|
|
|
|
Target->isSizeRel(Type))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
uintX_t Addend = getAddend<ELFT>(RI);
|
|
|
|
if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) {
|
|
|
|
Out<ELFT>::RelaDyn->addReloc({R_PPC64_RELATIVE, &C, RI.r_offset, false,
|
|
|
|
nullptr,
|
|
|
|
(uintX_t)getPPC64TocBase() + Addend});
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Body) {
|
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->RelativeRel, &C, RI.r_offset, true, Body, Addend});
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const Elf_Sym *Sym =
|
|
|
|
File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
|
|
|
|
InputSectionBase<ELFT> *Section = File.getSection(*Sym);
|
|
|
|
uintX_t Offset = Sym->st_value;
|
|
|
|
if (Sym->getType() == STT_SECTION) {
|
|
|
|
Offset += Addend;
|
|
|
|
Addend = 0;
|
|
|
|
}
|
|
|
|
Out<ELFT>::RelaDyn->addReloc(
|
|
|
|
{Target->RelativeRel, &C, RI.r_offset, Section, Offset, Addend});
|
2015-09-17 22:02:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-11 23:29:50 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::scanRelocs(InputSection<ELFT> &C) {
|
2016-01-26 15:17:29 +08:00
|
|
|
if (C.getSectionHdr()->sh_flags & SHF_ALLOC)
|
|
|
|
for (const Elf_Shdr *RelSec : C.RelocSections)
|
|
|
|
scanRelocs(C, *RelSec);
|
2015-11-12 03:54:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT>
|
|
|
|
void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &S,
|
|
|
|
const Elf_Shdr &RelSec) {
|
|
|
|
ELFFile<ELFT> &EObj = S.getFile()->getObj();
|
|
|
|
if (RelSec.sh_type == SHT_RELA)
|
|
|
|
scanRelocs(S, EObj.relas(&RelSec));
|
|
|
|
else
|
|
|
|
scanRelocs(S, EObj.rels(&RelSec));
|
2015-09-16 23:54:15 +08:00
|
|
|
}
|
|
|
|
|
2015-09-23 22:37:01 +08:00
|
|
|
template <class ELFT>
|
2016-01-06 04:01:29 +08:00
|
|
|
static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
|
2015-10-02 04:14:45 +08:00
|
|
|
if (Config->Shared && !Config->NoUndefined)
|
2015-10-02 01:24:24 +08:00
|
|
|
return;
|
|
|
|
|
2016-01-06 04:01:29 +08:00
|
|
|
std::string Msg = "undefined symbol: " + Sym->getName().str();
|
|
|
|
if (ELFFileBase<ELFT> *File = Symtab.findFile(Sym))
|
|
|
|
Msg += " in " + File->getName().str();
|
2015-09-26 03:24:57 +08:00
|
|
|
if (Config->NoInhibitExec)
|
2016-01-06 04:01:29 +08:00
|
|
|
warning(Msg);
|
2015-09-23 22:37:01 +08:00
|
|
|
else
|
2016-01-29 06:56:29 +08:00
|
|
|
error(Msg);
|
2015-09-23 22:37:01 +08:00
|
|
|
}
|
|
|
|
|
2016-01-28 02:04:26 +08:00
|
|
|
template <class ELFT>
|
|
|
|
static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
|
|
|
|
const typename ELFFile<ELFT>::Elf_Sym &Sym) {
|
|
|
|
if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
InputSectionBase<ELFT> *Sec = File.getSection(Sym);
|
|
|
|
// If sym references a section in a discarded group, don't keep it.
|
|
|
|
if (Sec == &InputSection<ELFT>::Discarded)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (Config->DiscardNone)
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (Config->DiscardLocals)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
|
|
|
|
}
|
|
|
|
|
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() {
|
2016-01-21 11:07:38 +08:00
|
|
|
if (!Out<ELFT>::SymTab)
|
|
|
|
return;
|
2015-10-10 05:07:25 +08:00
|
|
|
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
|
|
|
|
for (const Elf_Sym &Sym : F->getLocalSymbols()) {
|
|
|
|
ErrorOr<StringRef> SymNameOrErr = Sym.getName(F->getStringTable());
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
fatal(SymNameOrErr);
|
2015-10-09 07:49:30 +08:00
|
|
|
StringRef SymName = *SymNameOrErr;
|
2015-10-10 05:07:25 +08:00
|
|
|
if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
|
2015-10-10 03:25:07 +08:00
|
|
|
continue;
|
2016-01-28 01:09:37 +08:00
|
|
|
if (Sym.st_shndx != SHN_ABS) {
|
|
|
|
InputSectionBase<ELFT> *Section = F->getSection(Sym);
|
|
|
|
if (!Section->isLive())
|
|
|
|
continue;
|
|
|
|
}
|
2016-01-29 09:24:25 +08:00
|
|
|
++Out<ELFT>::SymTab->NumLocals;
|
|
|
|
F->KeptLocalSyms.push_back(std::make_pair(
|
|
|
|
&Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
|
2015-10-09 07:49:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-13 04:51:48 +08:00
|
|
|
// 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).
|
|
|
|
static int getPPC64SectionRank(StringRef SectionName) {
|
|
|
|
return StringSwitch<int>(SectionName)
|
|
|
|
.Case(".tocbss", 0)
|
|
|
|
.Case(".branch_lt", 2)
|
|
|
|
.Case(".toc", 3)
|
|
|
|
.Case(".toc1", 4)
|
|
|
|
.Case(".opd", 5)
|
|
|
|
.Default(1);
|
|
|
|
}
|
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
template <class ELFT> static bool isRelroSection(OutputSectionBase<ELFT> *Sec) {
|
|
|
|
typename OutputSectionBase<ELFT>::uintX_t Flags = Sec->getFlags();
|
|
|
|
if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
|
|
|
|
return false;
|
2015-12-11 03:13:08 +08:00
|
|
|
if (Flags & SHF_TLS)
|
|
|
|
return true;
|
2015-11-24 18:15:50 +08:00
|
|
|
uint32_t Type = Sec->getType();
|
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;
|
|
|
|
if (Sec == Out<ELFT>::GotPlt)
|
|
|
|
return Config->ZNow;
|
|
|
|
if (Sec == Out<ELFT>::Dynamic || Sec == Out<ELFT>::Got)
|
|
|
|
return true;
|
2015-12-11 03:19:04 +08:00
|
|
|
StringRef S = Sec->getName();
|
|
|
|
return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
|
|
|
|
S == ".eh_frame";
|
2015-11-24 18:15:50 +08:00
|
|
|
}
|
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
// Output section ordering is determined by this function.
|
|
|
|
template <class ELFT>
|
2015-10-16 06:27:29 +08:00
|
|
|
static bool compareOutputSections(OutputSectionBase<ELFT> *A,
|
|
|
|
OutputSectionBase<ELFT> *B) {
|
2015-10-09 07:49:30 +08:00
|
|
|
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
|
|
|
|
|
|
|
|
uintX_t AFlags = A->getFlags();
|
|
|
|
uintX_t BFlags = B->getFlags();
|
|
|
|
|
|
|
|
// Allocatable sections go first to reduce the total PT_LOAD size and
|
|
|
|
// so debug info doesn't change addresses in actual code.
|
|
|
|
bool AIsAlloc = AFlags & SHF_ALLOC;
|
|
|
|
bool BIsAlloc = BFlags & SHF_ALLOC;
|
|
|
|
if (AIsAlloc != BIsAlloc)
|
|
|
|
return AIsAlloc;
|
|
|
|
|
|
|
|
// We don't have any special requirements for the relative order of
|
|
|
|
// two non allocatable sections.
|
|
|
|
if (!AIsAlloc)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// We want the read only sections first so that they go in the PT_LOAD
|
|
|
|
// covering the program headers at the start of the file.
|
|
|
|
bool AIsWritable = AFlags & SHF_WRITE;
|
|
|
|
bool BIsWritable = BFlags & SHF_WRITE;
|
|
|
|
if (AIsWritable != BIsWritable)
|
|
|
|
return BIsWritable;
|
|
|
|
|
|
|
|
// For a corresponding reason, put non exec sections first (the program
|
|
|
|
// header PT_LOAD is not executable).
|
|
|
|
bool AIsExec = AFlags & SHF_EXECINSTR;
|
|
|
|
bool BIsExec = BFlags & SHF_EXECINSTR;
|
|
|
|
if (AIsExec != BIsExec)
|
|
|
|
return BIsExec;
|
|
|
|
|
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
|
|
|
|
|
|
|
// The TLS initialization block needs to be a single contiguous block in a R/W
|
|
|
|
// PT_LOAD, so stick TLS sections directly before R/W sections. The TLS NOBITS
|
|
|
|
// sections are placed here as they don't take up virtual address space in the
|
|
|
|
// PT_LOAD.
|
2015-12-17 08:12:03 +08:00
|
|
|
bool AIsTls = AFlags & SHF_TLS;
|
|
|
|
bool BIsTls = BFlags & SHF_TLS;
|
|
|
|
if (AIsTls != BIsTls)
|
|
|
|
return AIsTls;
|
2015-10-17 07:11:07 +08:00
|
|
|
|
2015-10-14 02:55:01 +08:00
|
|
|
// The next requirement we have is to put nobits sections last. The
|
2015-10-09 07:49:30 +08:00
|
|
|
// 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.
|
2015-10-14 03:27:12 +08:00
|
|
|
bool AIsNoBits = A->getType() == SHT_NOBITS;
|
|
|
|
bool BIsNoBits = B->getType() == SHT_NOBITS;
|
|
|
|
if (AIsNoBits != BIsNoBits)
|
|
|
|
return BIsNoBits;
|
2015-10-13 04:51:48 +08:00
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
// We place RelRo section before plain r/w ones.
|
|
|
|
bool AIsRelRo = isRelroSection(A);
|
|
|
|
bool BIsRelRo = isRelroSection(B);
|
|
|
|
if (AIsRelRo != BIsRelRo)
|
|
|
|
return AIsRelRo;
|
|
|
|
|
2015-10-14 03:07:29 +08:00
|
|
|
// Some architectures have additional ordering restrictions for sections
|
|
|
|
// within the same PT_LOAD.
|
|
|
|
if (Config->EMachine == EM_PPC64)
|
|
|
|
return getPPC64SectionRank(A->getName()) <
|
|
|
|
getPPC64SectionRank(B->getName());
|
|
|
|
|
|
|
|
return false;
|
2015-10-09 07:49:30 +08:00
|
|
|
}
|
|
|
|
|
2016-01-06 00:35:43 +08:00
|
|
|
template <class ELFT> OutputSection<ELFT> *Writer<ELFT>::getBss() {
|
2015-11-04 05:35:14 +08:00
|
|
|
if (!Out<ELFT>::Bss) {
|
2015-12-26 15:01:26 +08:00
|
|
|
Out<ELFT>::Bss =
|
|
|
|
new OutputSection<ELFT>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
|
|
|
OwningSections.emplace_back(Out<ELFT>::Bss);
|
2015-11-04 05:35:14 +08:00
|
|
|
OutputSections.push_back(Out<ELFT>::Bss);
|
|
|
|
}
|
|
|
|
return Out<ELFT>::Bss;
|
|
|
|
}
|
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
// Until this function is called, common symbols do not belong to any section.
|
|
|
|
// This function adds them to end of BSS section.
|
|
|
|
template <class ELFT>
|
2015-12-25 00:23:37 +08:00
|
|
|
void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
|
2015-11-04 05:35:14 +08:00
|
|
|
if (Syms.empty())
|
|
|
|
return;
|
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
// Sort the common symbols by alignment as an heuristic to pack them better.
|
2015-12-25 00:23:37 +08:00
|
|
|
std::stable_sort(Syms.begin(), Syms.end(),
|
|
|
|
[](const DefinedCommon *A, const DefinedCommon *B) {
|
|
|
|
return A->MaxAlignment > B->MaxAlignment;
|
|
|
|
});
|
2015-10-09 07:49:30 +08:00
|
|
|
|
2016-01-06 00:35:43 +08:00
|
|
|
uintX_t Off = getBss()->getSize();
|
2015-12-25 00:23:37 +08:00
|
|
|
for (DefinedCommon *C : Syms) {
|
2016-01-15 04:53:50 +08:00
|
|
|
Off = alignTo(Off, C->MaxAlignment);
|
2016-01-06 00:35:43 +08:00
|
|
|
C->OffsetInBss = Off;
|
2015-12-25 00:23:37 +08:00
|
|
|
Off += C->Size;
|
2015-10-09 07:49:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Out<ELFT>::Bss->setSize(Off);
|
|
|
|
}
|
|
|
|
|
2015-12-26 18:07:03 +08:00
|
|
|
// Reserve space in .bss for copy relocations.
|
2015-10-29 00:48:58 +08:00
|
|
|
template <class ELFT>
|
2015-12-26 18:07:03 +08:00
|
|
|
void Writer<ELFT>::addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms) {
|
2015-11-04 05:35:14 +08:00
|
|
|
if (Syms.empty())
|
|
|
|
return;
|
2016-01-06 00:35:43 +08:00
|
|
|
uintX_t Off = getBss()->getSize();
|
2015-10-29 00:48:58 +08:00
|
|
|
for (SharedSymbol<ELFT> *C : Syms) {
|
|
|
|
const Elf_Sym &Sym = C->Sym;
|
2015-11-03 22:13:40 +08:00
|
|
|
const Elf_Shdr *Sec = C->File->getSection(Sym);
|
|
|
|
uintX_t SecAlign = Sec->sh_addralign;
|
2015-12-11 06:53:24 +08:00
|
|
|
unsigned TrailingZeros =
|
|
|
|
std::min(countTrailingZeros(SecAlign),
|
|
|
|
countTrailingZeros((uintX_t)Sym.st_value));
|
|
|
|
uintX_t Align = 1 << TrailingZeros;
|
2015-11-03 22:13:40 +08:00
|
|
|
Out<ELFT>::Bss->updateAlign(Align);
|
2016-01-15 04:53:50 +08:00
|
|
|
Off = alignTo(Off, Align);
|
2016-01-06 00:35:43 +08:00
|
|
|
C->OffsetInBss = Off;
|
2015-10-29 00:48:58 +08:00
|
|
|
Off += Sym.st_size;
|
|
|
|
}
|
|
|
|
Out<ELFT>::Bss->setSize(Off);
|
|
|
|
}
|
|
|
|
|
2015-11-12 17:52:08 +08:00
|
|
|
template <class ELFT>
|
|
|
|
StringRef Writer<ELFT>::getOutputSectionName(StringRef S) const {
|
|
|
|
auto It = InputToOutputSection.find(S);
|
|
|
|
if (It != std::end(InputToOutputSection))
|
|
|
|
return It->second;
|
|
|
|
|
2015-10-15 03:21:25 +08:00
|
|
|
if (S.startswith(".text."))
|
|
|
|
return ".text";
|
|
|
|
if (S.startswith(".rodata."))
|
|
|
|
return ".rodata";
|
2015-11-13 15:56:27 +08:00
|
|
|
if (S.startswith(".data.rel.ro"))
|
|
|
|
return ".data.rel.ro";
|
2015-10-15 03:21:25 +08:00
|
|
|
if (S.startswith(".data."))
|
|
|
|
return ".data";
|
|
|
|
if (S.startswith(".bss."))
|
|
|
|
return ".bss";
|
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2015-12-10 17:12:18 +08:00
|
|
|
template <class ELFT>
|
|
|
|
void reportDiscarded(InputSectionBase<ELFT> *IS,
|
|
|
|
const std::unique_ptr<ObjectFile<ELFT>> &File) {
|
|
|
|
if (!Config->PrintGcSections || !IS || IS->isLive())
|
|
|
|
return;
|
|
|
|
llvm::errs() << "removing unused section from '" << IS->getSectionName()
|
|
|
|
<< "' in file '" << File->getName() << "'\n";
|
|
|
|
}
|
|
|
|
|
2015-11-12 17:52:08 +08:00
|
|
|
template <class ELFT>
|
|
|
|
bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *IS) const {
|
|
|
|
if (!IS || !IS->isLive() || IS == &InputSection<ELFT>::Discarded)
|
|
|
|
return true;
|
|
|
|
return InputToOutputSection.lookup(IS->getSectionName()) == "/DISCARD/";
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT>
|
|
|
|
static bool compareSections(OutputSectionBase<ELFT> *A,
|
|
|
|
OutputSectionBase<ELFT> *B) {
|
|
|
|
auto ItA = Config->OutputSections.find(A->getName());
|
|
|
|
auto ItEnd = std::end(Config->OutputSections);
|
|
|
|
if (ItA == ItEnd)
|
|
|
|
return compareOutputSections(A, B);
|
|
|
|
auto ItB = Config->OutputSections.find(B->getName());
|
|
|
|
if (ItB == ItEnd)
|
|
|
|
return compareOutputSections(A, B);
|
|
|
|
|
|
|
|
return std::distance(ItA, ItB) > 0;
|
|
|
|
}
|
|
|
|
|
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.
|
2015-12-21 18:12:06 +08:00
|
|
|
template <class ELFT>
|
2015-12-26 17:47:57 +08:00
|
|
|
void Writer<ELFT>::addRelIpltSymbols() {
|
|
|
|
if (isOutputDynamic() || !Out<ELFT>::RelaPlt)
|
2015-12-21 18:12:06 +08:00
|
|
|
return;
|
|
|
|
bool IsRela = shouldUseRela<ELFT>();
|
2015-12-26 17:47:57 +08:00
|
|
|
|
|
|
|
StringRef S = IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
|
|
|
|
if (Symtab.find(S))
|
|
|
|
Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltStart);
|
|
|
|
|
|
|
|
S = IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
|
|
|
|
if (Symtab.find(S))
|
|
|
|
Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltEnd);
|
2015-12-21 18:12:06 +08:00
|
|
|
}
|
|
|
|
|
2015-12-24 04:37:51 +08:00
|
|
|
template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
|
|
|
|
if (!B.isUsedInRegularObj())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Don't include synthetic symbols like __init_array_start in every output.
|
2015-12-24 22:22:24 +08:00
|
|
|
if (auto *U = dyn_cast<DefinedRegular<ELFT>>(&B))
|
2016-01-20 05:19:52 +08:00
|
|
|
if (&U->Sym == &ElfSym<ELFT>::Ignored)
|
2015-12-24 04:37:51 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-29 10:17:01 +08:00
|
|
|
static bool includeInDynsym(const SymbolBody &B) {
|
2015-12-25 15:01:09 +08:00
|
|
|
uint8_t V = B.getVisibility();
|
|
|
|
if (V != STV_DEFAULT && V != STV_PROTECTED)
|
|
|
|
return false;
|
|
|
|
if (Config->ExportDynamic || Config->Shared)
|
|
|
|
return true;
|
2016-02-05 23:27:15 +08:00
|
|
|
return B.MustBeInDynSym;
|
2015-12-25 15:01:09 +08:00
|
|
|
}
|
|
|
|
|
2015-12-26 15:01:28 +08:00
|
|
|
// This class knows how to create an output section for a given
|
|
|
|
// input section. Output section type is determined by various
|
|
|
|
// factors, including input section's sh_flags, sh_type and
|
|
|
|
// linker scripts.
|
|
|
|
namespace {
|
|
|
|
template <class ELFT> class OutputSectionFactory {
|
|
|
|
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
|
|
|
|
typedef typename ELFFile<ELFT>::uintX_t uintX_t;
|
|
|
|
|
|
|
|
public:
|
|
|
|
std::pair<OutputSectionBase<ELFT> *, bool> create(InputSectionBase<ELFT> *C,
|
|
|
|
StringRef OutsecName);
|
|
|
|
|
|
|
|
OutputSectionBase<ELFT> *lookup(StringRef Name, uint32_t Type, uintX_t Flags);
|
|
|
|
|
|
|
|
private:
|
|
|
|
SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
|
|
|
|
StringRef OutsecName);
|
|
|
|
|
|
|
|
SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSectionBase<ELFT> *> Map;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT>
|
|
|
|
std::pair<OutputSectionBase<ELFT> *, bool>
|
|
|
|
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
|
|
|
|
StringRef OutsecName) {
|
|
|
|
SectionKey<ELFT::Is64Bits> Key = createKey(C, OutsecName);
|
|
|
|
OutputSectionBase<ELFT> *&Sec = Map[Key];
|
|
|
|
if (Sec)
|
|
|
|
return {Sec, false};
|
|
|
|
|
2015-12-25 15:38:58 +08:00
|
|
|
switch (C->SectionKind) {
|
|
|
|
case InputSectionBase<ELFT>::Regular:
|
2016-01-12 07:50:55 +08:00
|
|
|
Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
|
|
|
|
break;
|
2015-12-25 15:38:58 +08:00
|
|
|
case InputSectionBase<ELFT>::EHFrame:
|
2016-01-12 07:50:55 +08:00
|
|
|
Sec = new EHOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
|
|
|
|
break;
|
2015-12-25 15:38:58 +08:00
|
|
|
case InputSectionBase<ELFT>::Merge:
|
2016-01-12 07:50:55 +08:00
|
|
|
Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
|
|
|
|
break;
|
2015-12-25 15:38:58 +08:00
|
|
|
case InputSectionBase<ELFT>::MipsReginfo:
|
2016-01-12 07:50:55 +08:00
|
|
|
Sec = new MipsReginfoOutputSection<ELFT>();
|
|
|
|
break;
|
2015-12-25 15:38:58 +08:00
|
|
|
}
|
2016-01-12 07:50:55 +08:00
|
|
|
return {Sec, true};
|
2015-12-25 15:38:58 +08:00
|
|
|
}
|
|
|
|
|
2015-12-26 15:01:28 +08:00
|
|
|
template <class ELFT>
|
|
|
|
OutputSectionBase<ELFT> *OutputSectionFactory<ELFT>::lookup(StringRef Name,
|
|
|
|
uint32_t Type,
|
|
|
|
uintX_t Flags) {
|
|
|
|
return Map.lookup({Name, Type, Flags, 0});
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT>
|
|
|
|
SectionKey<ELFT::Is64Bits>
|
|
|
|
OutputSectionFactory<ELFT>::createKey(InputSectionBase<ELFT> *C,
|
|
|
|
StringRef OutsecName) {
|
|
|
|
const Elf_Shdr *H = C->getSectionHdr();
|
2015-12-26 15:13:38 +08:00
|
|
|
uintX_t Flags = H->sh_flags & ~SHF_GROUP;
|
2015-12-26 15:01:28 +08:00
|
|
|
|
|
|
|
// For SHF_MERGE we create different output sections for each sh_entsize.
|
|
|
|
// This makes each output section simple and keeps a single level
|
|
|
|
// mapping from input to output.
|
|
|
|
uintX_t EntSize = isa<MergeInputSection<ELFT>>(C) ? H->sh_entsize : 0;
|
2015-12-26 15:13:38 +08:00
|
|
|
|
|
|
|
// GNU as can give .eh_frame secion type SHT_PROGBITS or SHT_X86_64_UNWIND
|
|
|
|
// depending on the construct. We want to canonicalize it so that
|
|
|
|
// there is only one .eh_frame in the end.
|
|
|
|
uint32_t Type = H->sh_type;
|
|
|
|
if (Type == SHT_PROGBITS && Config->EMachine == EM_X86_64 &&
|
|
|
|
isa<EHInputSection<ELFT>>(C))
|
|
|
|
Type = SHT_X86_64_UNWIND;
|
|
|
|
|
|
|
|
return SectionKey<ELFT::Is64Bits>{OutsecName, Type, Flags, EntSize};
|
2015-12-26 15:01:28 +08:00
|
|
|
}
|
|
|
|
|
2015-12-26 15:50:39 +08:00
|
|
|
// The linker is expected to define some symbols depending on
|
|
|
|
// the linking result. This function defines such symbols.
|
|
|
|
template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
|
|
|
|
// __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
|
|
|
|
// static linking the linker is required to optimize away any references to
|
|
|
|
// __tls_get_addr, so it's not defined anywhere. Create a hidden definition
|
|
|
|
// to avoid the undefined symbol error.
|
|
|
|
if (!isOutputDynamic())
|
|
|
|
Symtab.addIgnored("__tls_get_addr");
|
|
|
|
|
|
|
|
// If the "_end" symbol is referenced, it is expected to point to the address
|
|
|
|
// right after the data segment. Usually, this symbol points to the end
|
|
|
|
// of .bss section or to the end of .data section if .bss section is absent.
|
2016-01-29 08:20:09 +08:00
|
|
|
// We don't know the final address of _end yet, so just add a symbol here,
|
|
|
|
// and fix ElfSym<ELFT>::End.st_value later.
|
2015-12-26 15:50:39 +08:00
|
|
|
if (Symtab.find("_end"))
|
|
|
|
Symtab.addAbsolute("_end", ElfSym<ELFT>::End);
|
|
|
|
|
2016-01-29 08:20:09 +08:00
|
|
|
// Define "end" as an alias to "_end" if it is used but not defined.
|
|
|
|
// We don't want to define that unconditionally because we don't want to
|
|
|
|
// break programs that uses "end" as a regular symbol.
|
2015-12-26 15:50:39 +08:00
|
|
|
if (SymbolBody *B = Symtab.find("end"))
|
|
|
|
if (B->isUndefined())
|
|
|
|
Symtab.addAbsolute("end", ElfSym<ELFT>::End);
|
|
|
|
}
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
// Create output section objects and add them to OutputSections.
|
2016-01-29 06:56:29 +08:00
|
|
|
template <class ELFT> bool Writer<ELFT>::createSections() {
|
2015-12-26 18:22:16 +08:00
|
|
|
// Add .interp first because some loaders want to see that section
|
|
|
|
// on the first page of the executable file when loaded into memory.
|
2015-10-11 07:25:39 +08:00
|
|
|
if (needsInterpSection())
|
|
|
|
OutputSections.push_back(Out<ELFT>::Interp);
|
|
|
|
|
2015-12-26 18:22:16 +08:00
|
|
|
// Create output sections for input object file sections.
|
2015-10-16 06:27:29 +08:00
|
|
|
std::vector<OutputSectionBase<ELFT> *> RegularSections;
|
2015-12-26 15:01:28 +08:00
|
|
|
OutputSectionFactory<ELFT> Factory;
|
2015-10-10 05:07:25 +08:00
|
|
|
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
|
2015-10-20 05:00:02 +08:00
|
|
|
for (InputSectionBase<ELFT> *C : F->getSections()) {
|
2015-12-10 17:12:18 +08:00
|
|
|
if (isDiscarded(C)) {
|
|
|
|
reportDiscarded(C, F);
|
2015-09-16 23:54:15 +08:00
|
|
|
continue;
|
2015-12-10 17:12:18 +08:00
|
|
|
}
|
2015-12-26 15:01:28 +08:00
|
|
|
OutputSectionBase<ELFT> *Sec;
|
|
|
|
bool IsNew;
|
|
|
|
std::tie(Sec, IsNew) =
|
|
|
|
Factory.create(C, getOutputSectionName(C->getSectionName()));
|
|
|
|
if (IsNew) {
|
2015-12-26 15:01:26 +08:00
|
|
|
OwningSections.emplace_back(Sec);
|
2015-09-25 23:08:44 +08:00
|
|
|
OutputSections.push_back(Sec);
|
2015-10-16 01:11:03 +08:00
|
|
|
RegularSections.push_back(Sec);
|
2015-09-25 23:08:44 +08:00
|
|
|
}
|
2015-12-26 13:51:07 +08:00
|
|
|
Sec->addSection(C);
|
2015-09-16 23:54:15 +08:00
|
|
|
}
|
2015-09-01 08:16:38 +08:00
|
|
|
}
|
|
|
|
|
2015-11-04 05:35:14 +08:00
|
|
|
Out<ELFT>::Bss = static_cast<OutputSection<ELFT> *>(
|
2015-12-26 15:01:28 +08:00
|
|
|
Factory.lookup(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE));
|
2015-11-04 05:35:14 +08:00
|
|
|
|
2015-12-26 15:50:41 +08:00
|
|
|
// If we have a .opd section (used under PPC64 for function descriptors),
|
|
|
|
// store a pointer to it here so that we can use it later when processing
|
|
|
|
// relocations.
|
|
|
|
Out<ELFT>::Opd = Factory.lookup(".opd", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC);
|
|
|
|
|
2015-12-26 15:01:28 +08:00
|
|
|
Out<ELFT>::Dynamic->PreInitArraySec = Factory.lookup(
|
|
|
|
".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC);
|
2015-10-08 03:18:16 +08:00
|
|
|
Out<ELFT>::Dynamic->InitArraySec =
|
2015-12-26 15:01:28 +08:00
|
|
|
Factory.lookup(".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC);
|
2015-10-08 03:18:16 +08:00
|
|
|
Out<ELFT>::Dynamic->FiniArraySec =
|
2015-12-26 15:01:28 +08:00
|
|
|
Factory.lookup(".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC);
|
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.
|
|
|
|
addStartEndSymbols();
|
2015-10-19 23:21:42 +08:00
|
|
|
for (OutputSectionBase<ELFT> *Sec : RegularSections)
|
|
|
|
addStartStopSymbols(Sec);
|
|
|
|
|
2016-02-05 05:33:05 +08:00
|
|
|
// Define __rel[a]_iplt_{start,end} symbols if needed.
|
|
|
|
addRelIpltSymbols();
|
|
|
|
|
2015-10-19 23:21:42 +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.
|
2015-11-12 03:54:14 +08:00
|
|
|
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
|
2015-11-12 17:52:08 +08:00
|
|
|
for (InputSectionBase<ELFT> *C : F->getSections()) {
|
|
|
|
if (isDiscarded(C))
|
|
|
|
continue;
|
|
|
|
if (auto *S = dyn_cast<InputSection<ELFT>>(C))
|
|
|
|
scanRelocs(*S);
|
|
|
|
else if (auto *S = dyn_cast<EHInputSection<ELFT>>(C))
|
2015-11-12 03:54:14 +08:00
|
|
|
if (S->RelocSection)
|
|
|
|
scanRelocs(*S, *S->RelocSection);
|
|
|
|
}
|
|
|
|
}
|
2015-10-19 23:21:42 +08:00
|
|
|
|
2015-12-26 18:22:16 +08:00
|
|
|
// Now that we have defined all possible symbols including linker-
|
|
|
|
// synthesized ones. Visit all symbols to give the finishing touches.
|
2015-12-25 00:23:37 +08:00
|
|
|
std::vector<DefinedCommon *> CommonSymbols;
|
2015-12-26 18:07:03 +08:00
|
|
|
std::vector<SharedSymbol<ELFT> *> CopyRelSymbols;
|
2015-09-23 07:38:23 +08:00
|
|
|
for (auto &P : Symtab.getSymbols()) {
|
|
|
|
SymbolBody *Body = P.second->Body;
|
2015-12-23 07:00:50 +08:00
|
|
|
if (auto *U = dyn_cast<Undefined>(Body))
|
2015-10-05 17:43:57 +08:00
|
|
|
if (!U->isWeak() && !U->canKeepUndefined())
|
2016-01-06 04:01:29 +08:00
|
|
|
reportUndefined<ELFT>(Symtab, Body);
|
2015-09-23 07:38:23 +08:00
|
|
|
|
2015-12-25 00:23:37 +08:00
|
|
|
if (auto *C = dyn_cast<DefinedCommon>(Body))
|
2015-09-23 07:38:23 +08:00
|
|
|
CommonSymbols.push_back(C);
|
2015-10-29 00:48:58 +08:00
|
|
|
if (auto *SC = dyn_cast<SharedSymbol<ELFT>>(Body))
|
2015-12-17 09:14:23 +08:00
|
|
|
if (SC->NeedsCopy)
|
2015-12-26 18:07:03 +08:00
|
|
|
CopyRelSymbols.push_back(SC);
|
2015-10-29 00:48:58 +08:00
|
|
|
|
2015-10-05 23:24:04 +08:00
|
|
|
if (!includeInSymtab<ELFT>(*Body))
|
2015-09-23 07:38:23 +08:00
|
|
|
continue;
|
2015-10-24 16:52:46 +08:00
|
|
|
if (Out<ELFT>::SymTab)
|
|
|
|
Out<ELFT>::SymTab->addSymbol(Body);
|
2015-09-23 07:38:23 +08:00
|
|
|
|
2016-01-29 10:17:01 +08:00
|
|
|
if (isOutputDynamic() && includeInDynsym(*Body))
|
2015-10-21 05:47:58 +08:00
|
|
|
Out<ELFT>::DynSymTab->addSymbol(Body);
|
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.
|
|
|
|
if (HasError)
|
|
|
|
return false;
|
|
|
|
|
2015-10-09 07:49:30 +08:00
|
|
|
addCommonSymbols(CommonSymbols);
|
2015-12-26 18:07:03 +08:00
|
|
|
addCopyRelSymbols(CopyRelSymbols);
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2015-12-26 15:50:41 +08:00
|
|
|
// So far we have added sections from input object files.
|
|
|
|
// This function adds linker-created Out<ELFT>::* sections.
|
|
|
|
addPredefinedSections();
|
|
|
|
|
|
|
|
std::stable_sort(OutputSections.begin(), OutputSections.end(),
|
|
|
|
compareSections<ELFT>);
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = OutputSections.size(); I < N; ++I) {
|
|
|
|
OutputSections[I]->SectionIndex = I + 1;
|
|
|
|
HasRelro |= (Config->ZRelro && isRelroSection(OutputSections[I]));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections)
|
2016-01-29 09:24:25 +08:00
|
|
|
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
|
2015-12-26 15:50:41 +08:00
|
|
|
|
|
|
|
// Finalizers fix each section's size.
|
2016-01-26 05:32:04 +08:00
|
|
|
// .dynsym is finalized early since that may fill up .gnu.hash.
|
2015-12-26 15:50:41 +08:00
|
|
|
if (isOutputDynamic())
|
|
|
|
Out<ELFT>::DynSymTab->finalize();
|
|
|
|
|
2016-02-02 17:07:47 +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. The dynamic string table is
|
|
|
|
// finalized once the .dynamic finalizer has added a few last
|
|
|
|
// strings. See DynamicSection::finalize()
|
2015-12-26 15:50:41 +08:00
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections)
|
2016-02-02 17:07:47 +08:00
|
|
|
if (Sec != Out<ELFT>::DynStrTab && Sec != Out<ELFT>::Dynamic)
|
2016-01-26 05:32:04 +08:00
|
|
|
Sec->finalize();
|
2016-02-02 17:07:47 +08:00
|
|
|
|
|
|
|
if (isOutputDynamic())
|
|
|
|
Out<ELFT>::Dynamic->finalize();
|
2016-01-29 06:56:29 +08:00
|
|
|
return true;
|
2015-12-26 15:50:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// This function add Out<ELFT>::* sections to OutputSections.
|
|
|
|
template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
|
2015-12-26 18:34:33 +08:00
|
|
|
auto Add = [&](OutputSectionBase<ELFT> *C) {
|
|
|
|
if (C)
|
|
|
|
OutputSections.push_back(C);
|
|
|
|
};
|
|
|
|
|
2015-10-16 05:50:30 +08:00
|
|
|
// This order is not the same as the final output order
|
|
|
|
// because we sort the sections using their attributes below.
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::SymTab);
|
|
|
|
Add(Out<ELFT>::ShStrTab);
|
|
|
|
Add(Out<ELFT>::StrTab);
|
2015-10-13 07:39:23 +08:00
|
|
|
if (isOutputDynamic()) {
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::DynSymTab);
|
|
|
|
Add(Out<ELFT>::GnuHashTab);
|
|
|
|
Add(Out<ELFT>::HashTab);
|
|
|
|
Add(Out<ELFT>::Dynamic);
|
|
|
|
Add(Out<ELFT>::DynStrTab);
|
2015-10-08 03:18:16 +08:00
|
|
|
if (Out<ELFT>::RelaDyn->hasRelocs())
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::RelaDyn);
|
|
|
|
|
2015-11-12 12:39:49 +08:00
|
|
|
// This is a MIPS specific section to hold a space within the data segment
|
|
|
|
// of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.
|
|
|
|
// See "Dynamic section" in Chapter 5 in the following document:
|
|
|
|
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
|
|
|
if (Config->EMachine == EM_MIPS && !Config->Shared) {
|
2015-12-26 15:01:26 +08:00
|
|
|
Out<ELFT>::MipsRldMap = new OutputSection<ELFT>(".rld_map", SHT_PROGBITS,
|
|
|
|
SHF_ALLOC | SHF_WRITE);
|
2016-01-30 06:18:57 +08:00
|
|
|
Out<ELFT>::MipsRldMap->setSize(sizeof(uintX_t));
|
|
|
|
Out<ELFT>::MipsRldMap->updateAlign(sizeof(uintX_t));
|
2015-12-26 15:01:26 +08:00
|
|
|
OwningSections.emplace_back(Out<ELFT>::MipsRldMap);
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::MipsRldMap);
|
2015-11-12 12:39:49 +08:00
|
|
|
}
|
2015-09-09 23:33:08 +08:00
|
|
|
}
|
2015-11-12 12:39:49 +08:00
|
|
|
|
2015-12-21 18:12:06 +08:00
|
|
|
// We always need to add rel[a].plt to output if it has entries.
|
|
|
|
// Even during static linking it can contain R_[*]_IRELATIVE relocations.
|
|
|
|
if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::RelaPlt);
|
2015-12-21 18:12:06 +08:00
|
|
|
Out<ELFT>::RelaPlt->Static = !isOutputDynamic();
|
|
|
|
}
|
|
|
|
|
2015-12-21 18:00:12 +08:00
|
|
|
bool needsGot = !Out<ELFT>::Got->empty();
|
2015-11-12 12:39:49 +08:00
|
|
|
// We add the .got section to the result for dynamic MIPS target because
|
|
|
|
// its address and properties are mentioned in the .dynamic section.
|
2015-12-21 18:00:12 +08:00
|
|
|
if (Config->EMachine == EM_MIPS)
|
|
|
|
needsGot |= isOutputDynamic();
|
|
|
|
// If we have a relocation that is relative to GOT (such as GOTOFFREL),
|
|
|
|
// we need to emit a GOT even if it's empty.
|
|
|
|
if (HasGotOffRel)
|
|
|
|
needsGot = true;
|
|
|
|
|
|
|
|
if (needsGot)
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::Got);
|
2015-10-20 16:54:27 +08:00
|
|
|
if (Out<ELFT>::GotPlt && !Out<ELFT>::GotPlt->empty())
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::GotPlt);
|
2015-10-08 03:18:16 +08:00
|
|
|
if (!Out<ELFT>::Plt->empty())
|
2015-12-26 18:34:33 +08:00
|
|
|
Add(Out<ELFT>::Plt);
|
2016-01-15 21:34:52 +08:00
|
|
|
|
|
|
|
if (Out<ELFT>::EhFrameHdr->Live)
|
|
|
|
Add(Out<ELFT>::EhFrameHdr);
|
2015-08-13 23:23:46 +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() {
|
|
|
|
auto Define = [&](StringRef Start, StringRef End,
|
|
|
|
OutputSectionBase<ELFT> *OS) {
|
|
|
|
if (OS) {
|
|
|
|
Symtab.addSynthetic(Start, *OS, 0);
|
|
|
|
Symtab.addSynthetic(End, *OS, OS->getSize());
|
|
|
|
} else {
|
|
|
|
Symtab.addIgnored(Start);
|
|
|
|
Symtab.addIgnored(End);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Define("__preinit_array_start", "__preinit_array_end",
|
|
|
|
Out<ELFT>::Dynamic->PreInitArraySec);
|
|
|
|
Define("__init_array_start", "__init_array_end",
|
|
|
|
Out<ELFT>::Dynamic->InitArraySec);
|
|
|
|
Define("__fini_array_start", "__fini_array_end",
|
|
|
|
Out<ELFT>::Dynamic->FiniArraySec);
|
|
|
|
}
|
|
|
|
|
2015-10-16 01:11:03 +08:00
|
|
|
static bool isAlpha(char C) {
|
|
|
|
return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }
|
|
|
|
|
|
|
|
// Returns true if S is valid as a C language identifier.
|
|
|
|
static bool isValidCIdentifier(StringRef S) {
|
|
|
|
if (S.empty() || !isAlpha(S[0]))
|
|
|
|
return false;
|
|
|
|
return std::all_of(S.begin() + 1, S.end(), isAlnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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>
|
2015-10-16 06:27:29 +08:00
|
|
|
void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
|
2015-10-16 01:11:03 +08:00
|
|
|
StringRef S = Sec->getName();
|
|
|
|
if (!isValidCIdentifier(S))
|
|
|
|
return;
|
|
|
|
StringSaver Saver(Alloc);
|
|
|
|
StringRef Start = Saver.save("__start_" + S);
|
|
|
|
StringRef Stop = Saver.save("__stop_" + S);
|
2016-01-06 04:35:16 +08:00
|
|
|
if (SymbolBody *B = Symtab.find(Start))
|
|
|
|
if (B->isUndefined())
|
|
|
|
Symtab.addSynthetic(Start, *Sec, 0);
|
|
|
|
if (SymbolBody *B = Symtab.find(Stop))
|
|
|
|
if (B->isUndefined())
|
|
|
|
Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
|
2015-10-16 01:11:03 +08:00
|
|
|
}
|
|
|
|
|
2015-10-16 06:27:29 +08:00
|
|
|
template <class ELFT> static bool needsPhdr(OutputSectionBase<ELFT> *Sec) {
|
2015-09-18 03:58:07 +08:00
|
|
|
return Sec->getFlags() & SHF_ALLOC;
|
2015-09-10 04:48:09 +08:00
|
|
|
}
|
|
|
|
|
2015-10-25 02:22:59 +08:00
|
|
|
static uint32_t toPhdrFlags(uint64_t Flags) {
|
|
|
|
uint32_t Ret = PF_R;
|
|
|
|
if (Flags & SHF_WRITE)
|
|
|
|
Ret |= PF_W;
|
|
|
|
if (Flags & SHF_EXECINSTR)
|
|
|
|
Ret |= PF_X;
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2016-01-07 11:59:08 +08:00
|
|
|
/// For AMDGPU we need to use custom segment kinds in order to specify which
|
|
|
|
/// address space data should be loaded into.
|
|
|
|
template <class ELFT>
|
|
|
|
static uint32_t getAmdgpuPhdr(OutputSectionBase<ELFT> *Sec) {
|
|
|
|
uint32_t Flags = Sec->getFlags();
|
|
|
|
if (Flags & SHF_AMDGPU_HSA_CODE)
|
|
|
|
return PT_AMDGPU_HSA_LOAD_CODE_AGENT;
|
|
|
|
if ((Flags & SHF_AMDGPU_HSA_GLOBAL) && !(Flags & SHF_AMDGPU_HSA_AGENT))
|
|
|
|
return PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM;
|
|
|
|
return PT_LOAD;
|
|
|
|
}
|
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
template <class ELFT>
|
|
|
|
void Writer<ELFT>::updateRelro(Elf_Phdr *Cur, Elf_Phdr *GnuRelroPhdr,
|
2015-12-23 23:20:38 +08:00
|
|
|
uintX_t VA) {
|
2015-11-24 18:15:50 +08:00
|
|
|
if (!GnuRelroPhdr->p_type)
|
|
|
|
setPhdr(GnuRelroPhdr, PT_GNU_RELRO, PF_R, Cur->p_offset, Cur->p_vaddr,
|
|
|
|
VA - Cur->p_vaddr, 1 /*p_align*/);
|
|
|
|
GnuRelroPhdr->p_filesz = VA - Cur->p_vaddr;
|
|
|
|
GnuRelroPhdr->p_memsz = VA - Cur->p_vaddr;
|
|
|
|
}
|
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Visits all sections to create PHDRs and to assign incremental,
|
|
|
|
// non-overlapping addresses to output sections.
|
2015-07-25 05:03:07 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::assignAddresses() {
|
2015-11-10 16:39:27 +08:00
|
|
|
uintX_t VA = Target->getVAStart() + sizeof(Elf_Ehdr);
|
2015-10-11 06:34:30 +08:00
|
|
|
uintX_t FileOff = sizeof(Elf_Ehdr);
|
2015-09-10 04:48:09 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Calculate and reserve the space for the program header first so that
|
|
|
|
// the first section can start right after the program header.
|
|
|
|
Phdrs.resize(getPhdrsNum());
|
|
|
|
size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size();
|
2015-10-11 07:59:57 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// The first phdr entry is PT_PHDR which describes the program header itself.
|
|
|
|
setPhdr(&Phdrs[0], PT_PHDR, PF_R, FileOff, VA, PhdrSize, /*Align=*/8);
|
|
|
|
FileOff += PhdrSize;
|
|
|
|
VA += PhdrSize;
|
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.
|
|
|
|
int PhdrIdx = 0;
|
2015-10-11 07:59:57 +08:00
|
|
|
Elf_Phdr *Interp = nullptr;
|
2015-10-24 05:45:59 +08:00
|
|
|
if (needsInterpSection())
|
|
|
|
Interp = &Phdrs[++PhdrIdx];
|
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.
|
2015-11-10 16:39:27 +08:00
|
|
|
setPhdr(&Phdrs[++PhdrIdx], PT_LOAD, PF_R, 0, Target->getVAStart(), FileOff,
|
2016-01-29 09:49:32 +08:00
|
|
|
Target->PageSize);
|
2015-09-10 23:41:34 +08:00
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
Elf_Phdr GnuRelroPhdr = {};
|
2015-11-04 06:43:11 +08:00
|
|
|
Elf_Phdr TlsPhdr{};
|
2015-12-23 23:20:38 +08:00
|
|
|
bool RelroAligned = false;
|
2016-01-06 00:35:43 +08:00
|
|
|
uintX_t ThreadBssOffset = 0;
|
2015-10-24 05:45:59 +08:00
|
|
|
// Create phdrs as we assign VAs and file offsets to all output sections.
|
2015-10-16 06:27:29 +08:00
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
|
2015-12-23 23:20:38 +08:00
|
|
|
Elf_Phdr *PH = &Phdrs[PhdrIdx];
|
2015-11-04 07:19:42 +08:00
|
|
|
if (needsPhdr<ELFT>(Sec)) {
|
|
|
|
uintX_t Flags = toPhdrFlags(Sec->getFlags());
|
2015-12-23 23:20:38 +08:00
|
|
|
bool InRelRo = Config->ZRelro && (Flags & PF_W) && isRelroSection(Sec);
|
|
|
|
bool FirstNonRelRo = GnuRelroPhdr.p_type && !InRelRo && !RelroAligned;
|
|
|
|
if (FirstNonRelRo || PH->p_flags != Flags) {
|
2016-01-29 09:49:32 +08:00
|
|
|
VA = alignTo(VA, Target->PageSize);
|
|
|
|
FileOff = alignTo(FileOff, Target->PageSize);
|
2015-12-23 23:20:38 +08:00
|
|
|
if (FirstNonRelRo)
|
|
|
|
RelroAligned = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PH->p_flags != Flags) {
|
|
|
|
// Flags changed. Create a new PT_LOAD.
|
|
|
|
PH = &Phdrs[++PhdrIdx];
|
2016-01-07 11:59:08 +08:00
|
|
|
uint32_t PTType = (Config->EMachine != EM_AMDGPU) ? (uint32_t)PT_LOAD
|
|
|
|
: getAmdgpuPhdr(Sec);
|
2016-01-29 09:49:32 +08:00
|
|
|
setPhdr(PH, PTType, Flags, FileOff, VA, 0, Target->PageSize);
|
2015-09-18 03:58:07 +08:00
|
|
|
}
|
2015-09-10 04:48:09 +08:00
|
|
|
|
2015-11-04 07:19:42 +08:00
|
|
|
if (Sec->getFlags() & SHF_TLS) {
|
2015-11-07 06:14:44 +08:00
|
|
|
if (!TlsPhdr.p_vaddr)
|
2015-11-04 07:19:42 +08:00
|
|
|
setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
|
|
|
|
if (Sec->getType() != SHT_NOBITS)
|
2016-01-15 04:53:50 +08:00
|
|
|
VA = alignTo(VA, Sec->getAlign());
|
|
|
|
uintX_t TVA = alignTo(VA + ThreadBssOffset, Sec->getAlign());
|
2015-11-04 07:19:42 +08:00
|
|
|
Sec->setVA(TVA);
|
|
|
|
TlsPhdr.p_memsz += Sec->getSize();
|
|
|
|
if (Sec->getType() == SHT_NOBITS) {
|
2016-01-06 00:35:43 +08:00
|
|
|
ThreadBssOffset = TVA - VA + Sec->getSize();
|
2015-11-04 07:19:42 +08:00
|
|
|
} else {
|
|
|
|
TlsPhdr.p_filesz += Sec->getSize();
|
|
|
|
VA += Sec->getSize();
|
|
|
|
}
|
|
|
|
TlsPhdr.p_align = std::max<uintX_t>(TlsPhdr.p_align, Sec->getAlign());
|
2015-11-03 23:46:15 +08:00
|
|
|
} else {
|
2016-01-15 04:53:50 +08:00
|
|
|
VA = alignTo(VA, Sec->getAlign());
|
2015-11-04 07:19:42 +08:00
|
|
|
Sec->setVA(VA);
|
2015-11-03 08:34:39 +08:00
|
|
|
VA += Sec->getSize();
|
2015-12-23 23:20:38 +08:00
|
|
|
if (InRelRo)
|
|
|
|
updateRelro(PH, &GnuRelroPhdr, VA);
|
2015-11-03 08:34:39 +08:00
|
|
|
}
|
2015-08-13 23:31:17 +08:00
|
|
|
}
|
2015-11-03 08:34:39 +08:00
|
|
|
|
2016-01-15 04:53:50 +08:00
|
|
|
FileOff = alignTo(FileOff, Sec->getAlign());
|
2015-07-25 05:03:07 +08:00
|
|
|
Sec->setFileOffset(FileOff);
|
2015-09-01 04:23:57 +08:00
|
|
|
if (Sec->getType() != SHT_NOBITS)
|
2015-10-24 05:45:59 +08:00
|
|
|
FileOff += Sec->getSize();
|
2015-11-04 07:19:42 +08:00
|
|
|
if (needsPhdr<ELFT>(Sec)) {
|
2015-12-23 23:20:38 +08:00
|
|
|
PH->p_filesz = FileOff - PH->p_offset;
|
|
|
|
PH->p_memsz = VA - PH->p_vaddr;
|
2015-11-04 07:19:42 +08:00
|
|
|
}
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
2015-08-12 08:00:24 +08:00
|
|
|
|
2015-11-05 10:00:35 +08:00
|
|
|
if (TlsPhdr.p_vaddr) {
|
2015-11-07 06:14:44 +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.
|
2016-01-15 04:53:50 +08:00
|
|
|
TlsPhdr.p_memsz = alignTo(TlsPhdr.p_memsz, TlsPhdr.p_align);
|
2015-11-03 08:34:39 +08:00
|
|
|
Phdrs[++PhdrIdx] = TlsPhdr;
|
2015-11-07 06:14:44 +08:00
|
|
|
Out<ELFT>::TlsPhdr = &Phdrs[PhdrIdx];
|
2015-11-05 10:00:35 +08:00
|
|
|
}
|
2015-11-03 08:34:39 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Add an entry for .dynamic.
|
2015-10-13 07:39:23 +08:00
|
|
|
if (isOutputDynamic()) {
|
2015-10-24 05:45:59 +08:00
|
|
|
Elf_Phdr *PH = &Phdrs[++PhdrIdx];
|
2015-10-11 07:59:57 +08:00
|
|
|
PH->p_type = PT_DYNAMIC;
|
2015-10-12 03:45:58 +08:00
|
|
|
copyPhdr(PH, Out<ELFT>::Dynamic);
|
2015-10-11 06:34:30 +08:00
|
|
|
}
|
2015-08-12 09:45:28 +08:00
|
|
|
|
2015-11-24 18:15:50 +08:00
|
|
|
if (HasRelro) {
|
|
|
|
Elf_Phdr *PH = &Phdrs[++PhdrIdx];
|
|
|
|
*PH = GnuRelroPhdr;
|
|
|
|
}
|
|
|
|
|
2016-01-15 21:34:52 +08:00
|
|
|
if (Out<ELFT>::EhFrameHdr->Live) {
|
|
|
|
Elf_Phdr *PH = &Phdrs[++PhdrIdx];
|
|
|
|
PH->p_type = PT_GNU_EH_FRAME;
|
|
|
|
copyPhdr(PH, Out<ELFT>::EhFrameHdr);
|
|
|
|
}
|
|
|
|
|
2015-11-22 06:19:32 +08:00
|
|
|
// PT_GNU_STACK is a special section to tell the loader to make the
|
|
|
|
// pages for the stack non-executable.
|
2015-11-25 07:42:33 +08:00
|
|
|
if (!Config->ZExecStack) {
|
|
|
|
Elf_Phdr *PH = &Phdrs[++PhdrIdx];
|
|
|
|
PH->p_type = PT_GNU_STACK;
|
2015-11-22 06:19:32 +08:00
|
|
|
PH->p_flags = PF_R | PF_W;
|
2015-11-25 07:42:33 +08:00
|
|
|
}
|
2015-11-15 04:56:08 +08:00
|
|
|
|
2015-10-24 05:45:59 +08:00
|
|
|
// Fix up PT_INTERP as we now know the address of .interp section.
|
|
|
|
if (Interp) {
|
|
|
|
Interp->p_type = PT_INTERP;
|
|
|
|
copyPhdr(Interp, Out<ELFT>::Interp);
|
2015-10-11 07:25:39 +08:00
|
|
|
}
|
|
|
|
|
2015-07-29 08:30:10 +08:00
|
|
|
// Add space for section headers.
|
2016-01-30 06:18:57 +08:00
|
|
|
SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t));
|
2015-10-24 05:45:59 +08:00
|
|
|
FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
|
2015-11-06 15:43:03 +08:00
|
|
|
|
2015-11-20 10:32:35 +08:00
|
|
|
// Update "_end" and "end" symbols so that they
|
|
|
|
// point to the end of the data segment.
|
2015-12-25 14:12:18 +08:00
|
|
|
ElfSym<ELFT>::End.st_value = VA;
|
2015-10-24 05:45:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns the number of PHDR entries.
|
|
|
|
template <class ELFT> int Writer<ELFT>::getPhdrsNum() const {
|
2015-11-03 08:34:39 +08:00
|
|
|
bool Tls = false;
|
2015-11-25 07:42:33 +08:00
|
|
|
int I = 2; // 2 for PT_PHDR and first PT_LOAD
|
2015-10-24 05:45:59 +08:00
|
|
|
if (needsInterpSection())
|
|
|
|
++I;
|
|
|
|
if (isOutputDynamic())
|
|
|
|
++I;
|
2015-11-25 07:42:33 +08:00
|
|
|
if (!Config->ZExecStack)
|
|
|
|
++I;
|
2015-10-24 05:45:59 +08:00
|
|
|
uintX_t Last = PF_R;
|
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
|
2015-11-04 06:08:08 +08:00
|
|
|
if (!needsPhdr<ELFT>(Sec))
|
2015-10-24 05:45:59 +08:00
|
|
|
continue;
|
2015-11-03 08:34:39 +08:00
|
|
|
if (Sec->getFlags() & SHF_TLS)
|
|
|
|
Tls = true;
|
2015-10-24 05:45:59 +08:00
|
|
|
uintX_t Flags = toPhdrFlags(Sec->getFlags());
|
|
|
|
if (Last != Flags) {
|
|
|
|
Last = Flags;
|
|
|
|
++I;
|
|
|
|
}
|
|
|
|
}
|
2015-11-03 08:34:39 +08:00
|
|
|
if (Tls)
|
|
|
|
++I;
|
2015-11-24 18:15:50 +08:00
|
|
|
if (HasRelro)
|
|
|
|
++I;
|
2016-01-15 21:34:52 +08:00
|
|
|
if (Out<ELFT>::EhFrameHdr->Live)
|
|
|
|
++I;
|
2015-10-24 05:45:59 +08:00
|
|
|
return I;
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2015-12-19 13:51:49 +08:00
|
|
|
static uint32_t getELFFlags() {
|
|
|
|
if (Config->EMachine != EM_MIPS)
|
|
|
|
return 0;
|
|
|
|
// FIXME: In fact ELF flags depends on ELF flags of input object files
|
2016-01-12 14:24:02 +08:00
|
|
|
// and selected emulation. For now just use hard coded values.
|
2015-12-19 13:51:49 +08:00
|
|
|
uint32_t V = EF_MIPS_ABI_O32 | EF_MIPS_CPIC | EF_MIPS_ARCH_32R2;
|
|
|
|
if (Config->Shared)
|
|
|
|
V |= EF_MIPS_PIC;
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
2015-12-24 16:37:34 +08:00
|
|
|
template <class ELFT>
|
|
|
|
static typename ELFFile<ELFT>::uintX_t getEntryAddr() {
|
|
|
|
if (Config->EntrySym) {
|
2016-02-02 05:00:35 +08:00
|
|
|
if (SymbolBody *B = Config->EntrySym->repl())
|
|
|
|
return B->getVA<ELFT>();
|
2015-12-24 16:37:34 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (Config->EntryAddr != uint64_t(-1))
|
|
|
|
return Config->EntryAddr;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-12-26 18:52:26 +08:00
|
|
|
// This function is called after we have assigned address and size
|
|
|
|
// to each section. This function fixes some predefined absolute
|
|
|
|
// symbol values that depend on section address and size.
|
|
|
|
template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() {
|
|
|
|
// Update __rel[a]_iplt_{start,end} symbols so that they point
|
|
|
|
// to beginning or ending of .rela.plt section, respectively.
|
|
|
|
if (Out<ELFT>::RelaPlt) {
|
|
|
|
uintX_t Start = Out<ELFT>::RelaPlt->getVA();
|
|
|
|
ElfSym<ELFT>::RelaIpltStart.st_value = Start;
|
|
|
|
ElfSym<ELFT>::RelaIpltEnd.st_value = Start + Out<ELFT>::RelaPlt->getSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update MIPS _gp absolute symbol so that it points to the static data.
|
|
|
|
if (Config->EMachine == EM_MIPS)
|
|
|
|
ElfSym<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
|
|
|
|
}
|
|
|
|
|
2015-07-25 05:03:07 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::writeHeader() {
|
|
|
|
uint8_t *Buf = Buffer->getBufferStart();
|
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);
|
2015-08-05 23:08:40 +08:00
|
|
|
EHdr->e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
|
|
|
|
EHdr->e_ident[EI_DATA] = ELFT::TargetEndianness == llvm::support::little
|
|
|
|
? ELFDATA2LSB
|
|
|
|
: ELFDATA2MSB;
|
2015-07-25 05:03:07 +08:00
|
|
|
EHdr->e_ident[EI_VERSION] = EV_CURRENT;
|
2015-09-25 09:59:13 +08:00
|
|
|
|
2015-10-12 19:52:31 +08:00
|
|
|
auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf);
|
2015-09-25 09:59:13 +08:00
|
|
|
EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
|
2015-07-25 05:03:07 +08:00
|
|
|
|
2015-09-12 06:42:45 +08:00
|
|
|
EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC;
|
2015-09-04 04:03:54 +08:00
|
|
|
EHdr->e_machine = FirstObj.getEMachine();
|
2015-07-25 05:03:07 +08:00
|
|
|
EHdr->e_version = EV_CURRENT;
|
2015-12-24 16:37:34 +08:00
|
|
|
EHdr->e_entry = getEntryAddr<ELFT>();
|
2015-10-11 06:36:36 +08:00
|
|
|
EHdr->e_phoff = sizeof(Elf_Ehdr);
|
2015-07-29 08:30:10 +08:00
|
|
|
EHdr->e_shoff = SectionHeaderOff;
|
2015-12-19 13:51:49 +08:00
|
|
|
EHdr->e_flags = getELFFlags();
|
2015-09-09 05:57:31 +08:00
|
|
|
EHdr->e_ehsize = sizeof(Elf_Ehdr);
|
|
|
|
EHdr->e_phentsize = sizeof(Elf_Phdr);
|
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);
|
2015-09-09 01:39:39 +08:00
|
|
|
EHdr->e_shnum = getNumSections();
|
2015-10-21 01:21:35 +08:00
|
|
|
EHdr->e_shstrndx = Out<ELFT>::ShStrTab->SectionIndex;
|
2015-10-25 01:57:40 +08:00
|
|
|
|
|
|
|
// Write the program header table.
|
2015-10-11 08:10:36 +08:00
|
|
|
memcpy(Buf + EHdr->e_phoff, &Phdrs[0], Phdrs.size() * sizeof(Phdrs[0]));
|
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.
|
2015-09-09 05:57:31 +08:00
|
|
|
auto SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
|
2015-10-25 01:57:39 +08:00
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections)
|
2015-10-25 01:57:40 +08:00
|
|
|
Sec->writeHeaderTo(++SHdrs);
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
|
|
|
|
2016-02-03 06:48:04 +08:00
|
|
|
template <class ELFT> bool Writer<ELFT>::openFile() {
|
2015-08-13 08:31:46 +08:00
|
|
|
ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
|
2016-02-03 06:48:04 +08:00
|
|
|
FileOutputBuffer::create(Config->OutputFile, FileSize,
|
|
|
|
FileOutputBuffer::F_executable);
|
|
|
|
if (error(BufferOrErr, "failed to open " + Config->OutputFile))
|
|
|
|
return false;
|
2015-08-13 08:31:46 +08:00
|
|
|
Buffer = std::move(*BufferOrErr);
|
2016-02-03 06:48:04 +08:00
|
|
|
return true;
|
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
|
|
|
|
|
|
|
// PPC64 needs to process relocations in the .opd section before processing
|
|
|
|
// relocations in code-containing sections.
|
2015-10-16 06:27:29 +08:00
|
|
|
if (OutputSectionBase<ELFT> *Sec = Out<ELFT>::Opd) {
|
2015-10-13 22:45:51 +08:00
|
|
|
Out<ELFT>::OpdBuf = Buf + Sec->getFileOff();
|
|
|
|
Sec->writeTo(Buf + Sec->getFileOff());
|
|
|
|
}
|
[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
|
|
|
|
2015-10-16 06:27:29 +08:00
|
|
|
for (OutputSectionBase<ELFT> *Sec : OutputSections)
|
2016-02-02 05:52:00 +08:00
|
|
|
if (Sec != Out<ELFT>::Opd)
|
[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
|
|
|
Sec->writeTo(Buf + Sec->getFileOff());
|
2015-07-25 05:03:07 +08:00
|
|
|
}
|
2015-10-10 05:07:25 +08:00
|
|
|
|
2015-10-24 06:44:37 +08:00
|
|
|
template <class ELFT>
|
2015-10-12 03:45:58 +08:00
|
|
|
void Writer<ELFT>::setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags,
|
2015-10-24 05:45:59 +08:00
|
|
|
uintX_t FileOff, uintX_t VA, uintX_t Size,
|
|
|
|
uintX_t Align) {
|
2015-10-11 06:34:30 +08:00
|
|
|
PH->p_type = Type;
|
|
|
|
PH->p_flags = Flags;
|
|
|
|
PH->p_offset = FileOff;
|
|
|
|
PH->p_vaddr = VA;
|
|
|
|
PH->p_paddr = VA;
|
2015-10-24 05:45:59 +08:00
|
|
|
PH->p_filesz = Size;
|
|
|
|
PH->p_memsz = Size;
|
2015-10-11 06:34:30 +08:00
|
|
|
PH->p_align = Align;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class ELFT>
|
2015-10-16 06:27:29 +08:00
|
|
|
void Writer<ELFT>::copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT> *From) {
|
2015-10-11 06:34:30 +08:00
|
|
|
PH->p_flags = toPhdrFlags(From->getFlags());
|
|
|
|
PH->p_offset = From->getFileOff();
|
|
|
|
PH->p_vaddr = From->getVA();
|
|
|
|
PH->p_paddr = From->getVA();
|
|
|
|
PH->p_filesz = From->getSize();
|
|
|
|
PH->p_memsz = From->getSize();
|
|
|
|
PH->p_align = From->getAlign();
|
|
|
|
}
|
|
|
|
|
2015-11-12 17:52:08 +08:00
|
|
|
template <class ELFT> void Writer<ELFT>::buildSectionMap() {
|
|
|
|
for (const std::pair<StringRef, std::vector<StringRef>> &OutSec :
|
|
|
|
Config->OutputSections)
|
|
|
|
for (StringRef Name : OutSec.second)
|
|
|
|
InputToOutputSection[Name] = OutSec.first;
|
|
|
|
}
|
|
|
|
|
2016-01-07 04:11:55 +08:00
|
|
|
template void elf2::writeResult<ELF32LE>(SymbolTable<ELF32LE> *Symtab);
|
|
|
|
template void elf2::writeResult<ELF32BE>(SymbolTable<ELF32BE> *Symtab);
|
|
|
|
template void elf2::writeResult<ELF64LE>(SymbolTable<ELF64LE> *Symtab);
|
|
|
|
template void elf2::writeResult<ELF64BE>(SymbolTable<ELF64BE> *Symtab);
|