Commit 0d9ba4fe authored by Dimitry Andric's avatar Dimitry Andric
Browse files

Vendor import of lld trunk r321414:

https://llvm.org/svn/llvm-project/lld/trunk@321414
parent eb1ff93d
......@@ -362,12 +362,12 @@ class AddressTableChunk : public Chunk {
size_t getSize() const override { return Size * 4; }
void writeTo(uint8_t *Buf) const override {
uint32_t Bit = 0;
// Pointer to thumb code must have the LSB set, so adjust it.
if (Config->Machine == ARMNT)
Bit = 1;
for (Export &E : Config->Exports) {
for (const Export &E : Config->Exports) {
uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
uint32_t Bit = 0;
// Pointer to thumb code must have the LSB set, so adjust it.
if (Config->Machine == ARMNT && !E.Data)
Bit = 1;
if (E.ForwardChunk) {
write32le(P, E.ForwardChunk->getRVA() | Bit);
} else {
......
......@@ -400,8 +400,8 @@ lld::elf::Patch843419Section::Patch843419Section(InputSection *P, uint64_t Off)
this->Parent = P->getParent();
PatchSym = addSyntheticLocal(
Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
getSize(), this);
addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, this);
getSize(), *this);
addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this);
}
uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {
......
......@@ -37,8 +37,8 @@ class ARM final : public TargetInfo {
void writePltHeader(uint8_t *Buf) const override;
void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
int32_t Index, unsigned RelOff) const override;
void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
void addPltHeaderSymbols(InputSectionBase *ISD) const override;
void addPltSymbols(InputSection &IS, uint64_t Off) const override;
void addPltHeaderSymbols(InputSection &ISD) const override;
bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
uint64_t BranchAddr, const Symbol &S) const override;
bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
......@@ -184,7 +184,7 @@ void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
write32le(Buf, S.getVA());
}
// Long form PLT Heade that does not have any restrictions on the displacement
// Long form PLT Header that does not have any restrictions on the displacement
// of the .plt from the .plt.got.
static void writePltHeaderLong(uint8_t *Buf) {
const uint8_t PltData[] = {
......@@ -232,8 +232,7 @@ void ARM::writePltHeader(uint8_t *Buf) const {
write32le(Buf + 28, TrapInstr);
}
void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
auto *IS = cast<InputSection>(ISD);
void ARM::addPltHeaderSymbols(InputSection &IS) const {
addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
}
......@@ -282,8 +281,7 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary
}
void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
auto *IS = cast<InputSection>(ISD);
void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
}
......
......@@ -1056,7 +1056,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// We need to create some reserved symbols such as _end. Create them.
if (!Config->Relocatable)
addReservedSymbols<ELFT>();
addReservedSymbols();
// Apply version scripts.
Symtab->scanVersionScript();
......@@ -1111,7 +1111,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// before decompressAndMergeSections because the .comment section is a
// mergeable section.
if (!Config->Relocatable)
InputSections.push_back(createCommentSection<ELFT>());
InputSections.push_back(createCommentSection());
// Do size optimizations: garbage collection, merging of SHF_MERGE sections
// and identical code folding.
......
......@@ -32,6 +32,7 @@
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::sys;
using namespace llvm::sys::fs;
using namespace lld;
......@@ -69,6 +70,50 @@ Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
return MBRef;
}
// Concatenates arguments to construct a string representing an error location.
static std::string createFileLineMsg(StringRef Path, unsigned Line) {
std::string Filename = path::filename(Path);
std::string Lineno = ":" + std::to_string(Line);
if (Filename == Path)
return Filename + Lineno;
return Filename + Lineno + " (" + Path.str() + Lineno + ")";
}
template <class ELFT>
static std::string getSrcMsgAux(ObjFile<ELFT> &File, const Symbol &Sym,
InputSectionBase &Sec, uint64_t Offset) {
// In DWARF, functions and variables are stored to different places.
// First, lookup a function for a given offset.
if (Optional<DILineInfo> Info = File.getDILineInfo(&Sec, Offset))
return createFileLineMsg(Info->FileName, Info->Line);
// If it failed, lookup again as a variable.
if (Optional<std::pair<std::string, unsigned>> FileLine =
File.getVariableLoc(Sym.getName()))
return createFileLineMsg(FileLine->first, FileLine->second);
// File.SourceFile contains STT_FILE symbol, and that is a last resort.
return File.SourceFile;
}
std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
uint64_t Offset) {
if (kind() != ObjKind)
return "";
switch (Config->EKind) {
default:
llvm_unreachable("Invalid kind");
case ELF32LEKind:
return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), Sym, Sec, Offset);
case ELF32BEKind:
return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), Sym, Sec, Offset);
case ELF64LEKind:
return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), Sym, Sec, Offset);
case ELF64BEKind:
return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), Sym, Sec, Offset);
}
}
template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(this));
const DWARFObject &Obj = Dwarf.getDWARFObj();
......@@ -384,8 +429,8 @@ void ObjFile<ELFT>::initializeSections(
// have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
if (Sec.sh_flags & SHF_LINK_ORDER) {
if (Sec.sh_link >= this->Sections.size())
fatal(toString(this) + ": invalid sh_link index: " +
Twine(Sec.sh_link));
fatal(toString(this) +
": invalid sh_link index: " + Twine(Sec.sh_link));
this->Sections[Sec.sh_link]->DependentSections.push_back(
cast<InputSection>(this->Sections[I]));
}
......@@ -454,11 +499,9 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
// Create a regular InputSection class that has the same contents
// as a given section.
InputSectionBase *toRegularSection(MergeInputSection *Sec) {
auto *Ret = make<InputSection>(Sec->Flags, Sec->Type, Sec->Alignment,
Sec->Data, Sec->Name);
Ret->File = Sec->File;
return Ret;
static InputSection *toRegularSection(MergeInputSection *Sec) {
return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
Sec->Data, Sec->Name);
}
template <class ELFT>
......@@ -471,13 +514,13 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
break;
ARMAttributeParser Attributes;
ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
Attributes.Parse(Contents, /*isLittle*/Config->EKind == ELF32LEKind);
Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
updateSupportedARMFeatures(Attributes);
// FIXME: Retain the first attribute section we see. The eglibc ARM
// dynamic loaders require the presence of an attribute section for dlopen
// to work. In a full implementation we would merge all attribute sections.
if (InX::ARMAttributes == nullptr) {
InX::ARMAttributes = make<InputSection>(this, &Sec, Name);
InX::ARMAttributes = make<InputSection>(*this, Sec, Name);
return InX::ARMAttributes;
}
return &InputSection::Discarded;
......@@ -496,7 +539,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// If -r is given, we do not interpret or apply relocation
// but just copy relocation sections to output.
if (Config->Relocatable)
return make<InputSection>(this, &Sec, Name);
return make<InputSection>(*this, Sec, Name);
if (Target->FirstRelocation)
fatal(toString(this) +
......@@ -534,7 +577,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// However, if -emit-relocs is given, we need to leave them in the output.
// (Some post link analysis tools need this information.)
if (Config->EmitRelocs) {
InputSection *RelocSec = make<InputSection>(this, &Sec, Name);
InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
// We will not emit relocation section if target was discarded.
Target->DependentSections.push_back(RelocSec);
return RelocSec;
......@@ -581,11 +624,11 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
if (Name == ".eh_frame" && !Config->Relocatable)
return make<EhInputSection>(this, &Sec, Name);
return make<EhInputSection>(*this, Sec, Name);
if (shouldMerge(Sec))
return make<MergeInputSection>(this, &Sec, Name);
return make<InputSection>(this, &Sec, Name);
return make<MergeInputSection>(*this, Sec, Name);
return make<InputSection>(*this, Sec, Name);
}
template <class ELFT>
......@@ -636,7 +679,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
if (Value == 0 || Value >= UINT32_MAX)
fatal(toString(this) + ": common symbol '" + Name +
"' has invalid alignment: " + Twine(Value));
return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, this);
return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, *this);
}
switch (Binding) {
......@@ -648,8 +691,8 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) {
if (Sec == &InputSection::Discarded)
return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
/*CanOmitFromDynSym=*/false, this);
return Symtab->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding,
Sec, this);
return Symtab->addRegular(Name, StOther, Type, Value, Size, Binding, Sec,
this);
}
}
......@@ -660,7 +703,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
template <class ELFT> void ArchiveFile::parse() {
Symbols.reserve(File->getNumberOfSymbols());
for (const Archive::Symbol &Sym : File->symbols())
Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), this, Sym));
Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym));
}
// Returns a buffer pointing to a member file containing a given symbol.
......@@ -841,14 +884,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
error(toString(this) + ": alignment too large: " + Name);
if (!Hidden)
Symtab->addShared(Name, this, Sym, Alignment, VersymIndex);
Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex);
// Also add the symbol with the versioned name to handle undefined symbols
// with explicit versions.
if (Ver) {
StringRef VerName = this->StringTable.data() + Ver->getAux()->vda_name;
Name = Saver.save(Name + "@" + VerName);
Symtab->addShared(Name, this, Sym, Alignment, VersymIndex);
Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex);
}
}
}
......@@ -925,7 +968,7 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
template <class ELFT>
static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
const lto::InputFile::Symbol &ObjSym,
BitcodeFile *F) {
BitcodeFile &F) {
StringRef NameRef = Saver.save(ObjSym.getName());
uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
......@@ -936,11 +979,11 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
int C = ObjSym.getComdatIndex();
if (C != -1 && !KeptComdats[C])
return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
CanOmitFromDynSym, F);
CanOmitFromDynSym, &F);
if (ObjSym.isUndefined())
return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
CanOmitFromDynSym, F);
CanOmitFromDynSym, &F);
if (ObjSym.isCommon())
return Symtab->addCommon(NameRef, ObjSym.getCommonSize(),
......@@ -958,7 +1001,7 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second);
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
}
static ELFKind getELFKind(MemoryBufferRef MB) {
......@@ -981,10 +1024,10 @@ static ELFKind getELFKind(MemoryBufferRef MB) {
return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
}
template <class ELFT> void BinaryFile::parse() {
void BinaryFile::parse() {
ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
auto *Section =
make<InputSection>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 8, Data, ".data");
auto *Section = make<InputSection>(nullptr, SHF_ALLOC | SHF_WRITE,
SHT_PROGBITS, 8, Data, ".data");
Sections.push_back(Section);
// For each input file foo that is embedded to a result as a binary
......@@ -996,12 +1039,12 @@ template <class ELFT> void BinaryFile::parse() {
if (!isAlnum(S[I]))
S[I] = '_';
Symtab->addRegular<ELFT>(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT,
0, 0, STB_GLOBAL, Section, nullptr);
Symtab->addRegular<ELFT>(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
Data.size(), 0, STB_GLOBAL, Section, nullptr);
Symtab->addRegular<ELFT>(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
Symtab->addRegular(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
STB_GLOBAL, Section, nullptr);
Symtab->addRegular(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
Data.size(), 0, STB_GLOBAL, Section, nullptr);
Symtab->addRegular(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
}
static bool isBitcode(MemoryBufferRef MB) {
......@@ -1145,8 +1188,3 @@ template class elf::SharedFile<ELF32LE>;
template class elf::SharedFile<ELF32BE>;
template class elf::SharedFile<ELF64LE>;
template class elf::SharedFile<ELF64BE>;
template void BinaryFile::parse<ELF32LE>();
template void BinaryFile::parse<ELF32BE>();
template void BinaryFile::parse<ELF64LE>();
template void BinaryFile::parse<ELF64BE>();
......@@ -72,6 +72,11 @@ class InputFile {
Kind kind() const { return FileKind; }
bool isElf() const {
Kind K = kind();
return K == ObjKind || K == SharedKind;
}
StringRef getName() const { return MB.getBufferIdentifier(); }
MemoryBufferRef MB;
......@@ -104,6 +109,9 @@ class InputFile {
// Cache for toString(). Only toString() should use this member.
mutable std::string ToStringCache;
std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
uint64_t Offset);
protected:
InputFile(Kind K, MemoryBufferRef M);
std::vector<InputSectionBase *> Sections;
......@@ -121,10 +129,7 @@ template <typename ELFT> class ELFFileBase : public InputFile {
typedef typename ELFT::SymRange Elf_Sym_Range;
ELFFileBase(Kind K, MemoryBufferRef M);
static bool classof(const InputFile *F) {
Kind K = F->kind();
return K == ObjKind || K == SharedKind;
}
static bool classof(const InputFile *F) { return F->isElf(); }
llvm::object::ELFFile<ELFT> getObj() const {
return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
......@@ -325,7 +330,7 @@ class BinaryFile : public InputFile {
public:
explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
template <class ELFT> void parse();
void parse();
};
InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
......
......@@ -24,7 +24,6 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/xxhash.h"
#include <mutex>
......@@ -73,11 +72,11 @@ DenseMap<SectionBase *, int> elf::buildSectionOrder() {
}
template <class ELFT>
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> *File,
const typename ELFT::Shdr *Hdr) {
if (!File || Hdr->sh_type == SHT_NOBITS)
return makeArrayRef<uint8_t>(nullptr, Hdr->sh_size);
return check(File->getObj().getSectionContents(Hdr));
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File,
const typename ELFT::Shdr &Hdr) {
if (Hdr.sh_type == SHT_NOBITS)
return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size);
return check(File.getObj().getSectionContents(&Hdr));
}
InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
......@@ -88,6 +87,12 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
: SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
Link),
File(File), Data(Data) {
// In order to reduce memory allocation, we assume that mergeable
// sections are smaller than 4 GiB, which is not an unreasonable
// assumption as of 2017.
if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX)
error(toString(this) + ": section too large");
NumRelocations = 0;
AreRelocsRela = false;
......@@ -128,18 +133,18 @@ static uint64_t getType(uint64_t Type, StringRef Name) {
}
template <class ELFT>
InputSectionBase::InputSectionBase(ObjFile<ELFT> *File,
const typename ELFT::Shdr *Hdr,
InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
const typename ELFT::Shdr &Hdr,
StringRef Name, Kind SectionKind)
: InputSectionBase(File, getFlags(Hdr->sh_flags),
getType(Hdr->sh_type, Name), Hdr->sh_entsize,
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
: InputSectionBase(&File, getFlags(Hdr.sh_flags),
getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link,
Hdr.sh_info, Hdr.sh_addralign,
getSectionContents(File, Hdr), Name, SectionKind) {
// We reject object files having insanely large alignments even though
// they are allowed by the spec. I think 4GB is a reasonable limitation.
// We might want to relax this in the future.
if (Hdr->sh_addralign > UINT32_MAX)
fatal(toString(File) + ": section sh_addralign is too large");
if (Hdr.sh_addralign > UINT32_MAX)
fatal(toString(&File) + ": section sh_addralign is too large");
}
size_t InputSectionBase::getSize() const {
......@@ -211,8 +216,8 @@ void InputSectionBase::maybeUncompress() {
fatal(toString(this) +
": decompress failed: " + llvm::toString(std::move(E)));
this->Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size);
this->Flags &= ~(uint64_t)SHF_COMPRESSED;
Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size);
Flags &= ~(uint64_t)SHF_COMPRESSED;
}
InputSection *InputSectionBase::getLinkOrderDep() const {
......@@ -257,40 +262,17 @@ std::string InputSectionBase::getLocation(uint64_t Offset) {
return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
}
// Concatenates arguments to construct a string representing an error location.
static std::string createFileLineMsg(StringRef Path, unsigned Line) {
std::string Filename = path::filename(Path);
std::string Lineno = ":" + std::to_string(Line);
if (Filename == Path)
return Filename + Lineno;
return Filename + Lineno + " (" + Path.str() + Lineno + ")";
}
// This function is intended to be used for constructing an error message.
// The returned message looks like this:
//
// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
//
// Returns an empty string if there's no way to get line info.
template <class ELFT>
std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
// Synthetic sections don't have input files.
ObjFile<ELFT> *File = getFile<ELFT>();
if (!File)
return "";
// In DWARF, functions and variables are stored to different places.
// First, lookup a function for a given offset.
if (Optional<DILineInfo> Info = File->getDILineInfo(this, Offset))
return createFileLineMsg(Info->FileName, Info->Line);
// If it failed, lookup again as a variable.
if (Optional<std::pair<std::string, unsigned>> FileLine =
File->getVariableLoc(Sym.getName()))
return createFileLineMsg(FileLine->first, FileLine->second);
// File->SourceFile contains STT_FILE symbol, and that is a last resort.
return File->SourceFile;
return File->getSrcMsg(Sym, *this, Offset);
}
// Returns a filename string along with an optional section name. This
......@@ -323,16 +305,17 @@ std::string InputSectionBase::getObjMsg(uint64_t Off) {
.str();
}
InputSection InputSection::Discarded(0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection::InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
ArrayRef<uint8_t> Data, StringRef Name, Kind K)
: InputSectionBase(nullptr, Flags, Type,
InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type,
uint32_t Alignment, ArrayRef<uint8_t> Data,
StringRef Name, Kind K)
: InputSectionBase(F, Flags, Type,
/*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
Name, K) {}
template <class ELFT>
InputSection::InputSection(ObjFile<ELFT> *F, const typename ELFT::Shdr *Header,
InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
StringRef Name)
: InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
......@@ -357,15 +340,15 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
// Adjust section numbers because section numbers in an input object
// files are different in the output.
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
ArrayRef<InputSectionBase *> Sections = File->getSections();
for (uint32_t Idx : From.slice(1))
*To++ = Sections[Idx]->getOutputSection()->SectionIndex;
}
InputSectionBase *InputSection::getRelocatedSection() {
assert(this->Type == SHT_RELA || this->Type == SHT_REL);
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
return Sections[this->Info];
assert(Type == SHT_RELA || Type == SHT_REL);
ArrayRef<InputSectionBase *> Sections = File->getSections();
return Sections[Info];
}
// This is used for -r and --emit-relocs. We can't use memcpy to copy
......@@ -377,7 +360,7 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
for (const RelTy &Rel : Rels) {
RelType Type = Rel.getType(Config->IsMips64EL);
Symbol &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel);
Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
Buf += sizeof(RelTy);
......@@ -679,7 +662,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
if (!RelTy::IsRela)
Addend += Target->getImplicitAddend(BufLoc, Type);
Symbol &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel);
Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
if (Expr == R_NONE)
continue;
......@@ -691,7 +674,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
continue;
error(this->getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
error(getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
toString(Type) + " against symbol '" + toString(Sym) + "'");
return;
}
......@@ -765,7 +748,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
}
template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
if (this->Type == SHT_NOBITS)
if (Type == SHT_NOBITS)
return;
if (auto *S = dyn_cast<SyntheticSection>(this)) {
......@@ -775,19 +758,17 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
// If -r or --emit-relocs is given, then an InputSection
// may be a relocation section.
if (this->Type == SHT_RELA) {
copyRelocations<ELFT>(Buf + OutSecOff,
this->template getDataAs<typename ELFT::Rela>());
if (Type == SHT_RELA) {
copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>());
return;
}
if (this->Type == SHT_REL) {
copyRelocations<ELFT>(Buf + OutSecOff,
this->template getDataAs<typename ELFT::Rel>());
if (Type == SHT_REL) {
copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>());
return;
}
// If -r is given, we may have a SHT_GROUP section.
if (this->Type == SHT_GROUP) {
if (Type == SHT_GROUP) {
copyShtGroup<ELFT>(Buf + OutSecOff);
return;
}
......@@ -796,18 +777,18 @@ template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
// and then apply relocations.
memcpy(Buf + OutSecOff, Data.data(), Data.size());
uint8_t *BufEnd = Buf + OutSecOff + Data.size();
this->relocate<ELFT>(Buf, BufEnd);
relocate<ELFT>(Buf, BufEnd);