Date: Sat, 10 Jun 2017 13:44:49 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r319788 - in vendor/lld/dist: COFF ELF include/lld/Core include/lld/ReaderWriter lib/Core lib/Driver lib/ReaderWriter lib/ReaderWriter/MachO lib/ReaderWriter/YAML test test/COFF test/EL... Message-ID: <201706101344.v5ADinJW095051@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Sat Jun 10 13:44:49 2017 New Revision: 319788 URL: https://svnweb.freebsd.org/changeset/base/319788 Log: Vendor import of lld trunk r305145: https://llvm.org/svn/llvm-project/lld/trunk@305145 Added: vendor/lld/dist/test/ELF/Inputs/relocatable-comdat-multiple.s (contents, props changed) vendor/lld/dist/test/ELF/arm-thumb-thunk-symbols.s (contents, props changed) vendor/lld/dist/test/ELF/dso_handle.s (contents, props changed) vendor/lld/dist/test/ELF/i386-reloc-large-addend.s (contents, props changed) vendor/lld/dist/test/ELF/i386-reloc-range.s (contents, props changed) vendor/lld/dist/test/ELF/icf-comdat.s (contents, props changed) vendor/lld/dist/test/ELF/linkerscript/emit-relocs-multiple.s (contents, props changed) vendor/lld/dist/test/ELF/linkerscript/noload.s (contents, props changed) vendor/lld/dist/test/ELF/lto/Inputs/defsym-bar.ll vendor/lld/dist/test/ELF/lto/Inputs/wrap-bar.ll vendor/lld/dist/test/ELF/lto/defsym.ll vendor/lld/dist/test/ELF/lto/wrap-1.ll vendor/lld/dist/test/ELF/lto/wrap-2.ll vendor/lld/dist/test/ELF/mips-npic-call-pic-script.s (contents, props changed) vendor/lld/dist/test/ELF/relocatable-comdat-multiple.s (contents, props changed) vendor/lld/dist/test/ELF/relocatable-compressed-input.s (contents, props changed) vendor/lld/dist/test/ELF/relocatable-empty-archive.s (contents, props changed) Modified: vendor/lld/dist/COFF/CMakeLists.txt vendor/lld/dist/COFF/Chunks.cpp vendor/lld/dist/COFF/Driver.cpp vendor/lld/dist/COFF/InputFiles.cpp vendor/lld/dist/ELF/CMakeLists.txt vendor/lld/dist/ELF/Config.h vendor/lld/dist/ELF/Driver.cpp vendor/lld/dist/ELF/EhFrame.cpp vendor/lld/dist/ELF/GdbIndex.h vendor/lld/dist/ELF/ICF.cpp vendor/lld/dist/ELF/InputFiles.cpp vendor/lld/dist/ELF/InputSection.cpp vendor/lld/dist/ELF/InputSection.h vendor/lld/dist/ELF/LTO.cpp vendor/lld/dist/ELF/LinkerScript.cpp vendor/lld/dist/ELF/LinkerScript.h vendor/lld/dist/ELF/Mips.cpp vendor/lld/dist/ELF/OutputSections.cpp vendor/lld/dist/ELF/OutputSections.h vendor/lld/dist/ELF/Relocations.cpp vendor/lld/dist/ELF/Relocations.h vendor/lld/dist/ELF/ScriptParser.cpp vendor/lld/dist/ELF/SymbolTable.cpp vendor/lld/dist/ELF/SymbolTable.h vendor/lld/dist/ELF/Symbols.cpp vendor/lld/dist/ELF/SyntheticSections.cpp vendor/lld/dist/ELF/SyntheticSections.h vendor/lld/dist/ELF/Target.cpp vendor/lld/dist/ELF/Thunks.cpp vendor/lld/dist/ELF/Writer.cpp vendor/lld/dist/include/lld/Core/Reader.h vendor/lld/dist/include/lld/ReaderWriter/MachOLinkingContext.h vendor/lld/dist/lib/Core/CMakeLists.txt vendor/lld/dist/lib/Core/Reader.cpp vendor/lld/dist/lib/Core/SymbolTable.cpp vendor/lld/dist/lib/Driver/DarwinLdDriver.cpp vendor/lld/dist/lib/ReaderWriter/FileArchive.cpp vendor/lld/dist/lib/ReaderWriter/MachO/ExecutableAtoms.h vendor/lld/dist/lib/ReaderWriter/MachO/MachOLinkingContext.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFile.h vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp vendor/lld/dist/lib/ReaderWriter/MachO/WriterMachO.cpp vendor/lld/dist/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp vendor/lld/dist/test/CMakeLists.txt vendor/lld/dist/test/COFF/pdb-none.test vendor/lld/dist/test/COFF/pdb.test vendor/lld/dist/test/ELF/aarch64-undefined-weak.s vendor/lld/dist/test/ELF/amdgpu-globals.s vendor/lld/dist/test/ELF/amdgpu-kernels.s vendor/lld/dist/test/ELF/arm-icf-exidx.s vendor/lld/dist/test/ELF/arm-thumb-no-undefined-thunk.s vendor/lld/dist/test/ELF/arm-thumb-undefined-weak.s vendor/lld/dist/test/ELF/arm-undefined-weak.s vendor/lld/dist/test/ELF/ehdr_start.s vendor/lld/dist/test/ELF/emit-relocs-merge.s vendor/lld/dist/test/ELF/gdb-index-empty.s vendor/lld/dist/test/ELF/linkerscript/early-assign-symbol.s vendor/lld/dist/test/ELF/linkerscript/expr-invalid-sec.s vendor/lld/dist/unittests/DriverTests/DarwinLdDriverTest.cpp vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp vendor/lld/dist/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp vendor/lld/dist/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp vendor/lld/dist/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp Modified: vendor/lld/dist/COFF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/COFF/CMakeLists.txt Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/COFF/CMakeLists.txt Sat Jun 10 13:44:49 2017 (r319788) @@ -25,6 +25,7 @@ add_lld_library(lldCOFF LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + BinaryFormat BitReader Core DebugInfoCodeView Modified: vendor/lld/dist/COFF/Chunks.cpp ============================================================================== --- vendor/lld/dist/COFF/Chunks.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/COFF/Chunks.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -12,8 +12,8 @@ #include "InputFiles.h" #include "Symbols.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/COFF.h" -#include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/raw_ostream.h" Modified: vendor/lld/dist/COFF/Driver.cpp ============================================================================== --- vendor/lld/dist/COFF/Driver.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/COFF/Driver.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -18,6 +18,7 @@ #include "lld/Driver/Driver.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/BinaryFormat/Magic.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/COFFModuleDefinition.h" @@ -40,8 +41,6 @@ using namespace llvm; using namespace llvm::object; using namespace llvm::COFF; using llvm::sys::Process; -using llvm::sys::fs::file_magic; -using llvm::sys::fs::identify_magic; namespace lld { namespace coff { @@ -457,17 +456,11 @@ static void createImportLibrary() { static void parseModuleDefs(StringRef Path) { std::unique_ptr<MemoryBuffer> MB = check( MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path); - MemoryBufferRef MBRef = MB->getMemBufferRef(); + COFFModuleDefinition M = + check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine)); - Expected<COFFModuleDefinition> Def = - parseCOFFModuleDefinition(MBRef, Config->Machine); - if (!Def) - fatal(errorToErrorCode(Def.takeError()).message()); - - COFFModuleDefinition &M = *Def; if (Config->OutputFile.empty()) Config->OutputFile = Saver.save(M.OutputFile); - if (M.ImageBase) Config->ImageBase = M.ImageBase; if (M.StackReserve) Modified: vendor/lld/dist/COFF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/COFF/InputFiles.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/COFF/InputFiles.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -19,9 +19,9 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" -#include "llvm/Support/COFF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" Modified: vendor/lld/dist/ELF/CMakeLists.txt ============================================================================== --- vendor/lld/dist/ELF/CMakeLists.txt Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/CMakeLists.txt Sat Jun 10 13:44:49 2017 (r319788) @@ -36,6 +36,7 @@ add_lld_library(lldELF LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} Analysis + BinaryFormat BitReader BitWriter Codegen Modified: vendor/lld/dist/ELF/Config.h ============================================================================== --- vendor/lld/dist/ELF/Config.h Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/Config.h Sat Jun 10 13:44:49 2017 (r319788) @@ -13,9 +13,9 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" -#include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include <vector> @@ -67,6 +67,12 @@ struct VersionDefinition { size_t NameOff = 0; // Offset in the string table }; +// Structure for mapping renamed symbols +struct RenamedSymbol { + Symbol *Target; + uint8_t OrigBinding; +}; + // This struct contains the global configuration for the linker. // Most fields are direct mapping from the command line options // and such fields have the same name as the corresponding options. @@ -98,6 +104,7 @@ struct Configuration { std::vector<SymbolVersion> VersionScriptGlobals; std::vector<SymbolVersion> VersionScriptLocals; std::vector<uint8_t> BuildIdVector; + llvm::MapVector<Symbol *, RenamedSymbol> RenamedSymbols; bool AllowMultipleDefinition; bool AsNeeded = false; bool Bsymbolic; Modified: vendor/lld/dist/ELF/Driver.cpp ============================================================================== --- vendor/lld/dist/ELF/Driver.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/Driver.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -185,7 +185,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLO // is attempting LTO and using a default ar command that doesn't // understand the LLVM bitcode file. It is a pretty common error, so // we'll handle it as if it had a symbol table. - if (!File->hasSymbolTable()) { + if (!File->isEmpty() && !File->hasSymbolTable()) { for (const auto &P : getArchiveMembers(MBRef)) Files.push_back(make<LazyObjectFile>(P.first, Path, P.second)); return; @@ -970,6 +970,14 @@ template <class ELFT> void LinkerDriver::link(opt::Inp Symtab.scanShlibUndefined(); Symtab.scanVersionScript(); + // Create wrapped symbols for -wrap option. + for (auto *Arg : Args.filtered(OPT_wrap)) + Symtab.addSymbolWrap(Arg->getValue()); + + // Create alias symbols for -defsym option. + for (std::pair<StringRef, StringRef> &Def : getDefsym(Args)) + Symtab.addSymbolAlias(Def.first, Def.second); + Symtab.addCombinedLTOObject(); if (ErrorCount) return; @@ -979,12 +987,8 @@ template <class ELFT> void LinkerDriver::link(opt::Inp for (StringRef Sym : Script->Opt.ReferencedSymbols) Symtab.addUndefined(Sym); - for (auto *Arg : Args.filtered(OPT_wrap)) - Symtab.wrap(Arg->getValue()); - - // Handle --defsym=sym=alias option. - for (std::pair<StringRef, StringRef> &Def : getDefsym(Args)) - Symtab.alias(Def.first, Def.second); + // Apply symbol renames for -wrap and -defsym + Symtab.applySymbolRenames(); // Now that we have a complete list of input files. // Beyond this point, no new files are added. Modified: vendor/lld/dist/ELF/EhFrame.cpp ============================================================================== --- vendor/lld/dist/ELF/EhFrame.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/EhFrame.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -22,8 +22,8 @@ #include "Relocations.h" #include "Strings.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Object/ELF.h" -#include "llvm/Support/Dwarf.h" #include "llvm/Support/Endian.h" using namespace llvm; Modified: vendor/lld/dist/ELF/GdbIndex.h ============================================================================== --- vendor/lld/dist/ELF/GdbIndex.h Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/GdbIndex.h Sat Jun 10 13:44:49 2017 (r319788) @@ -24,7 +24,30 @@ struct AddressEntry { InputSection *Section; uint64_t LowAddress; uint64_t HighAddress; - size_t CuIndex; + uint32_t CuIndex; +}; + +// Struct represents single entry of compilation units list area of gdb index. +// It consist of CU offset in .debug_info section and it's size. +struct CompilationUnitEntry { + uint64_t CuOffset; + uint64_t CuLength; +}; + +// Represents data about symbol and type names which are used +// to build symbol table and constant pool area of gdb index. +struct NameTypeEntry { + StringRef Name; + uint8_t Type; +}; + +// We fill one GdbIndexDataChunk for each object where scan of +// debug information performed. That information futher used +// for filling gdb index section areas. +struct GdbIndexChunk { + std::vector<AddressEntry> AddressArea; + std::vector<CompilationUnitEntry> CompilationUnits; + std::vector<NameTypeEntry> NamesAndTypes; }; // Element of GdbHashTab hash table. Modified: vendor/lld/dist/ELF/ICF.cpp ============================================================================== --- vendor/lld/dist/ELF/ICF.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/ICF.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -78,8 +78,8 @@ #include "SymbolTable.h" #include "Threads.h" #include "llvm/ADT/Hashing.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" -#include "llvm/Support/ELF.h" #include <algorithm> #include <atomic> Modified: vendor/lld/dist/ELF/InputFiles.cpp ============================================================================== --- vendor/lld/dist/ELF/InputFiles.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/InputFiles.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -306,21 +306,23 @@ void elf::ObjectFile<ELFT>::initializeSections( switch (Sec.sh_type) { case SHT_GROUP: { - // We discard comdat sections usually. When -r we should not do that. We - // still do deduplication in this case to simplify implementation, because - // otherwise merging group sections together would requre additional - // regeneration of its contents. - bool New = ComdatGroups - .insert(CachedHashStringRef( - getShtGroupSignature(ObjSections, Sec))) - .second; - if (New && Config->Relocatable) - this->Sections[I] = createInputSection(Sec, SectionStringTable); - else - this->Sections[I] = &InputSection::Discarded; - if (New) + // De-duplicate section groups by their signatures. + StringRef Signature = getShtGroupSignature(ObjSections, Sec); + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; + this->Sections[I] = &InputSection::Discarded; + + // If it is a new section group, we want to keep group members. + // Group leader sections, which contain indices of group members, are + // discarded because they are useless beyond this point. The only + // exception is the -r option because in order to produce re-linkable + // object files, we want to pass through basically everything. + if (IsNew) { + if (Config->Relocatable) + this->Sections[I] = createInputSection(Sec, SectionStringTable); continue; + } + // Otherwise, discard group members. for (uint32_t SecIndex : getShtGroupEntries(Sec)) { if (SecIndex >= Size) fatal(toString(this) + Modified: vendor/lld/dist/ELF/InputSection.cpp ============================================================================== --- vendor/lld/dist/ELF/InputSection.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/InputSection.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -20,6 +20,7 @@ #include "Target.h" #include "Thunks.h" #include "llvm/Object/Decompressor.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Path.h" @@ -72,6 +73,16 @@ InputSectionBase::InputSectionBase(InputFile *File, ui this->Alignment = V; } +// Drop SHF_GROUP bit unless we are producing a re-linkable object file. +// SHF_GROUP is a marker that a section belongs to some comdat group. +// That flag doesn't make sense in an executable. +static uint64_t getFlags(uint64_t Flags) { + Flags &= ~(uint64_t)SHF_INFO_LINK; + if (!Config->Relocatable) + Flags &= ~(uint64_t)SHF_GROUP; + return Flags; +} + // GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of // March 2017) fail to infer section types for sections starting with // ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of @@ -94,7 +105,7 @@ template <class ELFT> InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File, const typename ELFT::Shdr *Hdr, StringRef Name, Kind SectionKind) - : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK, + : 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) { @@ -308,23 +319,21 @@ OutputSection *InputSection::getParent() const { return cast_or_null<OutputSection>(Parent); } -void InputSection::copyShtGroup(uint8_t *Buf) { - assert(this->Type == SHT_GROUP); +// Copy SHT_GROUP section contents. Used only for the -r option. +template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) { + // ELFT::Word is the 32-bit integral type in the target endianness. + typedef typename ELFT::Word u32; + ArrayRef<u32> From = getDataAs<u32>(); + auto *To = reinterpret_cast<u32 *>(Buf); - ArrayRef<uint32_t> From = getDataAs<uint32_t>(); - uint32_t *To = reinterpret_cast<uint32_t *>(Buf); - - // First entry is a flag word, we leave it unchanged. + // The first entry is not a section number but a flag. *To++ = From[0]; - // Here we adjust indices of sections that belong to group as it - // might change during linking. + // Adjust section numbers because section numbers in an input object + // files are different in the output. ArrayRef<InputSectionBase *> Sections = this->File->getSections(); - for (uint32_t Val : From.slice(1)) { - uint32_t Index = read32(&Val, Config->Endianness); - write32(To++, Sections[Index]->getOutputSection()->SectionIndex, - Config->Endianness); - } + for (uint32_t Idx : From.slice(1)) + *To++ = Sections[Idx]->getOutputSection()->SectionIndex; } InputSectionBase *InputSection::getRelocatedSection() { @@ -682,7 +691,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uin // Patch a nop (0x60000000) to a ld. if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000) write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1) - // fallthrough + LLVM_FALLTHROUGH; default: Target->relocateOne(BufLoc, Type, TargetVA); break; @@ -712,10 +721,9 @@ template <class ELFT> void InputSection::writeTo(uint8 return; } - // If -r is given, linker should keep SHT_GROUP sections. We should fixup - // them, see copyShtGroup(). + // If -r is given, we may have a SHT_GROUP section. if (this->Type == SHT_GROUP) { - copyShtGroup(Buf + OutSecOff); + copyShtGroup<ELFT>(Buf + OutSecOff); return; } Modified: vendor/lld/dist/ELF/InputSection.h ============================================================================== --- vendor/lld/dist/ELF/InputSection.h Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/InputSection.h Sat Jun 10 13:44:49 2017 (r319788) @@ -325,7 +325,7 @@ class InputSection : public InputSectionBase { (privat template <class ELFT, class RelTy> void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); - void copyShtGroup(uint8_t *Buf); + template <class ELFT> void copyShtGroup(uint8_t *Buf); }; // The list of all input sections. Modified: vendor/lld/dist/ELF/LTO.cpp ============================================================================== --- vendor/lld/dist/ELF/LTO.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/LTO.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -17,13 +17,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/LTO/Caching.h" #include "llvm/LTO/Config.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/SymbolicFile.h" #include "llvm/Support/CodeGen.h" -#include "llvm/Support/ELF.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -136,6 +136,7 @@ void BitcodeCompiler::add(BitcodeFile &F) { Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym()); if (R.Prevailing) undefine(Sym); + R.LinkerRedefined = Config->RenamedSymbols.count(Sym); } checkError(LTOObj->add(std::move(F.Obj), Resols)); } Modified: vendor/lld/dist/ELF/LinkerScript.cpp ============================================================================== --- vendor/lld/dist/ELF/LinkerScript.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/LinkerScript.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -25,9 +25,9 @@ #include "Writer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" -#include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" @@ -54,7 +54,7 @@ uint64_t ExprValue::getValue() const { if (Sec) { if (OutputSection *OS = Sec->getOutputSection()) return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment); - error("unable to evaluate expression: input section " + Sec->Name + + error(Loc + ": unable to evaluate expression: input section " + Sec->Name + " has no output section assigned"); } return alignTo(Val, Alignment); @@ -431,6 +431,8 @@ void LinkerScript::processCommands(OutputSectionFactor if (OutputSection *Sec = Cmd->Sec) { assert(Sec->SectionIndex == INT_MAX); Sec->SectionIndex = I; + if (Cmd->Noload) + Sec->Type = SHT_NOBITS; SecToCommand[Sec] = Cmd; } } @@ -442,7 +444,7 @@ void LinkerScript::fabricateDefaultCommands() { std::vector<BaseCommand *> Commands; // Define start address - uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize(); + uint64_t StartAddr = -1; // The Sections with -T<section> have been sorted in order of ascending // address. We must lower StartAddr if the lowest -T<section address> as @@ -450,8 +452,12 @@ void LinkerScript::fabricateDefaultCommands() { for (auto& KV : Config->SectionStartMap) StartAddr = std::min(StartAddr, KV.second); - Commands.push_back( - make<SymbolAssignment>(".", [=] { return StartAddr; }, "")); + Commands.push_back(make<SymbolAssignment>( + ".", + [=] { + return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize()); + }, + "")); // For each OutputSection that needs a VA fabricate an OutputSectionCommand // with an InputSectionDescription describing the InputSections @@ -870,51 +876,6 @@ void LinkerScript::processNonSectionCommands() { } } -// Do a last effort at synchronizing the linker script "AST" and the section -// list. This is needed to account for last minute changes, like adding a -// .ARM.exidx terminator and sorting SHF_LINK_ORDER sections. -// -// FIXME: We should instead create the "AST" earlier and the above changes would -// be done directly in the "AST". -// -// This can only handle new sections being added and sections being reordered. -void LinkerScript::synchronize() { - for (BaseCommand *Base : Opt.Commands) { - auto *Cmd = dyn_cast<OutputSectionCommand>(Base); - if (!Cmd) - continue; - ArrayRef<InputSection *> Sections = Cmd->Sec->Sections; - std::vector<InputSection **> ScriptSections; - DenseSet<InputSection *> ScriptSectionsSet; - for (BaseCommand *Base : Cmd->Commands) { - auto *ISD = dyn_cast<InputSectionDescription>(Base); - if (!ISD) - continue; - for (InputSection *&IS : ISD->Sections) { - if (IS->Live) { - ScriptSections.push_back(&IS); - ScriptSectionsSet.insert(IS); - } - } - } - std::vector<InputSection *> Missing; - for (InputSection *IS : Sections) - if (!ScriptSectionsSet.count(IS)) - Missing.push_back(IS); - if (!Missing.empty()) { - auto ISD = make<InputSectionDescription>(""); - ISD->Sections = Missing; - Cmd->Commands.push_back(ISD); - for (InputSection *&IS : ISD->Sections) - if (IS->Live) - ScriptSections.push_back(&IS); - } - assert(ScriptSections.size() == Sections.size()); - for (int I = 0, N = Sections.size(); I < N; ++I) - *ScriptSections[I] = Sections[I]; - } -} - static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs, ArrayRef<OutputSectionCommand *> OutputSectionCommands, @@ -1071,6 +1032,81 @@ static void writeInt(uint8_t *Buf, uint64_t Data, uint llvm_unreachable("unsupported Size argument"); } +static bool compareByFilePosition(InputSection *A, InputSection *B) { + // Synthetic doesn't have link order dependecy, stable_sort will keep it last + if (A->kind() == InputSectionBase::Synthetic || + B->kind() == InputSectionBase::Synthetic) + return false; + InputSection *LA = A->getLinkOrderDep(); + InputSection *LB = B->getLinkOrderDep(); + OutputSection *AOut = LA->getParent(); + OutputSection *BOut = LB->getParent(); + if (AOut != BOut) + return AOut->SectionIndex < BOut->SectionIndex; + return LA->OutSecOff < LB->OutSecOff; +} + +template <class ELFT> +static void finalizeShtGroup(OutputSection *OS, + ArrayRef<InputSection *> Sections) { + // sh_link field for SHT_GROUP sections should contain the section index of + // the symbol table. + OS->Link = InX::SymTab->getParent()->SectionIndex; + + // sh_info then contain index of an entry in symbol table section which + // provides signature of the section group. + elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>(); + assert(Config->Relocatable && Sections.size() == 1); + ArrayRef<SymbolBody *> Symbols = Obj->getSymbols(); + OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]); +} + +template <class ELFT> void OutputSectionCommand::finalize() { + // Link order may be distributed across several InputSectionDescriptions + // but sort must consider them all at once. + std::vector<InputSection **> ScriptSections; + std::vector<InputSection *> Sections; + for (BaseCommand *Base : Commands) + if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) + for (InputSection *&IS : ISD->Sections) { + ScriptSections.push_back(&IS); + Sections.push_back(IS); + } + + if ((Sec->Flags & SHF_LINK_ORDER)) { + std::sort(Sections.begin(), Sections.end(), compareByFilePosition); + for (int I = 0, N = Sections.size(); I < N; ++I) + *ScriptSections[I] = Sections[I]; + + // We must preserve the link order dependency of sections with the + // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We + // need to translate the InputSection sh_link to the OutputSection sh_link, + // all InputSections in the OutputSection have the same dependency. + if (auto *D = Sections.front()->getLinkOrderDep()) + Sec->Link = D->getParent()->SectionIndex; + } + + uint32_t Type = Sec->Type; + if (Type == SHT_GROUP) { + finalizeShtGroup<ELFT>(Sec, Sections); + return; + } + + if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL)) + return; + + InputSection *First = Sections[0]; + if (isa<SyntheticSection>(First)) + return; + + Sec->Link = InX::SymTab->getParent()->SectionIndex; + // sh_info for SHT_REL[A] sections should contain the section header index of + // the section to which the relocation applies. + InputSectionBase *S = First->getRelocatedSection(); + Sec->Info = S->getOutputSection()->SectionIndex; + Sec->Flags |= SHF_INFO_LINK; +} + // Compress section contents if this section contains debug info. template <class ELFT> void OutputSectionCommand::maybeCompress() { typedef typename ELFT::Chdr Elf_Chdr; @@ -1099,6 +1135,9 @@ template <class ELFT> void OutputSectionCommand::maybe } template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) { + if (Sec->Type == SHT_NOBITS) + return; + Sec->Loc = Buf; // We may have already rendered compressed content when using @@ -1110,9 +1149,6 @@ template <class ELFT> void OutputSectionCommand::write return; } - if (Sec->Type == SHT_NOBITS) - return; - // Write leading padding. std::vector<InputSection *> Sections; for (BaseCommand *Cmd : Commands) @@ -1156,12 +1192,12 @@ bool LinkerScript::hasLMA(OutputSection *Sec) { ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { if (S == ".") - return {CurOutSec, Dot - CurOutSec->Addr}; + return {CurOutSec, Dot - CurOutSec->Addr, Loc}; if (SymbolBody *B = findSymbol(S)) { if (auto *D = dyn_cast<DefinedRegular>(B)) - return {D->Section, D->Value}; + return {D->Section, D->Value, Loc}; if (auto *C = dyn_cast<DefinedCommon>(B)) - return {InX::Common, C->Offset}; + return {InX::Common, C->Offset, Loc}; } error(Loc + ": symbol not found: " + S); return 0; @@ -1201,3 +1237,8 @@ template void OutputSectionCommand::maybeCompress<ELF3 template void OutputSectionCommand::maybeCompress<ELF32BE>(); template void OutputSectionCommand::maybeCompress<ELF64LE>(); template void OutputSectionCommand::maybeCompress<ELF64BE>(); + +template void OutputSectionCommand::finalize<ELF32LE>(); +template void OutputSectionCommand::finalize<ELF32BE>(); +template void OutputSectionCommand::finalize<ELF64LE>(); +template void OutputSectionCommand::finalize<ELF64BE>(); Modified: vendor/lld/dist/ELF/LinkerScript.h ============================================================================== --- vendor/lld/dist/ELF/LinkerScript.h Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/LinkerScript.h Sat Jun 10 13:44:49 2017 (r319788) @@ -42,15 +42,14 @@ struct ExprValue { uint64_t Val; bool ForceAbsolute; uint64_t Alignment = 1; + std::string Loc; ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val, - uint64_t Alignment) - : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) { - } - ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val) - : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {} - ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {} - ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {} + const Twine &Loc) + : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {} + ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc) + : ExprValue(Sec, false, Val, Loc) {} + ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {} bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; } uint64_t getValue() const; uint64_t getSecAddr() const; @@ -135,7 +134,9 @@ struct OutputSectionCommand : BaseCommand { ConstraintKind Constraint = ConstraintKind::NoConstraint; std::string Location; std::string MemoryRegionName; + bool Noload = false; + template <class ELFT> void finalize(); template <class ELFT> void writeTo(uint8_t *Buf); template <class ELFT> void maybeCompress(); uint32_t getFiller(); @@ -281,7 +282,6 @@ class LinkerScript final { (public) void assignOffsets(OutputSectionCommand *Cmd); void placeOrphanSections(); void processNonSectionCommands(); - void synchronize(); void assignAddresses(std::vector<PhdrEntry> &Phdrs, ArrayRef<OutputSectionCommand *> OutputSectionCommands); Modified: vendor/lld/dist/ELF/Mips.cpp ============================================================================== --- vendor/lld/dist/ELF/Mips.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/Mips.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -16,8 +16,8 @@ #include "SymbolTable.h" #include "Writer.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELF.h" -#include "llvm/Support/ELF.h" #include "llvm/Support/MipsABIFlags.h" using namespace llvm; Modified: vendor/lld/dist/ELF/OutputSections.cpp ============================================================================== --- vendor/lld/dist/ELF/OutputSections.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/OutputSections.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -16,7 +16,7 @@ #include "SyntheticSections.h" #include "Target.h" #include "Threads.h" -#include "llvm/Support/Dwarf.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SHA1.h" @@ -70,67 +70,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t /*Link*/ 0), SectionIndex(INT_MAX) {} -static bool compareByFilePosition(InputSection *A, InputSection *B) { - // Synthetic doesn't have link order dependecy, stable_sort will keep it last - if (A->kind() == InputSectionBase::Synthetic || - B->kind() == InputSectionBase::Synthetic) - return false; - InputSection *LA = A->getLinkOrderDep(); - InputSection *LB = B->getLinkOrderDep(); - OutputSection *AOut = LA->getParent(); - OutputSection *BOut = LB->getParent(); - if (AOut != BOut) - return AOut->SectionIndex < BOut->SectionIndex; - return LA->OutSecOff < LB->OutSecOff; -} - -template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) { - // sh_link field for SHT_GROUP sections should contain the section index of - // the symbol table. - Sec->Link = InX::SymTab->getParent()->SectionIndex; - - // sh_info then contain index of an entry in symbol table section which - // provides signature of the section group. - elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>(); - assert(Config->Relocatable && Sec->Sections.size() == 1); - ArrayRef<SymbolBody *> Symbols = Obj->getSymbols(); - Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]); -} - -template <class ELFT> void OutputSection::finalize() { - if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) { - std::sort(Sections.begin(), Sections.end(), compareByFilePosition); - assignOffsets(); - - // We must preserve the link order dependency of sections with the - // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We - // need to translate the InputSection sh_link to the OutputSection sh_link, - // all InputSections in the OutputSection have the same dependency. - if (auto *D = this->Sections.front()->getLinkOrderDep()) - this->Link = D->getParent()->SectionIndex; - } - - uint32_t Type = this->Type; - if (Type == SHT_GROUP) { - finalizeShtGroup<ELFT>(this); - return; - } - - if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL)) - return; - - InputSection *First = Sections[0]; - if (isa<SyntheticSection>(First)) - return; - - this->Link = InX::SymTab->getParent()->SectionIndex; - // sh_info for SHT_REL[A] sections should contain the section header index of - // the section to which the relocation applies. - InputSectionBase *S = First->getRelocatedSection(); - Info = S->getOutputSection()->SectionIndex; - Flags |= SHF_INFO_LINK; -} - static uint64_t updateOffset(uint64_t Off, InputSection *S) { Off = alignTo(Off, S->Alignment); S->OutSecOff = Off; @@ -162,9 +101,12 @@ void OutputSection::addSection(InputSection *S) { // This function is called after we sort input sections // and scan relocations to setup sections' offsets. void OutputSection::assignOffsets() { + OutputSectionCommand *Cmd = Script->getCmd(this); uint64_t Off = 0; - for (InputSection *S : Sections) - Off = updateOffset(Off, S); + for (BaseCommand *Base : Cmd->Commands) + if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) + for (InputSection *S : ISD->Sections) + Off = updateOffset(Off, S); this->Size = Off; } @@ -333,6 +275,31 @@ void elf::reportDiscarded(InputSectionBase *IS) { void OutputSectionFactory::addInputSec(InputSectionBase *IS, StringRef OutsecName) { + // Sections with the SHT_GROUP attribute reach here only when the - r option + // is given. Such sections define "section groups", and InputFiles.cpp has + // dedup'ed section groups by their signatures. For the -r, we want to pass + // through all SHT_GROUP sections without merging them because merging them + // creates broken section contents. + if (IS->Type == SHT_GROUP) { + OutputSection *Out = nullptr; + addInputSec(IS, OutsecName, Out); + return; + } + + // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have + // relocation sections .rela.foo and .rela.bar for example. Most tools do + // not allow multiple REL[A] sections for output section. Hence we + // should combine these relocation sections into single output. + // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any + // other REL[A] sections created by linker itself. + if (!isa<SyntheticSection>(IS) && + (IS->Type == SHT_REL || IS->Type == SHT_RELA)) { + auto *Sec = cast<InputSection>(IS); + OutputSection *Out = Sec->getRelocatedSection()->getOutputSection(); + addInputSec(IS, OutsecName, Out->RelocationSection); + return; + } + SectionKey Key = createKey(IS, OutsecName); OutputSection *&Sec = Map[Key]; return addInputSec(IS, OutsecName, Sec); @@ -346,10 +313,6 @@ void OutputSectionFactory::addInputSec(InputSectionBas return; } - uint64_t Flags = IS->Flags; - if (!Config->Relocatable) - Flags &= ~(uint64_t)SHF_GROUP; - if (Sec) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("incompatible section flags for " + Sec->Name + @@ -366,9 +329,9 @@ void OutputSectionFactory::addInputSec(InputSectionBas "\n>>> output section " + Sec->Name + ": " + getELFSectionTypeName(Config->EMachine, Sec->Type)); } - Sec->Flags |= Flags; + Sec->Flags |= IS->Flags; } else { - Sec = make<OutputSection>(OutsecName, IS->Type, Flags); + Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags); OutputSections.push_back(Sec); } @@ -405,8 +368,3 @@ template void OutputSection::writeHeaderTo<ELF32LE>(EL template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr); template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr); template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr); - -template void OutputSection::finalize<ELF32LE>(); -template void OutputSection::finalize<ELF32BE>(); -template void OutputSection::finalize<ELF64LE>(); -template void OutputSection::finalize<ELF64BE>(); Modified: vendor/lld/dist/ELF/OutputSections.h ============================================================================== --- vendor/lld/dist/ELF/OutputSections.h Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/OutputSections.h Sat Jun 10 13:44:49 2017 (r319788) @@ -67,6 +67,11 @@ class OutputSection final : public SectionBase { (publ // formula: Off = Off_first + VA - VA_first. OutputSection *FirstInPtLoad = nullptr; + // Pointer to a relocation section for this section. Usually nullptr because + // we consume relocations, but if --emit-relocs is specified (which is rare), + // it may have a non-null value. + OutputSection *RelocationSection = nullptr; + // The following fields correspond to Elf_Shdr members. uint64_t Size = 0; uint64_t Offset = 0; @@ -78,7 +83,6 @@ class OutputSection final : public SectionBase { (publ void sort(std::function<int(InputSectionBase *S)> Order); void sortInitFini(); void sortCtorsDtors(); - template <class ELFT> void finalize(); void assignOffsets(); std::vector<InputSection *> Sections; Modified: vendor/lld/dist/ELF/Relocations.cpp ============================================================================== --- vendor/lld/dist/ELF/Relocations.cpp Sat Jun 10 13:44:46 2017 (r319787) +++ vendor/lld/dist/ELF/Relocations.cpp Sat Jun 10 13:44:49 2017 (r319788) @@ -43,6 +43,7 @@ #include "Relocations.h" #include "Config.h" +#include "LinkerScript.h" #include "Memory.h" #include "OutputSections.h" #include "Strings.h" @@ -967,48 +968,51 @@ template <class ELFT> void elf::scanRelocations(InputS // in the Sections vector, and recalculate the InputSection output section // offsets. // This may invalidate any output section offsets stored outside of InputSection -void ThunkCreator::mergeThunks(OutputSection *OS, - std::vector<ThunkSection *> &Thunks) { - // Order Thunks in ascending OutSecOff - auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { - return A->OutSecOff < B->OutSecOff; - }; - std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); +void ThunkCreator::mergeThunks() { + for (auto &KV : ThunkSections) { + std::vector<InputSection *> *ISR = KV.first; + std::vector<ThunkSection *> &Thunks = KV.second; - // Merge sorted vectors of Thunks and InputSections by OutSecOff - std::vector<InputSection *> Tmp; - Tmp.reserve(OS->Sections.size() + Thunks.size()); - auto MergeCmp = [](const InputSection *A, const InputSection *B) { - // std::merge requires a strict weak ordering. - if (A->OutSecOff < B->OutSecOff) - return true; - if (A->OutSecOff == B->OutSecOff) - // Check if Thunk is immediately before any specific Target InputSection - // for example Mips LA25 Thunks. - if (auto *TA = dyn_cast<ThunkSection>(A)) - if (TA && TA->getTargetInputSection() == B) - return true; - return false; - }; - std::merge(OS->Sections.begin(), OS->Sections.end(), Thunks.begin(), - Thunks.end(), std::back_inserter(Tmp), MergeCmp); - OS->Sections = std::move(Tmp); - OS->assignOffsets(); + // Order Thunks in ascending OutSecOff + auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) { + return A->OutSecOff < B->OutSecOff; + }; + std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp); + + // Merge sorted vectors of Thunks and InputSections by OutSecOff + std::vector<InputSection *> Tmp; + Tmp.reserve(ISR->size() + Thunks.size()); + auto MergeCmp = [](const InputSection *A, const InputSection *B) { + // std::merge requires a strict weak ordering. + if (A->OutSecOff < B->OutSecOff) + return true; + if (A->OutSecOff == B->OutSecOff) + // Check if Thunk is immediately before any specific Target InputSection + // for example Mips LA25 Thunks. + if (auto *TA = dyn_cast<ThunkSection>(A)) + if (TA && TA->getTargetInputSection() == B) + return true; + return false; + }; + std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(), + std::back_inserter(Tmp), MergeCmp); + *ISR = std::move(Tmp); + } } -ThunkSection *ThunkCreator::getOSThunkSec(ThunkSection *&TS, - OutputSection *OS) { - if (TS == nullptr) { +ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS, + std::vector<InputSection *> *ISR) { + if (CurTS == nullptr) { uint32_t Off = 0; for (auto *IS : OS->Sections) { Off = IS->OutSecOff + IS->getSize(); if ((IS->Flags & SHF_EXECINSTR) == 0) break; } - TS = make<ThunkSection>(OS, Off); - ThunkSections[OS].push_back(TS); + CurTS = make<ThunkSection>(OS, Off); + ThunkSections[ISR].push_back(CurTS); } - return TS; + return CurTS; } ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) { @@ -1017,7 +1021,21 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection return TS; auto *TOS = IS->getParent(); TS = make<ThunkSection>(TOS, IS->OutSecOff); - ThunkSections[TOS].push_back(TS); + + // Find InputSectionRange within TOS that IS is in + OutputSectionCommand *C = Script->getCmd(TOS); + std::vector<InputSection *> *Range = nullptr; + for (BaseCommand *BC : C->Commands) + if (auto *ISD = dyn_cast<InputSectionDescription> (BC)) { + InputSection *first = ISD->Sections.front(); + InputSection *last = ISD->Sections.back(); + if (IS->OutSecOff >= first->OutSecOff && + IS->OutSecOff <= last->OutSecOff) { + Range = &ISD->Sections; + break; + } + } + ThunkSections[Range].push_back(TS); ThunkedSections[IS] = TS; return TS; } @@ -1030,6 +1048,27 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol return std::make_pair(res.first->second, res.second); } +// Call Fn on every executable InputSection accessed via the linker script +// InputSectionDescription::Sections. +void ThunkCreator::forEachExecInputSection( + ArrayRef<OutputSectionCommand *> OutputSections, + std::function<void(OutputSection *, std::vector<InputSection *> *, + InputSection *)> + Fn) { + for (OutputSectionCommand *Cmd : OutputSections) { + OutputSection *OS = Cmd->Sec; + if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR)) + continue; + if (OutputSectionCommand *C = Script->getCmd(OS)) + for (BaseCommand *BC : C->Commands) + if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) { + CurTS = nullptr; + for (InputSection* IS : ISD->Sections) + Fn(OS, &ISD->Sections, IS); + } + } +} + // Process all relocations from the InputSections that have been assigned // to OutputSections and redirect through Thunks if needed. // @@ -1040,42 +1079,41 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(Symbol // *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706101344.v5ADinJW095051>