From owner-svn-src-projects@freebsd.org Sun Dec 24 01:11:21 2017 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F1974E894C3 for ; Sun, 24 Dec 2017 01:11:21 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7AE877FFEB; Sun, 24 Dec 2017 01:11:21 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vBO1BKhw080902; Sun, 24 Dec 2017 01:11:20 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vBO1BJeA080891; Sun, 24 Dec 2017 01:11:19 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201712240111.vBO1BJeA080891@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Sun, 24 Dec 2017 01:11:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r327136 - in projects/clang600-import/contrib/llvm/tools/lld: . COFF ELF ELF/Arch X-SVN-Group: projects X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in projects/clang600-import/contrib/llvm/tools/lld: . COFF ELF ELF/Arch X-SVN-Commit-Revision: 327136 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Dec 2017 01:11:22 -0000 Author: dim Date: Sun Dec 24 01:11:19 2017 New Revision: 327136 URL: https://svnweb.freebsd.org/changeset/base/327136 Log: Merge lld trunk r321414 to contrib/llvm/tools/lld. Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.h projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.h projects/clang600-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/ScriptParser.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/SymbolTable.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/SymbolTable.h projects/clang600-import/contrib/llvm/tools/lld/ELF/Symbols.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Symbols.h projects/clang600-import/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/SyntheticSections.h projects/clang600-import/contrib/llvm/tools/lld/ELF/Target.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Target.h projects/clang600-import/contrib/llvm/tools/lld/ELF/Thunks.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Writer.cpp projects/clang600-import/contrib/llvm/tools/lld/ELF/Writer.h projects/clang600-import/contrib/llvm/tools/lld/README.md Directory Properties: projects/clang600-import/contrib/llvm/tools/lld/ (props changed) Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -362,12 +362,12 @@ class AddressTableChunk : public Chunk { (public) 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 { Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -400,8 +400,8 @@ lld::elf::Patch843419Section::Patch843419Section(Input 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 { Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -37,8 +37,8 @@ class ARM final : public TargetInfo { (public) 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) 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(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 GotPltEntryA write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary } -void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const { - auto *IS = cast(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); } Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -1056,7 +1056,7 @@ template void LinkerDriver::link(opt::Inp // We need to create some reserved symbols such as _end. Create them. if (!Config->Relocatable) - addReservedSymbols(); + addReservedSymbols(); // Apply version scripts. Symtab->scanVersionScript(); @@ -1111,7 +1111,7 @@ template void LinkerDriver::link(opt::Inp // before decompressAndMergeSections because the .comment section is a // mergeable section. if (!Config->Relocatable) - InputSections.push_back(createCommentSection()); + InputSections.push_back(createCommentSection()); // Do size optimizations: garbage collection, merging of SHF_MERGE sections // and identical code folding. Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -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 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 +static std::string getSrcMsgAux(ObjFile &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 Info = File.getDILineInfo(&Sec, Offset)) + return createFileLineMsg(Info->FileName, Info->Line); + + // If it failed, lookup again as a variable. + if (Optional> 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>(*this), Sym, Sec, Offset); + case ELF32BEKind: + return getSrcMsgAux(cast>(*this), Sym, Sec, Offset); + case ELF64LEKind: + return getSrcMsgAux(cast>(*this), Sym, Sec, Offset); + case ELF64BEKind: + return getSrcMsgAux(cast>(*this), Sym, Sec, Offset); + } +} + template void ObjFile::initializeDwarf() { DWARFContext Dwarf(make_unique>(this)); const DWARFObject &Obj = Dwarf.getDWARFObj(); @@ -384,8 +429,8 @@ void ObjFile::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(this->Sections[I])); } @@ -454,11 +499,9 @@ InputSectionBase *ObjFile::getRelocTarget(const // Create a regular InputSection class that has the same contents // as a given section. -InputSectionBase *toRegularSection(MergeInputSection *Sec) { - auto *Ret = make(Sec->Flags, Sec->Type, Sec->Alignment, - Sec->Data, Sec->Name); - Ret->File = Sec->File; - return Ret; +static InputSection *toRegularSection(MergeInputSection *Sec) { + return make(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment, + Sec->Data, Sec->Name); } template @@ -471,13 +514,13 @@ InputSectionBase *ObjFile::createInputSection(co break; ARMAttributeParser Attributes; ArrayRef 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(this, &Sec, Name); + InX::ARMAttributes = make(*this, Sec, Name); return InX::ARMAttributes; } return &InputSection::Discarded; @@ -496,7 +539,7 @@ InputSectionBase *ObjFile::createInputSection(co // If -r is given, we do not interpret or apply relocation // but just copy relocation sections to output. if (Config->Relocatable) - return make(this, &Sec, Name); + return make(*this, Sec, Name); if (Target->FirstRelocation) fatal(toString(this) + @@ -534,7 +577,7 @@ InputSectionBase *ObjFile::createInputSection(co // 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(this, &Sec, Name); + InputSection *RelocSec = make(*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::createInputSection(co // .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(this, &Sec, Name); + return make(*this, Sec, Name); if (shouldMerge(Sec)) - return make(this, &Sec, Name); - return make(this, &Sec, Name); + return make(*this, Sec, Name); + return make(*this, Sec, Name); } template @@ -636,7 +679,7 @@ template Symbol *ObjFile::createSym 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 Symbol *ObjFile::createSym if (Sec == &InputSection::Discarded) return Symtab->addUndefined(Name, Binding, StOther, Type, /*CanOmitFromDynSym=*/false, this); - return Symtab->addRegular(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 &&Fi template void ArchiveFile::parse() { Symbols.reserve(File->getNumberOfSymbols()); for (const Archive::Symbol &Sym : File->symbols()) - Symbols.push_back(Symtab->addLazyArchive(Sym.getName(), this, Sym)); + Symbols.push_back(Symtab->addLazyArchive(Sym.getName(), *this, Sym)); } // Returns a buffer pointing to a member file containing a given symbol. @@ -841,14 +884,14 @@ template void SharedFile::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::VisibilityTy template static Symbol *createBitcodeSymbol(const std::vector &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::vectoraddUndefined(NameRef, Binding, Visibility, Type, - CanOmitFromDynSym, F); + CanOmitFromDynSym, &F); if (ObjSym.isUndefined()) return Symtab->addUndefined(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 KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second); for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) - Symbols.push_back(createBitcodeSymbol(KeptComdats, ObjSym, this)); + Symbols.push_back(createBitcodeSymbol(KeptComdats, ObjSym, *this)); } static ELFKind getELFKind(MemoryBufferRef MB) { @@ -981,10 +1024,10 @@ static ELFKind getELFKind(MemoryBufferRef MB) { return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind; } -template void BinaryFile::parse() { +void BinaryFile::parse() { ArrayRef Data = toArrayRef(MB.getBuffer()); - auto *Section = - make(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 8, Data, ".data"); + auto *Section = make(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 void BinaryFile::parse() { if (!isAlnum(S[I])) S[I] = '_'; - 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); + 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; template class elf::SharedFile; template class elf::SharedFile; template class elf::SharedFile; - -template void BinaryFile::parse(); -template void BinaryFile::parse(); -template void BinaryFile::parse(); -template void BinaryFile::parse(); Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.h ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.h Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.h Sun Dec 24 01:11:19 2017 (r327136) @@ -72,6 +72,11 @@ class InputFile { (public) 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 { (public) // 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 Sections; @@ -121,10 +129,7 @@ template class ELFFileBase : public In 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 getObj() const { return check(llvm::object::ELFFile::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 void parse(); + void parse(); }; InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "", Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -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 @@ -73,11 +72,11 @@ DenseMap elf::buildSectionOrder() } template -static ArrayRef getSectionContents(ObjFile *File, - const typename ELFT::Shdr *Hdr) { - if (!File || Hdr->sh_type == SHT_NOBITS) - return makeArrayRef(nullptr, Hdr->sh_size); - return check(File->getObj().getSectionContents(Hdr)); +static ArrayRef getSectionContents(ObjFile &File, + const typename ELFT::Shdr &Hdr) { + if (Hdr.sh_type == SHT_NOBITS) + return makeArrayRef(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, ui : 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 -InputSectionBase::InputSectionBase(ObjFile *File, - const typename ELFT::Shdr *Hdr, +InputSectionBase::InputSectionBase(ObjFile &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 Off 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 std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) { // Synthetic sections don't have input files. - ObjFile *File = getFile(); if (!File) return ""; - - // In DWARF, functions and variables are stored to different places. - // First, lookup a function for a given offset. - if (Optional Info = File->getDILineInfo(this, Offset)) - return createFileLineMsg(Info->FileName, Info->Line); - - // If it failed, lookup again as a variable. - if (Optional> 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(), ""); +InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef(), ""); -InputSection::InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, - ArrayRef Data, StringRef Name, Kind K) - : InputSectionBase(nullptr, Flags, Type, +InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type, + uint32_t Alignment, ArrayRef Data, + StringRef Name, Kind K) + : InputSectionBase(F, Flags, Type, /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data, Name, K) {} template -InputSection::InputSection(ObjFile *F, const typename ELFT::Shdr *Header, +InputSection::InputSection(ObjFile &F, const typename ELFT::Shdr &Header, StringRef Name) : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {} @@ -357,15 +340,15 @@ template void InputSection::copyShtGroup( // Adjust section numbers because section numbers in an input object // files are different in the output. - ArrayRef Sections = this->File->getSections(); + ArrayRef 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 Sections = this->File->getSections(); - return Sections[this->Info]; + assert(Type == SHT_RELA || Type == SHT_REL); + ArrayRef 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, Array for (const RelTy &Rel : Rels) { RelType Type = Rel.getType(Config->IsMips64EL); - Symbol &Sym = this->getFile()->getRelocTargetSym(Rel); + Symbol &Sym = getFile()->getRelocTargetSym(Rel); auto *P = reinterpret_cast(Buf); Buf += sizeof(RelTy); @@ -679,7 +662,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, Arra if (!RelTy::IsRela) Addend += Target->getImplicitAddend(BufLoc, Type); - Symbol &Sym = this->getFile()->getRelocTargetSym(Rel); + Symbol &Sym = getFile()->getRelocTargetSym(Rel); RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc); if (Expr == R_NONE) continue; @@ -691,7 +674,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, Arra if (Config->EMachine == EM_386 && Type == R_386_GOTPC) continue; - error(this->getLocation(Offset) + ": has non-ABS relocation " + + error(getLocation(Offset) + ": has non-ABS relocation " + toString(Type) + " against symbol '" + toString(Sym) + "'"); return; } @@ -765,7 +748,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uin } template void InputSection::writeTo(uint8_t *Buf) { - if (this->Type == SHT_NOBITS) + if (Type == SHT_NOBITS) return; if (auto *S = dyn_cast(this)) { @@ -775,19 +758,17 @@ template void InputSection::writeTo(uint8 // If -r or --emit-relocs is given, then an InputSection // may be a relocation section. - if (this->Type == SHT_RELA) { - copyRelocations(Buf + OutSecOff, - this->template getDataAs()); + if (Type == SHT_RELA) { + copyRelocations(Buf + OutSecOff, getDataAs()); return; } - if (this->Type == SHT_REL) { - copyRelocations(Buf + OutSecOff, - this->template getDataAs()); + if (Type == SHT_REL) { + copyRelocations(Buf + OutSecOff, getDataAs()); return; } // If -r is given, we may have a SHT_GROUP section. - if (this->Type == SHT_GROUP) { + if (Type == SHT_GROUP) { copyShtGroup(Buf + OutSecOff); return; } @@ -796,18 +777,18 @@ template void InputSection::writeTo(uint8 // and then apply relocations. memcpy(Buf + OutSecOff, Data.data(), Data.size()); uint8_t *BufEnd = Buf + OutSecOff + Data.size(); - this->relocate(Buf, BufEnd); + relocate(Buf, BufEnd); } void InputSection::replace(InputSection *Other) { - this->Alignment = std::max(this->Alignment, Other->Alignment); - Other->Repl = this->Repl; + Alignment = std::max(Alignment, Other->Alignment); + Other->Repl = Repl; Other->Live = false; } template -EhInputSection::EhInputSection(ObjFile *F, - const typename ELFT::Shdr *Header, +EhInputSection::EhInputSection(ObjFile &F, + const typename ELFT::Shdr &Header, StringRef Name) : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {} @@ -838,22 +819,21 @@ static unsigned getReloc(IntTy Begin, IntTy Size, cons // This function splits an input section into records and returns them. template void EhInputSection::split() { // Early exit if already split. - if (!this->Pieces.empty()) + if (!Pieces.empty()) return; - if (this->AreRelocsRela) - split(this->relas()); + if (AreRelocsRela) + split(relas()); else - split(this->rels()); + split(rels()); } template void EhInputSection::split(ArrayRef Rels) { - ArrayRef Data = this->Data; unsigned RelI = 0; for (size_t Off = 0, End = Data.size(); Off != End;) { size_t Size = readEhRecordSize(this, Off); - this->Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI)); + Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI)); // The empty record is the end marker. if (Size == 4) break; @@ -882,7 +862,7 @@ SyntheticSection *MergeInputSection::getParent() const // null-terminated strings. void MergeInputSection::splitStrings(ArrayRef Data, size_t EntSize) { size_t Off = 0; - bool IsAlloc = this->Flags & SHF_ALLOC; + bool IsAlloc = Flags & SHF_ALLOC; StringRef S = toStringRef(Data); while (!S.empty()) { @@ -903,7 +883,7 @@ void MergeInputSection::splitNonStrings(ArrayRefFlags & SHF_ALLOC; + bool IsAlloc = Flags & SHF_ALLOC; for (size_t I = 0; I != Size; I += EntSize) Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))), @@ -911,17 +891,17 @@ void MergeInputSection::splitNonStrings(ArrayRef -MergeInputSection::MergeInputSection(ObjFile *F, - const typename ELFT::Shdr *Header, +MergeInputSection::MergeInputSection(ObjFile &F, + const typename ELFT::Shdr &Header, StringRef Name) - : InputSectionBase(F, Header, Name, InputSectionBase::Merge) { - // 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 (Data.size() > UINT32_MAX) - error(toString(this) + ": section too large"); -} + : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {} +MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type, + uint64_t Entsize, ArrayRef Data, + StringRef Name) + : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0, + /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {} + // This function is called after we obtain a complete list of input sections // that need to be linked. This is responsible to split section contents // into small chunks for further processing. @@ -931,14 +911,14 @@ MergeInputSection::MergeInputSection(ObjFile *F, void MergeInputSection::splitIntoPieces() { assert(Pieces.empty()); - if (this->Flags & SHF_STRINGS) + if (Flags & SHF_STRINGS) splitStrings(Data, Entsize); else splitNonStrings(Data, Entsize); - if (Config->GcSections && (this->Flags & SHF_ALLOC)) + if (Config->GcSections && (Flags & SHF_ALLOC)) for (uint64_t Off : LiveOffsets) - this->getSectionPiece(Off)->Live = true; + getSectionPiece(Off)->Live = true; } // Do binary search to get a section piece at a given input offset. @@ -993,7 +973,7 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) // If Offset is not at beginning of a section piece, it is not in the map. // In that case we need to search from the original section piece vector. - const SectionPiece &Piece = *this->getSectionPiece(Offset); + const SectionPiece &Piece = *getSectionPiece(Offset); if (!Piece.Live) return 0; @@ -1001,13 +981,13 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset) return Piece.OutputOff + Addend; } -template InputSection::InputSection(ObjFile *, const ELF32LE::Shdr *, +template InputSection::InputSection(ObjFile &, const ELF32LE::Shdr &, StringRef); -template InputSection::InputSection(ObjFile *, const ELF32BE::Shdr *, +template InputSection::InputSection(ObjFile &, const ELF32BE::Shdr &, StringRef); -template InputSection::InputSection(ObjFile *, const ELF64LE::Shdr *, +template InputSection::InputSection(ObjFile &, const ELF64LE::Shdr &, StringRef); -template InputSection::InputSection(ObjFile *, const ELF64BE::Shdr *, +template InputSection::InputSection(ObjFile &, const ELF64BE::Shdr &, StringRef); template std::string InputSectionBase::getLocation(uint64_t); @@ -1015,37 +995,28 @@ template std::string InputSectionBase::getLocation(uint64_t); template std::string InputSectionBase::getLocation(uint64_t); -template std::string InputSectionBase::getSrcMsg(const Symbol &, - uint64_t); -template std::string InputSectionBase::getSrcMsg(const Symbol &, - uint64_t); -template std::string InputSectionBase::getSrcMsg(const Symbol &, - uint64_t); -template std::string InputSectionBase::getSrcMsg(const Symbol &, - uint64_t); - template void InputSection::writeTo(uint8_t *); template void InputSection::writeTo(uint8_t *); template void InputSection::writeTo(uint8_t *); template void InputSection::writeTo(uint8_t *); -template MergeInputSection::MergeInputSection(ObjFile *, - const ELF32LE::Shdr *, StringRef); -template MergeInputSection::MergeInputSection(ObjFile *, - const ELF32BE::Shdr *, StringRef); -template MergeInputSection::MergeInputSection(ObjFile *, - const ELF64LE::Shdr *, StringRef); -template MergeInputSection::MergeInputSection(ObjFile *, - const ELF64BE::Shdr *, StringRef); +template MergeInputSection::MergeInputSection(ObjFile &, + const ELF32LE::Shdr &, StringRef); +template MergeInputSection::MergeInputSection(ObjFile &, + const ELF32BE::Shdr &, StringRef); +template MergeInputSection::MergeInputSection(ObjFile &, + const ELF64LE::Shdr &, StringRef); +template MergeInputSection::MergeInputSection(ObjFile &, + const ELF64BE::Shdr &, StringRef); -template EhInputSection::EhInputSection(ObjFile *, - const ELF32LE::Shdr *, StringRef); -template EhInputSection::EhInputSection(ObjFile *, - const ELF32BE::Shdr *, StringRef); -template EhInputSection::EhInputSection(ObjFile *, - const ELF64LE::Shdr *, StringRef); -template EhInputSection::EhInputSection(ObjFile *, - const ELF64BE::Shdr *, StringRef); +template EhInputSection::EhInputSection(ObjFile &, + const ELF32LE::Shdr &, StringRef); +template EhInputSection::EhInputSection(ObjFile &, + const ELF32BE::Shdr &, StringRef); +template EhInputSection::EhInputSection(ObjFile &, + const ELF64LE::Shdr &, StringRef); +template EhInputSection::EhInputSection(ObjFile &, + const ELF64BE::Shdr &, StringRef); template void EhInputSection::split(); template void EhInputSection::split(); Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.h ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.h Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.h Sun Dec 24 01:11:19 2017 (r327136) @@ -93,7 +93,7 @@ class SectionBase { (protected) class InputSectionBase : public SectionBase { public: template - InputSectionBase(ObjFile *File, const typename ELFT::Shdr *Header, + InputSectionBase(ObjFile &File, const typename ELFT::Shdr &Header, StringRef Name, Kind SectionKind); InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type, @@ -168,7 +168,6 @@ class InputSectionBase : public SectionBase { (public) // Returns a source location string. Used to construct an error message. template std::string getLocation(uint64_t Offset); - template std::string getSrcMsg(const Symbol &Sym, uint64_t Offset); std::string getObjMsg(uint64_t Offset); @@ -216,8 +215,11 @@ static_assert(sizeof(SectionPiece) == 16, "SectionPiec class MergeInputSection : public InputSectionBase { public: template - MergeInputSection(ObjFile *F, const typename ELFT::Shdr *Header, + MergeInputSection(ObjFile &F, const typename ELFT::Shdr &Header, StringRef Name); + MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize, + ArrayRef Data, StringRef Name); + static bool classof(const SectionBase *S) { return S->kind() == Merge; } void splitIntoPieces(); @@ -279,7 +281,7 @@ struct EhSectionPiece { class EhInputSection : public InputSectionBase { public: template - EhInputSection(ObjFile *F, const typename ELFT::Shdr *Header, + EhInputSection(ObjFile &F, const typename ELFT::Shdr &Header, StringRef Name); static bool classof(const SectionBase *S) { return S->kind() == EHFrame; } template void split(); @@ -298,10 +300,10 @@ class EhInputSection : public InputSectionBase { (publ // .eh_frame. It also includes the synthetic sections themselves. class InputSection : public InputSectionBase { public: - InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment, + InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment, ArrayRef Data, StringRef Name, Kind K = Regular); template - InputSection(ObjFile *F, const typename ELFT::Shdr *Header, + InputSection(ObjFile &F, const typename ELFT::Shdr &Header, StringRef Name); // Write this section to a mmap'ed file, assuming Buf is pointing to Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -68,7 +68,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT & B.Used = true; if (auto *SS = dyn_cast(&B)) if (!SS->isWeak()) - SS->getFile()->IsNeeded = true; + SS->getFile().IsNeeded = true; if (auto *D = dyn_cast(&B)) { auto *RelSec = dyn_cast_or_null(D->Section); @@ -246,7 +246,7 @@ template static void doGcSections() { // that point to .eh_frames. Otherwise, the garbage collector would drop // all of them. We also want to preserve personality routines and LSDA // referenced by .eh_frame sections, so we scan them for that here. - if (auto *EH = dyn_cast_or_null(Sec)) { + if (auto *EH = dyn_cast(Sec)) { EH->Live = true; scanEhFrameSection(*EH, Enqueue); } Modified: projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.cpp ============================================================================== --- projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.cpp Sun Dec 24 01:08:34 2017 (r327135) +++ projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.cpp Sun Dec 24 01:11:19 2017 (r327136) @@ -70,12 +70,11 @@ using namespace lld::elf; // >>> defined in /home/alice/src/foo.o // >>> referenced by bar.c:12 (/home/alice/src/bar.c:12) // >>> /home/alice/src/bar.o:(.text+0x1) -template static std::string getLocation(InputSectionBase &S, const Symbol &Sym, uint64_t Off) { std::string Msg = "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by "; - std::string Src = S.getSrcMsg(Sym, Off); + std::string Src = S.getSrcMsg(Sym, Off); if (!Src.empty()) Msg += Src + "\n>>> "; return Msg + S.getObjMsg(Off); @@ -365,7 +364,6 @@ static bool isRelExpr(RelExpr Expr) { // // If this function returns false, that means we need to emit a // dynamic relocation so that the relocation will be fixed at load-time. -template static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym, InputSectionBase &S, uint64_t RelOff) { // These expressions always compute a constant @@ -410,7 +408,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelTyp return true; error("relocation " + toString(Type) + " cannot refer to absolute symbol: " + - toString(Sym) + getLocation(S, Sym, RelOff)); + toString(Sym) + getLocation(S, Sym, RelOff)); return true; } @@ -443,8 +441,8 @@ template static bool isReadOnly(SharedSym typedef typename ELFT::Phdr Elf_Phdr; // Determine if the symbol is read-only by scanning the DSO's program headers. - const SharedFile *File = SS->getFile(); - for (const Elf_Phdr &Phdr : check(File->getObj().program_headers())) + const SharedFile &File = SS->getFile(); + for (const Elf_Phdr &Phdr : check(File.getObj().program_headers())) if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) && !(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr && SS->Value < Phdr.p_vaddr + Phdr.p_memsz) @@ -461,14 +459,14 @@ template static std::vector getSymbolsAt(SharedSymbol *SS) { typedef typename ELFT::Sym Elf_Sym; - SharedFile *File = SS->getFile(); + SharedFile &File = SS->getFile(); std::vector Ret; - for (const Elf_Sym &S : File->getGlobalELFSyms()) { + for (const Elf_Sym &S : File.getGlobalELFSyms()) { if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS || S.st_value != SS->Value) continue; - StringRef Name = check(S.getName(File->getStringTable())); + StringRef Name = check(S.getName(File.getStringTable())); Symbol *Sym = Symtab->find(Name); if (auto *Alias = dyn_cast_or_null(Sym)) Ret.push_back(Alias); @@ -554,22 +552,57 @@ static void errorOrWarn(const Twine &Msg) { warn(Msg); } +// Returns PLT relocation expression. +// +// This handles a non PIC program call to function in a shared library. In +// an ideal world, we could just report an error saying the relocation can +// overflow at runtime. In the real world with glibc, crt1.o has a +// R_X86_64_PC32 pointing to libc.so. +// +// The general idea on how to handle such cases is to create a PLT entry and +// use that as the function value. +// +// For the static linking part, we just return a plt expr and everything +// else will use the the PLT entry as the address. +// +// The remaining problem is making sure pointer equality still works. We +// need the help of the dynamic linker for that. We let it know that we have +// a direct reference to a so symbol by creating an undefined symbol with a +// non zero st_value. Seeing that, the dynamic linker resolves the symbol to +// the value of the symbol we created. This is true even for got entries, so +// pointer equality is maintained. To avoid an infinite loop, the only entry +// that points to the real function is a dedicated got entry used by the +// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, +// R_386_JMP_SLOT, etc). +static RelExpr getPltExpr(Symbol &Sym, RelExpr Expr, bool &IsConstant) { + Sym.NeedsPltAddr = true; + Sym.IsPreemptible = false; + IsConstant = true; + return toPlt(Expr); +} + template static RelExpr adjustExpr(Symbol &Sym, RelExpr Expr, RelType Type, - InputSectionBase &S, uint64_t RelOff) { + InputSectionBase &S, uint64_t RelOff, + bool &IsConstant) { // We can create any dynamic relocation if a section is simply writable. if (S.Flags & SHF_WRITE) return Expr; // Or, if we are allowed to create dynamic relocations against - // read-only sections (i.e. unless "-z notext" is given), + // read-only sections (i.e. when "-z notext" is given), // we can create a dynamic relocation as we want, too. - if (!Config->ZText) + if (!Config->ZText) { + // We use PLT for relocations that may overflow in runtime, *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***