Date: Tue, 31 Jul 2018 17:18:35 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r336982 - in projects/clang700-import/contrib/llvm/tools/lld: . COFF Common ELF ELF/Arch include/lld/Common include/lld/Core include/lld/ReaderWriter lib lib/Core lib/Driver lib/ReaderW... Message-ID: <201807311718.w6VHIZ7L015582@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Tue Jul 31 17:18:35 2018 New Revision: 336982 URL: https://svnweb.freebsd.org/changeset/base/336982 Log: Merge lld trunk r338150, and resolve conflicts. Added: projects/clang700-import/contrib/llvm/tools/lld/COFF/ICF.h - copied unchanged from r336979, vendor/lld/dist/COFF/ICF.h projects/clang700-import/contrib/llvm/tools/lld/COFF/MarkLive.h - copied unchanged from r336979, vendor/lld/dist/COFF/MarkLive.h projects/clang700-import/contrib/llvm/tools/lld/Common/Timer.cpp - copied unchanged from r336979, vendor/lld/dist/Common/Timer.cpp projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/Hexagon.cpp - copied unchanged from r336979, vendor/lld/dist/ELF/Arch/Hexagon.cpp projects/clang700-import/contrib/llvm/tools/lld/ELF/CallGraphSort.cpp - copied unchanged from r336979, vendor/lld/dist/ELF/CallGraphSort.cpp projects/clang700-import/contrib/llvm/tools/lld/ELF/CallGraphSort.h - copied unchanged from r336979, vendor/lld/dist/ELF/CallGraphSort.h projects/clang700-import/contrib/llvm/tools/lld/ELF/MarkLive.h - copied unchanged from r336979, vendor/lld/dist/ELF/MarkLive.h projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Timer.h - copied unchanged from r336979, vendor/lld/dist/include/lld/Common/Timer.h Deleted: projects/clang700-import/contrib/llvm/tools/lld/COFF/Strings.cpp projects/clang700-import/contrib/llvm/tools/lld/COFF/Strings.h projects/clang700-import/contrib/llvm/tools/lld/ELF/Strings.cpp projects/clang700-import/contrib/llvm/tools/lld/ELF/Strings.h projects/clang700-import/contrib/llvm/tools/lld/lib/Support/ projects/clang700-import/contrib/llvm/tools/lld/tools/linker-script-test/ Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Config.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Driver.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Driver.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/DriverUtils.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/ICF.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/InputFiles.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/InputFiles.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/LTO.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/LTO.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/MapFile.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/MarkLive.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/MinGW.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Options.td projects/clang700-import/contrib/llvm/tools/lld/COFF/PDB.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/PDB.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/SymbolTable.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/SymbolTable.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Symbols.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Symbols.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Writer.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/Writer.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Args.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/CMakeLists.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/ErrorHandler.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Strings.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/TargetOptionsCommandFlags.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/AArch64.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/AMDGPU.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/Mips.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/MipsArchTree.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/PPC.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/PPC64.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/SPARCV9.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/X86.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/X86_64.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/CMakeLists.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Config.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Driver.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Driver.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/DriverUtils.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/EhFrame.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Filesystem.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/GdbIndex.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/GdbIndex.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ICF.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ICF.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/InputFiles.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/InputSection.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/InputSection.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/LTO.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/LTO.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/LinkerScript.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/LinkerScript.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/MapFile.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/MapFile.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Options.td projects/clang700-import/contrib/llvm/tools/lld/ELF/OutputSections.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/OutputSections.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Relocations.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Relocations.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ScriptLexer.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ScriptParser.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/SymbolTable.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/SymbolTable.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Symbols.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Symbols.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/SyntheticSections.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Target.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Target.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Thunks.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Thunks.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Writer.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Writer.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/LICENSE.TXT (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Driver.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/ErrorHandler.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Strings.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/TargetOptionsCommandFlags.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Version.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/DefinedAtom.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/File.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Instrumentation.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/LinkingContext.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/PassManager.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Reader.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Resolver.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Simple.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/SymbolTable.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/TODO.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Writer.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/ReaderWriter/MachOLinkingContext.h (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/LinkingContext.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Driver/CMakeLists.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Driver/DarwinLdDriver.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Driver/DarwinLdOptions.td projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/FileArchive.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CMakeLists.txt (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/LayoutPass.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (contents, props changed) projects/clang700-import/contrib/llvm/tools/lld/tools/lld/lld.cpp (contents, props changed) Directory Properties: projects/clang700-import/contrib/llvm/tools/lld/ (props changed) projects/clang700-import/contrib/llvm/tools/lld/CMakeLists.txt (props changed) projects/clang700-import/contrib/llvm/tools/lld/CODE_OWNERS.TXT (props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/MapFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/COFF/MinGW.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Memory.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Reproduce.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Threads.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/Common/Version.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Arch/AVR.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Bits.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/EhFrame.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/Filesystem.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ScriptLexer.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/ELF/ScriptParser.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Args.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/LLVM.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Memory.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Reproduce.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Threads.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Common/Version.inc.in (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/AbsoluteAtom.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/ArchiveLibraryFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Atom.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Error.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Node.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Pass.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/Reference.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/SharedLibraryAtom.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/SharedLibraryFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/Core/UndefinedAtom.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/include/lld/ReaderWriter/YamlContext.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/CMakeLists.txt (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/CMakeLists.txt (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/DefinedAtom.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/Error.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/File.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/Reader.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/Resolver.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/SymbolTable.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/Core/Writer.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/CMakeLists.txt (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/Atoms.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/DebugInfo.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/File.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/GOTPass.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/LayoutPass.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachOPasses.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ObjCPass.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/SectCreateFile.h (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ShimPass.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/StubsPass.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/TLVPass.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/WriterMachO.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/YAML/CMakeLists.txt (props changed) projects/clang700-import/contrib/llvm/tools/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (props changed) projects/clang700-import/contrib/llvm/tools/lld/tools/lld/CMakeLists.txt (props changed) Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Tue Jul 31 17:18:35 2018 (r336982) @@ -18,7 +18,6 @@ add_lld_library(lldCOFF MarkLive.cpp MinGW.cpp PDB.cpp - Strings.cpp SymbolTable.cpp Symbols.cpp Writer.cpp Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.cpp ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Tue Jul 31 17:18:35 2018 (r336982) @@ -31,8 +31,7 @@ namespace coff { SectionChunk::SectionChunk(ObjFile *F, const coff_section *H) : Chunk(SectionKind), Repl(this), Header(H), File(F), - Relocs(File->getCOFFObj()->getRelocations(Header)), - NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { + Relocs(File->getCOFFObj()->getRelocations(Header)) { // Initialize SectionName. File->getCOFFObj()->getSectionName(Header, SectionName); @@ -51,13 +50,21 @@ static void add64(uint8_t *P, int64_t V) { write64le(P static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); } static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); } +// Verify that given sections are appropriate targets for SECREL +// relocations. This check is relaxed because unfortunately debug +// sections have section-relative relocations against absolute symbols. +static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) { + if (OS) + return true; + if (Sec->isCodeView()) + return false; + fatal("SECREL relocation cannot be applied to absolute symbols"); +} + static void applySecRel(const SectionChunk *Sec, uint8_t *Off, OutputSection *OS, uint64_t S) { - if (!OS) { - if (Sec->isCodeView()) - return; - fatal("SECREL relocation cannot be applied to absolute symbols"); - } + if (!checkSecRel(Sec, OS)) + return; uint64_t SecRel = S - OS->getRVA(); if (SecRel > UINT32_MAX) { error("overflow in SECREL relocation in section: " + Sec->getSectionName()); @@ -67,10 +74,13 @@ static void applySecRel(const SectionChunk *Sec, uint8 } static void applySecIdx(uint8_t *Off, OutputSection *OS) { - // If we have no output section, this must be an absolute symbol. Use the - // sentinel absolute symbol section index. - uint16_t SecIdx = OS ? OS->SectionIndex : DefinedAbsolute::OutputSectionIndex; - add16(Off, SecIdx); + // Absolute symbol doesn't have section index, but section index relocation + // against absolute symbol should be resolved to one plus the last output + // section index. This is required for compatibility with MSVC. + if (OS) + add16(Off, OS->SectionIndex); + else + add16(Off, DefinedAbsolute::NumOutputSections + 1); } void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, @@ -88,7 +98,8 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break; default: - fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); + fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + + toString(File)); } } @@ -102,7 +113,8 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break; default: - fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); + fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + + toString(File)); } } @@ -112,11 +124,10 @@ static void applyMOV(uint8_t *Off, uint16_t V) { } static uint16_t readMOV(uint8_t *Off) { - uint16_t Opcode1 = read16le(Off); - uint16_t Opcode2 = read16le(Off + 2); - uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700); - Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12); - return Imm; + uint16_t Op1 = read16le(Off); + uint16_t Op2 = read16le(Off + 2); + return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) | + ((Op1 & 0x000f) << 12); } void applyMOV32T(uint8_t *Off, uint32_t V) { @@ -153,7 +164,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t uint64_t S, uint64_t P) const { // Pointer to thumb code must have the LSB set. uint64_t SX = S; - if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE)) + if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE)) SX |= 1; switch (Type) { case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break; @@ -165,18 +176,19 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break; case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break; default: - fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); + fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + + toString(File)); } } // Interpret the existing immediate value as a byte offset to the // target symbol, then update the instruction with the immediate as // the page offset from the current instruction to the target. -static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P) { +static void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) { uint32_t Orig = read32le(Off); uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC); S += Imm; - Imm = (S >> 12) - (P >> 12); + Imm = (S >> Shift) - (P >> Shift); uint32_t ImmLo = (Imm & 0x3) << 29; uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); @@ -213,19 +225,70 @@ static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) applyArm64Imm(Off, Imm >> Size, Size); } +static void applySecRelLow12A(const SectionChunk *Sec, uint8_t *Off, + OutputSection *OS, uint64_t S) { + if (checkSecRel(Sec, OS)) + applyArm64Imm(Off, (S - OS->getRVA()) & 0xfff, 0); +} + +static void applySecRelHigh12A(const SectionChunk *Sec, uint8_t *Off, + OutputSection *OS, uint64_t S) { + if (!checkSecRel(Sec, OS)) + return; + uint64_t SecRel = (S - OS->getRVA()) >> 12; + if (0xfff < SecRel) { + error("overflow in SECREL_HIGH12A relocation in section: " + + Sec->getSectionName()); + return; + } + applyArm64Imm(Off, SecRel & 0xfff, 0); +} + +static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off, + OutputSection *OS, uint64_t S) { + if (checkSecRel(Sec, OS)) + applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff); +} + +static void applyArm64Branch26(uint8_t *Off, int64_t V) { + if (!isInt<28>(V)) + fatal("relocation out of range"); + or32(Off, (V & 0x0FFFFFFC) >> 2); +} + +static void applyArm64Branch19(uint8_t *Off, int64_t V) { + if (!isInt<21>(V)) + fatal("relocation out of range"); + or32(Off, (V & 0x001FFFFC) << 3); +} + +static void applyArm64Branch14(uint8_t *Off, int64_t V) { + if (!isInt<16>(V)) + fatal("relocation out of range"); + or32(Off, (V & 0x0000FFFC) << 3); +} + void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S, uint64_t P) const { switch (Type) { - case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P); break; + case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break; + case IMAGE_REL_ARM64_REL21: applyArm64Addr(Off, S, P, 0); break; case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break; case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break; - case IMAGE_REL_ARM64_BRANCH26: or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break; + case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(Off, S - P); break; + case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(Off, S - P); break; + case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(Off, S - P); break; case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break; case IMAGE_REL_ARM64_ADDR32NB: add32(Off, S); break; case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break; case IMAGE_REL_ARM64_SECREL: applySecRel(this, Off, OS, S); break; + case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, Off, OS, S); break; + case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break; + case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, Off, OS, S); break; + case IMAGE_REL_ARM64_SECTION: applySecIdx(Off, OS); break; default: - fatal("unsupported relocation type 0x" + Twine::utohexstr(Type)); + fatal("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " + + toString(File)); } } @@ -234,7 +297,8 @@ void SectionChunk::writeTo(uint8_t *Buf) const { return; // Copy section contents from source object file to output file. ArrayRef<uint8_t> A = getContents(); - memcpy(Buf + OutputSectionOff, A.data(), A.size()); + if (!A.empty()) + memcpy(Buf + OutputSectionOff, A.data(), A.size()); // Apply relocations. size_t InputSize = getSize(); @@ -350,8 +414,8 @@ bool SectionChunk::hasData() const { return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA); } -uint32_t SectionChunk::getPermissions() const { - return Header->Characteristics & PermMask; +uint32_t SectionChunk::getOutputCharacteristics() const { + return Header->Characteristics & (PermMask | TypeMask); } bool SectionChunk::isCOMDAT() const { @@ -378,6 +442,7 @@ ArrayRef<uint8_t> SectionChunk::getContents() const { } void SectionChunk::replace(SectionChunk *Other) { + Alignment = std::max(Alignment, Other->Alignment); Other->Repl = Repl; Other->Live = false; } @@ -388,7 +453,7 @@ CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym( Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue())); } -uint32_t CommonChunk::getPermissions() const { +uint32_t CommonChunk::getOutputCharacteristics() const { return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; } @@ -433,7 +498,7 @@ void ImportThunkChunkARM::writeTo(uint8_t *Buf) const void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const { int64_t Off = ImpSymbol->getRVA() & 0xfff; memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64)); - applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA); + applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12); applyArm64Ldr(Buf + OutputSectionOff + 4, Off); } @@ -453,12 +518,14 @@ void LocalImportChunk::writeTo(uint8_t *Buf) const { } } -void SEHTableChunk::writeTo(uint8_t *Buf) const { +void RVATableChunk::writeTo(uint8_t *Buf) const { ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff); size_t Cnt = 0; - for (Defined *D : Syms) - Begin[Cnt++] = D->getRVA(); + for (const ChunkAndOffset &CO : Syms) + Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset; std::sort(Begin, Begin + Cnt); + assert(std::unique(Begin, Begin + Cnt) == Begin + Cnt && + "RVA tables should be de-duplicated"); } // Windows-specific. This class represents a block in .reloc section. @@ -529,6 +596,48 @@ uint8_t Baserel::getDefaultType() { default: llvm_unreachable("unknown machine type"); } +} + +std::map<uint32_t, MergeChunk *> MergeChunk::Instances; + +MergeChunk::MergeChunk(uint32_t Alignment) + : Builder(StringTableBuilder::RAW, Alignment) { + this->Alignment = Alignment; +} + +void MergeChunk::addSection(SectionChunk *C) { + auto *&MC = Instances[C->Alignment]; + if (!MC) + MC = make<MergeChunk>(C->Alignment); + MC->Sections.push_back(C); +} + +void MergeChunk::finalizeContents() { + for (SectionChunk *C : Sections) + if (C->isLive()) + Builder.add(toStringRef(C->getContents())); + Builder.finalize(); + + for (SectionChunk *C : Sections) { + if (!C->isLive()) + continue; + size_t Off = Builder.getOffset(toStringRef(C->getContents())); + C->setOutputSection(Out); + C->setRVA(RVA + Off); + C->OutputSectionOff = OutputSectionOff + Off; + } +} + +uint32_t MergeChunk::getOutputCharacteristics() const { + return IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA; +} + +size_t MergeChunk::getSize() const { + return Builder.getSize(); +} + +void MergeChunk::writeTo(uint8_t *Buf) const { + Builder.write(Buf + OutputSectionOff); } } // namespace coff Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.h ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.h Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/Chunks.h Tue Jul 31 17:18:35 2018 (r336982) @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/COFF.h" #include <utility> #include <vector> @@ -37,10 +38,12 @@ class ObjFile; class OutputSection; class Symbol; -// Mask for section types (code, data, bss, disacardable, etc.) -// and permissions (writable, readable or executable). -const uint32_t PermMask = 0xFF0000F0; +// Mask for permissions (discardable, writable, readable, executable, etc). +const uint32_t PermMask = 0xFE000000; +// Mask for section types (code, data, bss). +const uint32_t TypeMask = 0x000000E0; + // A Chunk represents a chunk of data that will occupy space in the // output (if the resolver chose that). It may or may not be backed by // a section of an input file. It could be linker-created data, or @@ -60,6 +63,10 @@ class Chunk { (public) // before calling this function. virtual void writeTo(uint8_t *Buf) const {} + // Called by the writer after an RVA is assigned, but before calling + // getSize(). + virtual void finalizeContents() {} + // The writer sets and uses the addresses. uint64_t getRVA() const { return RVA; } void setRVA(uint64_t V) { RVA = V; } @@ -70,7 +77,7 @@ class Chunk { (public) virtual bool hasData() const { return true; } // Returns readable/writable/executable bits. - virtual uint32_t getPermissions() const { return 0; } + virtual uint32_t getOutputCharacteristics() const { return 0; } // Returns the section name if this is a section chunk. // It is illegal to call this function on non-section chunks. @@ -137,7 +144,7 @@ class SectionChunk final : public Chunk { (public) ArrayRef<uint8_t> getContents() const; void writeTo(uint8_t *Buf) const override; bool hasData() const override; - uint32_t getPermissions() const override; + uint32_t getOutputCharacteristics() const override; StringRef getSectionName() const override { return SectionName; } void getBaserels(std::vector<Baserel> *Res) override; bool isCOMDAT() const; @@ -208,11 +215,11 @@ class SectionChunk final : public Chunk { (public) // The COMDAT leader symbol if this is a COMDAT chunk. DefinedRegular *Sym = nullptr; + ArrayRef<coff_relocation> Relocs; + private: StringRef SectionName; std::vector<SectionChunk *> AssocChildren; - llvm::iterator_range<const coff_relocation *> Relocs; - size_t NumRelocs; // Used by the garbage collector. bool Live; @@ -222,13 +229,40 @@ class SectionChunk final : public Chunk { (public) uint32_t Class[2] = {0, 0}; }; +// This class is used to implement an lld-specific feature (not implemented in +// MSVC) that minimizes the output size by finding string literals sharing tail +// parts and merging them. +// +// If string tail merging is enabled and a section is identified as containing a +// string literal, it is added to a MergeChunk with an appropriate alignment. +// The MergeChunk then tail merges the strings using the StringTableBuilder +// class and assigns RVAs and section offsets to each of the member chunks based +// on the offsets assigned by the StringTableBuilder. +class MergeChunk : public Chunk { +public: + MergeChunk(uint32_t Alignment); + static void addSection(SectionChunk *C); + void finalizeContents() override; + + uint32_t getOutputCharacteristics() const override; + StringRef getSectionName() const override { return ".rdata"; } + size_t getSize() const override; + void writeTo(uint8_t *Buf) const override; + + static std::map<uint32_t, MergeChunk *> Instances; + std::vector<SectionChunk *> Sections; + +private: + llvm::StringTableBuilder Builder; +}; + // A chunk for common symbols. Common chunks don't have actual data. class CommonChunk : public Chunk { public: CommonChunk(const COFFSymbolRef Sym); size_t getSize() const override { return Sym.getValue(); } bool hasData() const override { return false; } - uint32_t getPermissions() const override; + uint32_t getOutputCharacteristics() const override; StringRef getSectionName() const override { return ".bss"; } private: @@ -320,17 +354,41 @@ class LocalImportChunk : public Chunk { (private) Defined *Sym; }; -// Windows-specific. -// A chunk for SEH table which contains RVAs of safe exception handler -// functions. x86-only. -class SEHTableChunk : public Chunk { +// Duplicate RVAs are not allowed in RVA tables, so unique symbols by chunk and +// offset into the chunk. Order does not matter as the RVA table will be sorted +// later. +struct ChunkAndOffset { + Chunk *InputChunk; + uint32_t Offset; + + struct DenseMapInfo { + static ChunkAndOffset getEmptyKey() { + return {llvm::DenseMapInfo<Chunk *>::getEmptyKey(), 0}; + } + static ChunkAndOffset getTombstoneKey() { + return {llvm::DenseMapInfo<Chunk *>::getTombstoneKey(), 0}; + } + static unsigned getHashValue(const ChunkAndOffset &CO) { + return llvm::DenseMapInfo<std::pair<Chunk *, uint32_t>>::getHashValue( + {CO.InputChunk, CO.Offset}); + } + static bool isEqual(const ChunkAndOffset &LHS, const ChunkAndOffset &RHS) { + return LHS.InputChunk == RHS.InputChunk && LHS.Offset == RHS.Offset; + } + }; +}; + +using SymbolRVASet = llvm::DenseSet<ChunkAndOffset>; + +// Table which contains symbol RVAs. Used for /safeseh and /guard:cf. +class RVATableChunk : public Chunk { public: - explicit SEHTableChunk(std::set<Defined *> S) : Syms(std::move(S)) {} + explicit RVATableChunk(SymbolRVASet S) : Syms(std::move(S)) {} size_t getSize() const override { return Syms.size() * 4; } void writeTo(uint8_t *Buf) const override; private: - std::set<Defined *> Syms; + SymbolRVASet Syms; }; // Windows-specific. @@ -361,5 +419,11 @@ void applyBranch24T(uint8_t *Off, int32_t V); } // namespace coff } // namespace lld + +namespace llvm { +template <> +struct DenseMapInfo<lld::coff::ChunkAndOffset> + : lld::coff::ChunkAndOffset::DenseMapInfo {}; +} #endif Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/Config.h ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/Config.h Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/Config.h Tue Jul 31 17:18:35 2018 (r336982) @@ -10,6 +10,7 @@ #ifndef LLD_COFF_CONFIG_H #define LLD_COFF_CONFIG_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include "llvm/Support/CachePruning.h" @@ -71,6 +72,12 @@ enum class DebugType { Fixup = 0x4, /// Relocation Table }; +enum class GuardCFLevel { + Off, + NoLongJmp, // Emit gfids but no longjmp tables + Full, // Enable all protections. +}; + // Global configuration. struct Configuration { enum ManifestKind { SideBySide, Embed, No }; @@ -85,13 +92,19 @@ struct Configuration { std::string ImportName; bool DoGC = true; bool DoICF = true; + bool TailMerge; bool Relocatable = true; bool Force = false; bool Debug = false; bool DebugDwarf = false; bool DebugGHashes = false; + bool DebugSymtab = false; + bool ShowTiming = false; unsigned DebugTypes = static_cast<unsigned>(DebugType::None); + std::vector<std::string> NatvisFiles; + llvm::SmallString<128> PDBAltPath; llvm::SmallString<128> PDBPath; + llvm::SmallString<128> PDBSourcePath; std::vector<llvm::StringRef> Argv; // Symbols in this set are considered as live by the garbage collector. @@ -110,15 +123,18 @@ struct Configuration { bool SaveTemps = false; + // /guard:cf + GuardCFLevel GuardCF = GuardCFLevel::Off; + // Used for SafeSEH. Symbol *SEHTable = nullptr; Symbol *SEHCount = nullptr; // Used for /opt:lldlto=N - unsigned LTOOptLevel = 2; + unsigned LTOO = 2; // Used for /opt:lldltojobs=N - unsigned LTOJobs = 0; + unsigned ThinLTOJobs = 0; // Used for /opt:lldltopartitions=N unsigned LTOPartitions = 1; @@ -152,6 +168,9 @@ struct Configuration { // Used for /alternatename. std::map<StringRef, StringRef> AlternateNames; + // Used for /order. + llvm::StringMap<int> Order; + // Used for /lldmap. std::string MapFile; @@ -164,7 +183,7 @@ struct Configuration { uint32_t MinorImageVersion = 0; uint32_t MajorOSVersion = 6; uint32_t MinorOSVersion = 0; - bool CanExitEarly = false; + uint32_t Timestamp = 0; bool DynamicBase = true; bool AllowBind = true; bool NxCompat = true; @@ -174,8 +193,12 @@ struct Configuration { bool HighEntropyVA = false; bool AppContainer = false; bool MinGW = false; + bool WarnMissingOrderSymbol = true; bool WarnLocallyDefinedImported = true; + bool Incremental = true; + bool IntegrityCheck = false; bool KillAt = false; + bool Repro = false; }; extern Configuration *Config; Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.cpp ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.cpp Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.cpp Tue Jul 31 17:18:35 2018 (r336982) @@ -18,8 +18,8 @@ // //===----------------------------------------------------------------------===// -#include "Chunks.h" #include "DLL.h" +#include "Chunks.h" #include "llvm/Object/COFF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Path.h" Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.h ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.h Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/DLL.h Tue Jul 31 17:18:35 2018 (r336982) @@ -76,6 +76,11 @@ class EdataContents { public: EdataContents(); std::vector<Chunk *> Chunks; + + uint64_t getRVA() { return Chunks[0]->getRVA(); } + uint64_t getSize() { + return Chunks.back()->getRVA() + Chunks.back()->getSize() - getRVA(); + } }; } // namespace coff Modified: projects/clang700-import/contrib/llvm/tools/lld/COFF/Driver.cpp ============================================================================== --- projects/clang700-import/contrib/llvm/tools/lld/COFF/Driver.cpp Tue Jul 31 17:16:06 2018 (r336981) +++ projects/clang700-import/contrib/llvm/tools/lld/COFF/Driver.cpp Tue Jul 31 17:18:35 2018 (r336982) @@ -9,14 +9,18 @@ #include "Driver.h" #include "Config.h" +#include "ICF.h" #include "InputFiles.h" +#include "MarkLive.h" #include "MinGW.h" #include "SymbolTable.h" #include "Symbols.h" #include "Writer.h" +#include "lld/Common/Args.h" #include "lld/Common/Driver.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" +#include "lld/Common/Timer.h" #include "lld/Common/Version.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSwitch.h" @@ -35,10 +39,9 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/ToolDrivers/llvm-lib/LibDriver.h" #include <algorithm> +#include <future> #include <memory> -#include <future> - using namespace llvm; using namespace llvm::object; using namespace llvm::COFF; @@ -47,20 +50,20 @@ using llvm::sys::Process; namespace lld { namespace coff { +static Timer InputFileTimer("Input File Reading", Timer::root()); + Configuration *Config; LinkerDriver *Driver; bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) { - errorHandler().LogName = Args[0]; + errorHandler().LogName = sys::path::filename(Args[0]); errorHandler().ErrorOS = &Diag; errorHandler().ColorDiagnostics = Diag.has_colors(); errorHandler().ErrorLimitExceededMsg = "too many errors emitted, stopping now" - " (use /ERRORLIMIT:0 to see all errors)"; + " (use /errorlimit:0 to see all errors)"; errorHandler().ExitEarly = CanExitEarly; Config = make<Configuration>(); - Config->Argv = {Args.begin(), Args.end()}; - Config->CanExitEarly = CanExitEarly; Symtab = make<SymbolTable>(); @@ -72,6 +75,9 @@ bool link(ArrayRef<const char *> Args, bool CanExitEar exitLld(errorCount() ? 1 : 0); freeArena(); + ObjFile::Instances.clear(); + ImportFile::Instances.clear(); + BitcodeFile::Instances.clear(); return !errorCount(); } @@ -93,7 +99,7 @@ typedef std::pair<std::unique_ptr<MemoryBuffer>, std:: // Create a std::future that opens and maps a file using the best strategy for // the host platform. static std::future<MBErrPair> createFutureForFile(std::string Path) { -#if LLVM_ON_WIN32 +#if _WIN32 // On Windows, file I/O is relatively slow so it is best to do this // asynchronously. auto Strategy = std::launch::async; @@ -101,7 +107,9 @@ static std::future<MBErrPair> createFutureForFile(std: auto Strategy = std::launch::deferred; #endif return std::async(Strategy, [=]() { - auto MBOrErr = MemoryBuffer::getFile(Path); + auto MBOrErr = MemoryBuffer::getFile(Path, + /*FileSize*/ -1, + /*RequiresNullTerminator*/ false); if (!MBOrErr) return MBErrPair{nullptr, MBOrErr.getError()}; return MBErrPair{std::move(*MBOrErr), std::error_code()}; @@ -120,39 +128,46 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_p void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB, bool WholeArchive) { + StringRef Filename = MB->getBufferIdentifier(); + MemoryBufferRef MBRef = takeBuffer(std::move(MB)); - FilePaths.push_back(MBRef.getBufferIdentifier()); + FilePaths.push_back(Filename); // File type is detected by contents, not by file extension. switch (identify_magic(MBRef.getBuffer())) { case file_magic::windows_resource: Resources.push_back(MBRef); break; - case file_magic::archive: if (WholeArchive) { std::unique_ptr<Archive> File = - CHECK(Archive::create(MBRef), - MBRef.getBufferIdentifier() + ": failed to parse archive"); + CHECK(Archive::create(MBRef), Filename + ": failed to parse archive"); for (MemoryBufferRef M : getArchiveMembers(File.get())) - addArchiveBuffer(M, "<whole-archive>", MBRef.getBufferIdentifier()); + addArchiveBuffer(M, "<whole-archive>", Filename); return; } Symtab->addFile(make<ArchiveFile>(MBRef)); break; - case file_magic::bitcode: Symtab->addFile(make<BitcodeFile>(MBRef)); break; - + case file_magic::coff_object: + case file_magic::coff_import_library: + Symtab->addFile(make<ObjFile>(MBRef)); + break; case file_magic::coff_cl_gl_object: - error(MBRef.getBufferIdentifier() + ": is not a native COFF file. " - "Recompile without /GL"); + error(Filename + ": is not a native COFF file. Recompile without /GL"); break; - + case file_magic::pecoff_executable: + if (Filename.endswith_lower(".dll")) { + error(Filename + ": bad file type. Did you specify a DLL instead of an " + "import library?"); + break; + } + LLVM_FALLTHROUGH; default: - Symtab->addFile(make<ObjFile>(MBRef)); + error(MBRef.getBufferIdentifier() + ": unknown file type"); break; } } @@ -228,8 +243,30 @@ static bool isDecorated(StringRef Sym) { void LinkerDriver::parseDirectives(StringRef S) { ArgParser Parser; // .drectve is always tokenized using Windows shell rules. - opt::InputArgList Args = Parser.parseDirectives(S); + // /EXPORT: option can appear too many times, processing in fastpath. + opt::InputArgList Args; + std::vector<StringRef> Exports; + std::tie(Args, Exports) = Parser.parseDirectives(S); + for (StringRef E : Exports) { + // If a common header file contains dllexported function + // declarations, many object files may end up with having the + // same /EXPORT options. In order to save cost of parsing them, + // we dedup them first. + if (!DirectivesExports.insert(E).second) + continue; + + Export Exp = parseExport(E); + if (Config->Machine == I386 && Config->MinGW) { + if (!isDecorated(Exp.Name)) + Exp.Name = Saver.save("_" + Exp.Name); + if (!Exp.ExtName.empty() && !isDecorated(Exp.ExtName)) + Exp.ExtName = Saver.save("_" + Exp.ExtName); + } + Exp.Directives = true; + Config->Exports.push_back(Exp); + } + for (auto *Arg : Args) { switch (Arg->getOption().getUnaliasedOption().getID()) { case OPT_aligncomm: @@ -245,25 +282,6 @@ void LinkerDriver::parseDirectives(StringRef S) { case OPT_entry: Config->Entry = addUndefined(mangle(Arg->getValue())); break; - case OPT_export: { - // If a common header file contains dllexported function - // declarations, many object files may end up with having the - // same /EXPORT options. In order to save cost of parsing them, - // we dedup them first. - if (!DirectivesExports.insert(Arg->getValue()).second) - break; - - Export E = parseExport(Arg->getValue()); - if (Config->Machine == I386 && Config->MinGW) { - if (!isDecorated(E.Name)) - E.Name = Saver.save("_" + E.Name); - if (!E.ExtName.empty() && !isDecorated(E.ExtName)) - E.ExtName = Saver.save("_" + E.ExtName); - } - E.Directives = true; - Config->Exports.push_back(E); - break; - } case OPT_failifmismatch: checkFailIfMismatch(Arg->getValue()); break; @@ -316,13 +334,24 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) return Filename; } +static Optional<sys::fs::UniqueID> getUniqueID(StringRef Path) { + sys::fs::UniqueID Ret; + if (sys::fs::getUniqueID(Path, Ret)) + return None; + return Ret; +} + // Resolves a file path. This never returns the same path // (in that case, it returns None). Optional<StringRef> LinkerDriver::findFile(StringRef Filename) { StringRef Path = doFindFile(Filename); - bool Seen = !VisitedFiles.insert(Path.lower()).second; - if (Seen) - return None; + + if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) { + bool Seen = !VisitedFiles.insert(*ID).second; + if (Seen) + return None; + } + if (Path.endswith_lower(".lib")) VisitedLibs.insert(sys::path::filename(Path)); return Path; @@ -345,11 +374,14 @@ Optional<StringRef> LinkerDriver::findLib(StringRef Fi return None; if (!VisitedLibs.insert(Filename.lower()).second) return None; + StringRef Path = doFindLib(Filename); if (Config->NoDefaultLibs.count(Path)) return None; - if (!VisitedFiles.insert(Path.lower()).second) - return None; + + if (Optional<sys::fs::UniqueID> ID = getUniqueID(Path)) + if (!VisitedFiles.insert(*ID).second) + return None; return Path; } @@ -384,7 +416,24 @@ StringRef LinkerDriver::mangle(StringRef Sym) { } // Windows specific -- find default entry point name. +// +// There are four different entry point functions for Windows executables, +// each of which corresponds to a user-defined "main" function. This function +// infers an entry point from a user-defined "main" function. StringRef LinkerDriver::findDefaultEntry() { + // As a special case, if /nodefaultlib is given, we directly look for an + // entry point. This is because, if no default library is linked, users + // need to define an entry point instead of a "main". + if (Config->NoDefaultLibAll) { + for (StringRef S : {"mainCRTStartup", "wmainCRTStartup", + "WinMainCRTStartup", "wWinMainCRTStartup"}) { + StringRef Entry = Symtab->findMangle(S); + if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry))) + return mangle(S); + } + return ""; + } + // User-defined main functions and their corresponding entry points. static const char *Entries[][2] = { {"main", "mainCRTStartup"}, @@ -534,10 +583,49 @@ static void createImportLibrary(bool AsLib) { Exports.push_back(E2); } - auto E = writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports, - Config->Machine, false); - handleAllErrors(std::move(E), - [&](ErrorInfoBase &EIB) { error(EIB.message()); }); + auto HandleError = [](Error &&E) { + handleAllErrors(std::move(E), + [](ErrorInfoBase &EIB) { error(EIB.message()); }); + }; + std::string LibName = getImportName(AsLib); + std::string Path = getImplibPath(); + + if (!Config->Incremental) { + HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, + Config->MinGW)); + return; + } + + // If the import library already exists, replace it only if the contents + // have changed. + ErrorOr<std::unique_ptr<MemoryBuffer>> OldBuf = MemoryBuffer::getFile( + Path, /*FileSize*/ -1, /*RequiresNullTerminator*/ false); + if (!OldBuf) { + HandleError(writeImportLibrary(LibName, Path, Exports, Config->Machine, + Config->MinGW)); + return; + } + + SmallString<128> TmpName; + if (std::error_code EC = + sys::fs::createUniqueFile(Path + ".tmp-%%%%%%%%.lib", TmpName)) + fatal("cannot create temporary file for import library " + Path + ": " + + EC.message()); + + if (Error E = writeImportLibrary(LibName, TmpName, Exports, Config->Machine, + Config->MinGW)) { + HandleError(std::move(E)); + return; + } + + std::unique_ptr<MemoryBuffer> NewBuf = check(MemoryBuffer::getFile( + TmpName, /*FileSize*/ -1, /*RequiresNullTerminator*/ false)); + if ((*OldBuf)->getBuffer() != NewBuf->getBuffer()) { + OldBuf->reset(); + HandleError(errorCodeToError(sys::fs::rename(TmpName, Path))); + } else { + sys::fs::remove(TmpName); + } } static void parseModuleDefs(StringRef Path) { @@ -570,9 +658,18 @@ static void parseModuleDefs(StringRef Path) { for (COFFShortExport E1 : M.Exports) { Export E2; + // In simple cases, only Name is set. Renamed exports are parsed + // and set as "ExtName = Name". If Name has the form "OtherDll.Func", + // it shouldn't be a normal exported function but a forward to another + // DLL instead. This is supported by both MS and GNU linkers. + if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) { + E2.Name = Saver.save(E1.ExtName); + E2.ForwardTo = Saver.save(E1.Name); + Config->Exports.push_back(E2); + continue; + } E2.Name = Saver.save(E1.Name); - if (E1.isWeak()) - E2.ExtName = Saver.save(E1.ExtName); + E2.ExtName = Saver.save(E1.ExtName); E2.Ordinal = E1.Ordinal; E2.Noname = E1.Noname; E2.Data = E1.Data; @@ -635,8 +732,8 @@ filterBitcodeFiles(StringRef Path, std::vector<std::st log("Creating a temporary archive for " + Path + " to remove bitcode files"); SmallString<128> S; - if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path), - ".lib", S)) + if (std::error_code EC = sys::fs::createTemporaryFile( + "lld-" + sys::path::stem(Path), ".lib", S)) fatal("cannot create a temporary file: " + EC.message()); std::string Temp = S.str(); TemporaryFiles.push_back(Temp); @@ -712,6 +809,8 @@ void LinkerDriver::enqueueTask(std::function<void()> T } bool LinkerDriver::run() { + ScopedTimer T(InputFileTimer); + bool DidWork = !TaskQueue.empty(); while (!TaskQueue.empty()) { TaskQueue.front()(); @@ -720,6 +819,46 @@ bool LinkerDriver::run() { return DidWork; } +// Parse an /order file. If an option is given, the linker places +// COMDAT sections in the same order as their names appear in the +// given file. +static void parseOrderFile(StringRef Arg) { + // For some reason, the MSVC linker requires a filename to be + // preceded by "@". + if (!Arg.startswith("@")) { + error("malformed /order option: '@' missing"); + return; + } + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807311718.w6VHIZ7L015582>