svn commit: r327026 - in projects/clang600-import/contrib/llvm/tools/lld: . COFF Common ELF ELF/Arch include/lld/Common include/lld/Config include/lld/Core include/lld/Driver include/lld/ReaderWrit...
Dimitry Andric
dim at FreeBSD.org
Wed Dec 20 15:50:24 UTC 2017
Author: dim
Date: Wed Dec 20 15:50:21 2017
New Revision: 327026
URL: https://svnweb.freebsd.org/changeset/base/327026
Log:
Merge lld trunk r321017 to contrib/llvm/tools/lld.
Added:
projects/clang600-import/contrib/llvm/tools/lld/COFF/MinGW.cpp
- copied unchanged from r327025, vendor/lld/dist/COFF/MinGW.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/MinGW.h
- copied unchanged from r327025, vendor/lld/dist/COFF/MinGW.h
projects/clang600-import/contrib/llvm/tools/lld/Common/
- copied from r327025, vendor/lld/dist/Common/
projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.cpp
- copied unchanged from r327025, vendor/lld/dist/ELF/AArch64ErrataFix.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/AArch64ErrataFix.h
- copied unchanged from r327025, vendor/lld/dist/ELF/AArch64ErrataFix.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Bits.h
- copied unchanged from r327025, vendor/lld/dist/ELF/Bits.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Common/
- copied from r327025, vendor/lld/dist/include/lld/Common/
Deleted:
projects/clang600-import/contrib/llvm/tools/lld/COFF/Error.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Error.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/Memory.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Error.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Error.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Memory.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Threads.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Config/
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/LLVM.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/Reproduce.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/TargetOptionsCommandFlags.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Driver/
projects/clang600-import/contrib/llvm/tools/lld/lib/Config/
projects/clang600-import/contrib/llvm/tools/lld/lib/Core/Reproduce.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/Core/TargetOptionsCommandFlags.cpp
projects/clang600-import/contrib/llvm/tools/lld/utils/
Modified:
projects/clang600-import/contrib/llvm/tools/lld/.arcconfig
projects/clang600-import/contrib/llvm/tools/lld/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/CODE_OWNERS.TXT
projects/clang600-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/Config.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Driver.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Driver.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/DriverUtils.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/ICF.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/InputFiles.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/InputFiles.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/LTO.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/LTO.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/MapFile.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/MarkLive.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Options.td
projects/clang600-import/contrib/llvm/tools/lld/COFF/PDB.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/PDB.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/Strings.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Strings.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/SymbolTable.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/SymbolTable.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/Symbols.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Symbols.h
projects/clang600-import/contrib/llvm/tools/lld/COFF/Writer.cpp
projects/clang600-import/contrib/llvm/tools/lld/COFF/Writer.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/AArch64.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/AMDGPU.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/AVR.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/Mips.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/MipsArchTree.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/PPC.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/PPC64.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/SPARCV9.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/X86.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Arch/X86_64.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/ELF/Config.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Driver.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/DriverUtils.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/EhFrame.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/EhFrame.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Filesystem.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Filesystem.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/GdbIndex.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/GdbIndex.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/ICF.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/InputFiles.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/InputSection.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/LTO.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/LTO.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/LinkerScript.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/MapFile.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/MapFile.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Options.td
projects/clang600-import/contrib/llvm/tools/lld/ELF/OutputSections.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/OutputSections.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Relocations.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/ScriptLexer.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/ScriptLexer.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/ScriptParser.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Strings.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Strings.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/SymbolTable.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/SymbolTable.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Symbols.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Symbols.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/SyntheticSections.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Target.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Target.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Thunks.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Thunks.h
projects/clang600-import/contrib/llvm/tools/lld/ELF/Writer.cpp
projects/clang600-import/contrib/llvm/tools/lld/ELF/Writer.h
projects/clang600-import/contrib/llvm/tools/lld/FREEBSD-Xlist
projects/clang600-import/contrib/llvm/tools/lld/README.md
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/Atom.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/DefinedAtom.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/Error.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/LinkingContext.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/PassManager.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/Reader.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/SymbolTable.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/Core/Writer.h
projects/clang600-import/contrib/llvm/tools/lld/include/lld/ReaderWriter/YamlContext.h
projects/clang600-import/contrib/llvm/tools/lld/lib/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/lib/Core/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/lib/Core/Resolver.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/Core/SymbolTable.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/Driver/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/lib/Driver/DarwinLdDriver.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/FileArchive.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.h
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/GOTPass.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ObjCPass.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ShimPass.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/StubsPass.cpp
projects/clang600-import/contrib/llvm/tools/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
projects/clang600-import/contrib/llvm/tools/lld/tools/lld/CMakeLists.txt
projects/clang600-import/contrib/llvm/tools/lld/tools/lld/lld.cpp
Directory Properties:
projects/clang600-import/contrib/llvm/tools/lld/ (props changed)
Modified: projects/clang600-import/contrib/llvm/tools/lld/.arcconfig
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/.arcconfig Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/.arcconfig Wed Dec 20 15:50:21 2017 (r327026)
@@ -1,4 +1,4 @@
{
- "project_id" : "lld",
+ "repository.callsign" : "LLD",
"conduit_uri" : "https://reviews.llvm.org/"
}
Modified: projects/clang600-import/contrib/llvm/tools/lld/CMakeLists.txt
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/CMakeLists.txt Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/CMakeLists.txt Wed Dec 20 15:50:21 2017 (r327026)
@@ -160,8 +160,8 @@ endif ()
# Configure the Version.inc file.
configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Config/Version.inc.in
- ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Config/Version.inc)
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Common/Version.inc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Common/Version.inc)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
@@ -210,6 +210,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
)
endif()
+add_subdirectory(Common)
add_subdirectory(lib)
add_subdirectory(tools/lld)
@@ -221,4 +222,5 @@ endif()
add_subdirectory(docs)
add_subdirectory(COFF)
add_subdirectory(ELF)
-
+add_subdirectory(MinGW)
+add_subdirectory(wasm)
Modified: projects/clang600-import/contrib/llvm/tools/lld/CODE_OWNERS.TXT
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/CODE_OWNERS.TXT Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/CODE_OWNERS.TXT Wed Dec 20 15:50:21 2017 (r327026)
@@ -17,3 +17,6 @@ N: Lang Hames, Nick Kledzik
E: lhames at gmail.com, kledzik at apple.com
D: Mach-O backend
+N: Sam Clegg
+E: sbc at chromium.org
+D: WebAssembly backend (wasm/*)
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Wed Dec 20 15:50:21 2017 (r327026)
@@ -11,12 +11,12 @@ add_lld_library(lldCOFF
DLL.cpp
Driver.cpp
DriverUtils.cpp
- Error.cpp
ICF.cpp
InputFiles.cpp
LTO.cpp
MapFile.cpp
MarkLive.cpp
+ MinGW.cpp
PDB.cpp
Strings.cpp
SymbolTable.cpp
@@ -26,22 +26,20 @@ add_lld_library(lldCOFF
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
BinaryFormat
- BitReader
Core
DebugInfoCodeView
DebugInfoMSF
DebugInfoPDB
- LTO
LibDriver
- Object
+ LTO
MC
- MCDisassembler
- Target
+ Object
Option
Support
+ WindowsManifest
LINK_LIBS
- lldCore
+ lldCommon
${LLVM_PTHREAD_LIB}
DEPENDS
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Wed Dec 20 15:50:21 2017 (r327026)
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#include "Chunks.h"
-#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "Writer.h"
+#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
@@ -29,18 +29,15 @@ using llvm::support::ulittle32_t;
namespace lld {
namespace coff {
-SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
+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())) {
// Initialize SectionName.
File->getCOFFObj()->getSectionName(Header, SectionName);
- Align = Header->getAlignment();
+ Alignment = Header->getAlignment();
- // Chunks may be discarded during comdat merging.
- Discarded = false;
-
// If linker GC is disabled, every chunk starts out alive. If linker GC is
// enabled, treat non-comdat sections as roots. Generally optimized object
// files will be built with -ffunction-sections or /Gy, so most things worth
@@ -62,7 +59,10 @@ static void applySecRel(const SectionChunk *Sec, uint8
fatal("SECREL relocation cannot be applied to absolute symbols");
}
uint64_t SecRel = S - OS->getRVA();
- assert(SecRel < INT32_MAX && "overflow in SECREL relocation");
+ if (SecRel > UINT32_MAX) {
+ error("overflow in SECREL relocation in section: " + Sec->getSectionName());
+ return;
+ }
add32(Off, SecRel);
}
@@ -119,7 +119,7 @@ static uint16_t readMOV(uint8_t *Off) {
return Imm;
}
-static void applyMOV32T(uint8_t *Off, uint32_t V) {
+void applyMOV32T(uint8_t *Off, uint32_t V) {
uint16_t ImmW = readMOV(Off); // read MOVW operand
uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
uint32_t Imm = ImmW | (ImmT << 16);
@@ -129,6 +129,8 @@ static void applyMOV32T(uint8_t *Off, uint32_t V) {
}
static void applyBranch20T(uint8_t *Off, int32_t V) {
+ if (!isInt<21>(V))
+ fatal("relocation out of range");
uint32_t S = V < 0 ? 1 : 0;
uint32_t J1 = (V >> 19) & 1;
uint32_t J2 = (V >> 18) & 1;
@@ -136,7 +138,7 @@ static void applyBranch20T(uint8_t *Off, int32_t V) {
or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
}
-static void applyBranch24T(uint8_t *Off, int32_t V) {
+void applyBranch24T(uint8_t *Off, int32_t V) {
if (!isInt<25>(V))
fatal("relocation out of range");
uint32_t S = V < 0 ? 1 : 0;
@@ -167,36 +169,61 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t
}
}
-static void applyArm64Addr(uint8_t *Off, uint64_t Imm) {
+// 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) {
+ uint32_t Orig = read32le(Off);
+ uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
+ S += Imm;
+ Imm = (S >> 12) - (P >> 12);
uint32_t ImmLo = (Imm & 0x3) << 29;
uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
- write32le(Off, (read32le(Off) & ~Mask) | ImmLo | ImmHi);
+ write32le(Off, (Orig & ~Mask) | ImmLo | ImmHi);
}
// Update the immediate field in a AARCH64 ldr, str, and add instruction.
-static void applyArm64Imm(uint8_t *Off, uint64_t Imm) {
+// Optionally limit the range of the written immediate by one or more bits
+// (RangeLimit).
+static void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
uint32_t Orig = read32le(Off);
Imm += (Orig >> 10) & 0xFFF;
Orig &= ~(0xFFF << 10);
- write32le(Off, Orig | ((Imm & 0xFFF) << 10));
+ write32le(Off, Orig | ((Imm & (0xFFF >> RangeLimit)) << 10));
}
+// Add the 12 bit page offset to the existing immediate.
+// Ldr/str instructions store the opcode immediate scaled
+// by the load/store size (giving a larger range for larger
+// loads/stores). The immediate is always (both before and after
+// fixing up the relocation) stored scaled similarly.
+// Even if larger loads/stores have a larger range, limit the
+// effective offset to 12 bit, since it is intended to be a
+// page offset.
static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
- int Size = read32le(Off) >> 30;
- Imm >>= Size;
- applyArm64Imm(Off, Imm);
+ uint32_t Orig = read32le(Off);
+ uint32_t Size = Orig >> 30;
+ // 0x04000000 indicates SIMD/FP registers
+ // 0x00800000 indicates 128 bit
+ if ((Orig & 0x4800000) == 0x4800000)
+ Size += 4;
+ if ((Imm & ((1 << Size) - 1)) != 0)
+ fatal("misaligned ldr/str offset");
+ applyArm64Imm(Off, Imm >> Size, Size);
}
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 >> 12) - (P >> 12)); break;
- case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff); break;
+ case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P); 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_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;
default:
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
}
@@ -224,8 +251,19 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
// Get the output section of the symbol for this relocation. The output
// section is needed to compute SECREL and SECTION relocations used in debug
// info.
- SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
- Defined *Sym = cast<Defined>(Body);
+ auto *Sym =
+ dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
+ if (!Sym) {
+ if (isCodeView() || isDWARF())
+ continue;
+ // Symbols in early discarded sections are represented using null pointers,
+ // so we need to retrieve the name from the object file.
+ COFFSymbolRef Sym =
+ check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
+ StringRef Name;
+ File->getCOFFObj()->getSymbolName(Sym, Name);
+ fatal("relocation against symbol in discarded section: " + Name);
+ }
Chunk *C = Sym->getChunk();
OutputSection *OS = C ? C->getOutputSection() : nullptr;
@@ -301,8 +339,8 @@ void SectionChunk::getBaserels(std::vector<Baserel> *R
uint8_t Ty = getBaserelType(Rel);
if (Ty == IMAGE_REL_BASED_ABSOLUTE)
continue;
- SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
- if (isa<DefinedAbsolute>(Body))
+ Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);
+ if (!Target || isa<DefinedAbsolute>(Target))
continue;
Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
}
@@ -323,12 +361,8 @@ bool SectionChunk::isCOMDAT() const {
void SectionChunk::printDiscardedMessage() const {
// Removed by dead-stripping. If it's removed by ICF, ICF already
// printed out the name, so don't repeat that here.
- if (Sym && this == Repl) {
- if (Discarded)
- message("Discarded comdat symbol " + Sym->getName());
- else if (!Live)
- message("Discarded " + Sym->getName());
- }
+ if (Sym && this == Repl)
+ message("Discarded " + Sym->getName());
}
StringRef SectionChunk::getDebugName() {
@@ -351,7 +385,7 @@ void SectionChunk::replace(SectionChunk *Other) {
CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
// Common symbols are aligned on natural boundaries up to 32 bytes.
// This is what MSVC link.exe does.
- Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
+ Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
}
uint32_t CommonChunk::getPermissions() const {
@@ -366,7 +400,7 @@ void StringChunk::writeTo(uint8_t *Buf) const {
ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
// Intel Optimization Manual says that all branch targets
// should be 16-byte aligned. MSVC linker does this too.
- Align = 16;
+ Alignment = 16;
}
void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
@@ -397,10 +431,9 @@ void ImportThunkChunkARM::writeTo(uint8_t *Buf) const
}
void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
- int64_t PageOff = (ImpSymbol->getRVA() >> 12) - (RVA >> 12);
int64_t Off = ImpSymbol->getRVA() & 0xfff;
memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
- applyArm64Addr(Buf + OutputSectionOff, PageOff);
+ applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA);
applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
}
@@ -488,8 +521,10 @@ void BaserelChunk::writeTo(uint8_t *Buf) const {
uint8_t Baserel::getDefaultType() {
switch (Config->Machine) {
case AMD64:
+ case ARM64:
return IMAGE_REL_BASED_DIR64;
case I386:
+ case ARMNT:
return IMAGE_REL_BASED_HIGHLOW;
default:
llvm_unreachable("unknown machine type");
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.h
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.h Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/Chunks.h Wed Dec 20 15:50:21 2017 (r327026)
@@ -12,7 +12,7 @@
#include "Config.h"
#include "InputFiles.h"
-#include "lld/Core/LLVM.h"
+#include "lld/Common/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@@ -33,9 +33,9 @@ class Baserel;
class Defined;
class DefinedImportData;
class DefinedRegular;
-class ObjectFile;
+class ObjFile;
class OutputSection;
-class SymbolBody;
+class Symbol;
// Mask for section types (code, data, bss, disacardable, etc.)
// and permissions (writable, readable or executable).
@@ -62,7 +62,6 @@ class Chunk { (public)
// The writer sets and uses the addresses.
uint64_t getRVA() const { return RVA; }
- uint32_t getAlign() const { return Align; }
void setRVA(uint64_t V) { RVA = V; }
// Returns true if this has non-zero data. BSS chunks return
@@ -82,7 +81,7 @@ class Chunk { (public)
// An output section has pointers to chunks in the section, and each
// chunk has a back pointer to an output section.
void setOutputSection(OutputSection *O) { Out = O; }
- OutputSection *getOutputSection() { return Out; }
+ OutputSection *getOutputSection() const { return Out; }
// Windows-specific.
// Collect all locations that contain absolute addresses for base relocations.
@@ -92,23 +91,22 @@ class Chunk { (public)
// bytes, so this is used only for logging or debugging.
virtual StringRef getDebugName() { return ""; }
+ // The alignment of this chunk. The writer uses the value.
+ uint32_t Alignment = 1;
+
protected:
Chunk(Kind K = OtherKind) : ChunkKind(K) {}
const Kind ChunkKind;
- // The alignment of this chunk. The writer uses the value.
- uint32_t Align = 1;
-
// The RVA of this chunk in the output. The writer sets a value.
uint64_t RVA = 0;
+ // The output section for this chunk.
+ OutputSection *Out = nullptr;
+
public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
-
-protected:
- // The output section for this chunk.
- OutputSection *Out = nullptr;
};
// A chunk corresponding a section of an input file.
@@ -119,23 +117,21 @@ class SectionChunk final : public Chunk {
public:
class symbol_iterator : public llvm::iterator_adaptor_base<
symbol_iterator, const coff_relocation *,
- std::random_access_iterator_tag, SymbolBody *> {
+ std::random_access_iterator_tag, Symbol *> {
friend SectionChunk;
- ObjectFile *File;
+ ObjFile *File;
- symbol_iterator(ObjectFile *File, const coff_relocation *I)
+ symbol_iterator(ObjFile *File, const coff_relocation *I)
: symbol_iterator::iterator_adaptor_base(I), File(File) {}
public:
symbol_iterator() = default;
- SymbolBody *operator*() const {
- return File->getSymbolBody(I->SymbolTableIndex);
- }
+ Symbol *operator*() const { return File->getSymbol(I->SymbolTableIndex); }
};
- SectionChunk(ObjectFile *File, const coff_section *Header);
+ SectionChunk(ObjFile *File, const coff_section *Header);
static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
size_t getSize() const override { return Header->SizeOfRawData; }
ArrayRef<uint8_t> getContents() const;
@@ -163,10 +159,9 @@ class SectionChunk final : public Chunk {
void addAssociative(SectionChunk *Child);
StringRef getDebugName() override;
- void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }
- // Returns true if the chunk was not dropped by GC or COMDAT deduplication.
- bool isLive() { return Live && !Discarded; }
+ // Returns true if the chunk was not dropped by GC.
+ bool isLive() { return Live; }
// Used by the garbage collector.
void markLive() {
@@ -175,21 +170,16 @@ class SectionChunk final : public Chunk {
Live = true;
}
- // Returns true if this chunk was dropped by COMDAT deduplication.
- bool isDiscarded() const { return Discarded; }
-
- // Used by the SymbolTable when discarding unused comdat sections. This is
- // redundant when GC is enabled, as all comdat sections will start out dead.
- void markDiscarded() { Discarded = true; }
-
// True if this is a codeview debug info chunk. These will not be laid out in
// the image. Instead they will end up in the PDB, if one is requested.
bool isCodeView() const {
return SectionName == ".debug" || SectionName.startswith(".debug$");
}
- // True if this is a DWARF debug info chunk.
- bool isDWARF() const { return SectionName.startswith(".debug_"); }
+ // True if this is a DWARF debug info or exception handling chunk.
+ bool isDWARF() const {
+ return SectionName.startswith(".debug_") || SectionName == ".eh_frame";
+ }
// Allow iteration over the bodies of this chunk's relocated symbols.
llvm::iterator_range<symbol_iterator> symbols() const {
@@ -213,26 +203,23 @@ class SectionChunk final : public Chunk {
const coff_section *Header;
// The file that this chunk was created from.
- ObjectFile *File;
+ ObjFile *File;
+ // The COMDAT leader symbol if this is a COMDAT chunk.
+ DefinedRegular *Sym = nullptr;
+
private:
StringRef SectionName;
std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
size_t NumRelocs;
- // True if this chunk was discarded because it was a duplicate comdat section.
- bool Discarded;
-
// Used by the garbage collector.
bool Live;
// Used for ICF (Identical COMDAT Folding)
void replace(SectionChunk *Other);
uint32_t Class[2] = {0, 0};
-
- // Sym points to a section symbol if this is a COMDAT chunk.
- DefinedRegular *Sym = nullptr;
};
// A chunk for common symbols. Common chunks don't have actual data.
@@ -368,6 +355,9 @@ class Baserel { (public)
uint32_t RVA;
uint8_t Type;
};
+
+void applyMOV32T(uint8_t *Off, uint32_t V);
+void applyBranch24T(uint8_t *Off, int32_t V);
} // namespace coff
} // namespace lld
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/Config.h
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/Config.h Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/Config.h Wed Dec 20 15:50:21 2017 (r327026)
@@ -12,6 +12,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Support/CachePruning.h"
#include <cstdint>
#include <map>
#include <set>
@@ -26,8 +27,7 @@ using llvm::StringRef;
class DefinedAbsolute;
class DefinedRelative;
class StringChunk;
-struct Symbol;
-class SymbolBody;
+class Symbol;
// Short aliases.
static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
@@ -39,7 +39,7 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHIN
struct Export {
StringRef Name; // N in /export:N or /export:E=N
StringRef ExtName; // E in /export:E=N
- SymbolBody *Sym = nullptr;
+ Symbol *Sym = nullptr;
uint16_t Ordinal = 0;
bool Noname = false;
bool Data = false;
@@ -79,24 +79,23 @@ struct Configuration {
llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
- SymbolBody *Entry = nullptr;
+ Symbol *Entry = nullptr;
bool NoEntry = false;
std::string OutputFile;
std::string ImportName;
- bool ColorDiagnostics;
bool DoGC = true;
bool DoICF = true;
- uint64_t ErrorLimit = 20;
bool Relocatable = true;
bool Force = false;
bool Debug = false;
- bool WriteSymtab = true;
+ bool DebugDwarf = false;
+ bool DebugGHashes = false;
unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
llvm::SmallString<128> PDBPath;
std::vector<llvm::StringRef> Argv;
// Symbols in this set are considered as live by the garbage collector.
- std::set<SymbolBody *> GCRoot;
+ std::vector<Symbol *> GCRoot;
std::set<StringRef> NoDefaultLibs;
bool NoDefaultLibAll = false;
@@ -107,7 +106,7 @@ struct Configuration {
std::vector<Export> Exports;
std::set<std::string> DelayLoads;
std::map<std::string, int> DLLOrder;
- SymbolBody *DelayLoadHelper = nullptr;
+ Symbol *DelayLoadHelper = nullptr;
bool SaveTemps = false;
@@ -123,6 +122,11 @@ struct Configuration {
// Used for /opt:lldltopartitions=N
unsigned LTOPartitions = 1;
+ // Used for /opt:lldltocache=path
+ StringRef LTOCache;
+ // Used for /opt:lldltocachepolicy=policy
+ llvm::CachePruningPolicy LTOCachePolicy;
+
// Used for /merge:from=to (e.g. /merge:.rdata=.text)
std::map<StringRef, StringRef> Merge;
@@ -139,6 +143,9 @@ struct Configuration {
StringRef ManifestUIAccess = "'false'";
StringRef ManifestFile;
+ // Used for /aligncomm.
+ std::map<std::string, int> AlignComm;
+
// Used for /failifmismatch.
std::map<StringRef, StringRef> MustMatch;
@@ -157,13 +164,16 @@ struct Configuration {
uint32_t MinorImageVersion = 0;
uint32_t MajorOSVersion = 6;
uint32_t MinorOSVersion = 0;
+ bool CanExitEarly = false;
bool DynamicBase = true;
+ bool AllowBind = true;
bool NxCompat = true;
bool AllowIsolation = true;
bool TerminalServerAware = true;
bool LargeAddressAware = false;
bool HighEntropyVA = false;
bool AppContainer = false;
+ bool MinGW = false;
};
extern Configuration *Config;
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/DLL.cpp Wed Dec 20 15:50:21 2017 (r327026)
@@ -61,7 +61,7 @@ class HintNameChunk : public Chunk { (private)
// A chunk for the import descriptor table.
class LookupChunk : public Chunk {
public:
- explicit LookupChunk(Chunk *C) : HintName(C) {}
+ explicit LookupChunk(Chunk *C) : HintName(C) { Alignment = ptrSize(); }
size_t getSize() const override { return ptrSize(); }
void writeTo(uint8_t *Buf) const override {
@@ -76,7 +76,7 @@ class LookupChunk : public Chunk { (public)
// See Microsoft PE/COFF spec 7.1. Import Header for details.
class OrdinalOnlyChunk : public Chunk {
public:
- explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {}
+ explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) { Alignment = ptrSize(); }
size_t getSize() const override { return ptrSize(); }
void writeTo(uint8_t *Buf) const override {
@@ -117,7 +117,6 @@ class NullChunk : public Chunk { (public)
explicit NullChunk(size_t N) : Size(N) {}
bool hasData() const override { return false; }
size_t getSize() const override { return Size; }
- void setAlign(size_t N) { Align = N; }
private:
size_t Size;
@@ -215,6 +214,22 @@ static const uint8_t ThunkX86[] = {
0xFF, 0xE0, // jmp eax
};
+static const uint8_t ThunkARM[] = {
+ 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0 __imp_<FUNCNAME>
+ 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0 __imp_<FUNCNAME>
+ 0x2d, 0xe9, 0x0f, 0x48, // push.w {r0, r1, r2, r3, r11, lr}
+ 0x0d, 0xf2, 0x10, 0x0b, // addw r11, sp, #16
+ 0x2d, 0xed, 0x10, 0x0b, // vpush {d0, d1, d2, d3, d4, d5, d6, d7}
+ 0x61, 0x46, // mov r1, ip
+ 0x40, 0xf2, 0x00, 0x00, // mov.w r0, #0 DELAY_IMPORT_DESCRIPTOR
+ 0xc0, 0xf2, 0x00, 0x00, // mov.t r0, #0 DELAY_IMPORT_DESCRIPTOR
+ 0x00, 0xf0, 0x00, 0xd0, // bl #0 __delayLoadHelper2
+ 0x84, 0x46, // mov ip, r0
+ 0xbd, 0xec, 0x10, 0x0b, // vpop {d0, d1, d2, d3, d4, d5, d6, d7}
+ 0xbd, 0xe8, 0x0f, 0x48, // pop.w {r0, r1, r2, r3, r11, lr}
+ 0x60, 0x47, // bx ip
+};
+
// A chunk for the delay import thunk.
class ThunkChunkX64 : public Chunk {
public:
@@ -259,17 +274,45 @@ class ThunkChunkX86 : public Chunk { (public)
Defined *Helper = nullptr;
};
+class ThunkChunkARM : public Chunk {
+public:
+ ThunkChunkARM(Defined *I, Chunk *D, Defined *H)
+ : Imp(I), Desc(D), Helper(H) {}
+
+ size_t getSize() const override { return sizeof(ThunkARM); }
+
+ void writeTo(uint8_t *Buf) const override {
+ memcpy(Buf + OutputSectionOff, ThunkARM, sizeof(ThunkARM));
+ applyMOV32T(Buf + OutputSectionOff + 0, Imp->getRVA() + Config->ImageBase);
+ applyMOV32T(Buf + OutputSectionOff + 22, Desc->getRVA() + Config->ImageBase);
+ applyBranch24T(Buf + OutputSectionOff + 30, Helper->getRVA() - RVA - 34);
+ }
+
+ void getBaserels(std::vector<Baserel> *Res) override {
+ Res->emplace_back(RVA + 0, IMAGE_REL_BASED_ARM_MOV32T);
+ Res->emplace_back(RVA + 22, IMAGE_REL_BASED_ARM_MOV32T);
+ }
+
+ Defined *Imp = nullptr;
+ Chunk *Desc = nullptr;
+ Defined *Helper = nullptr;
+};
+
// A chunk for the import descriptor table.
class DelayAddressChunk : public Chunk {
public:
- explicit DelayAddressChunk(Chunk *C) : Thunk(C) {}
+ explicit DelayAddressChunk(Chunk *C) : Thunk(C) { Alignment = ptrSize(); }
size_t getSize() const override { return ptrSize(); }
void writeTo(uint8_t *Buf) const override {
if (Config->is64()) {
write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
} else {
- write32le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
+ uint32_t Bit = 0;
+ // Pointer to thumb code must have the LSB set, so adjust it.
+ if (Config->Machine == ARMNT)
+ Bit = 1;
+ write32le(Buf + OutputSectionOff, (Thunk->getRVA() + Config->ImageBase) | Bit);
}
}
@@ -319,12 +362,16 @@ class AddressTableChunk : public Chunk { (public)
size_t getSize() const override { return Size * 4; }
void writeTo(uint8_t *Buf) const override {
+ uint32_t Bit = 0;
+ // Pointer to thumb code must have the LSB set, so adjust it.
+ if (Config->Machine == ARMNT)
+ Bit = 1;
for (Export &E : Config->Exports) {
uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
if (E.ForwardChunk) {
- write32le(P, E.ForwardChunk->getRVA());
+ write32le(P, E.ForwardChunk->getRVA() | Bit);
} else {
- write32le(P, cast<Defined>(E.Sym)->getRVA());
+ write32le(P, cast<Defined>(E.Sym)->getRVA() | Bit);
}
}
}
@@ -487,7 +534,7 @@ void DelayLoadContents::create(Defined *H) {
for (int I = 0, E = Syms.size(); I < E; ++I)
Syms[I]->setLocation(Addresses[Base + I]);
auto *MH = make<NullChunk>(8);
- MH->setAlign(8);
+ MH->Alignment = 8;
ModuleHandles.push_back(MH);
// Fill the delay import table header fields.
@@ -506,6 +553,8 @@ Chunk *DelayLoadContents::newThunkChunk(DefinedImportD
return make<ThunkChunkX64>(S, Dir, Helper);
case I386:
return make<ThunkChunkX86>(S, Dir, Helper);
+ case ARMNT:
+ return make<ThunkChunkARM>(S, Dir, Helper);
default:
llvm_unreachable("unsupported machine type");
}
Modified: projects/clang600-import/contrib/llvm/tools/lld/COFF/Driver.cpp
==============================================================================
--- projects/clang600-import/contrib/llvm/tools/lld/COFF/Driver.cpp Wed Dec 20 15:21:29 2017 (r327025)
+++ projects/clang600-import/contrib/llvm/tools/lld/COFF/Driver.cpp Wed Dec 20 15:50:21 2017 (r327026)
@@ -9,13 +9,15 @@
#include "Driver.h"
#include "Config.h"
-#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
+#include "MinGW.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
-#include "lld/Driver/Driver.h"
+#include "lld/Common/Driver.h"
+#include "lld/Common/ErrorHandler.h"
+#include "lld/Common/Memory.h"
+#include "lld/Common/Version.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Magic.h"
@@ -48,20 +50,28 @@ namespace coff {
Configuration *Config;
LinkerDriver *Driver;
-BumpPtrAllocator BAlloc;
-StringSaver Saver{BAlloc};
-std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;
-
-bool link(ArrayRef<const char *> Args, raw_ostream &Diag) {
- ErrorCount = 0;
- ErrorOS = &Diag;
+bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {
+ errorHandler().LogName = 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)";
Config = make<Configuration>();
Config->Argv = {Args.begin(), Args.end()};
- Config->ColorDiagnostics =
- (ErrorOS == &llvm::errs() && Process::StandardErrHasColors());
+ Config->CanExitEarly = CanExitEarly;
+
+ Symtab = make<SymbolTable>();
+
Driver = make<LinkerDriver>();
Driver->link(Args);
- return !ErrorCount;
+
+ // Call exit() if we can to avoid calling destructors.
+ if (CanExitEarly)
+ exitLld(errorCount() ? 1 : 0);
+
+ freeArena();
+ return !errorCount();
}
// Drop directory components and replace extension with ".exe" or ".dll".
@@ -107,30 +117,46 @@ MemoryBufferRef LinkerDriver::takeBuffer(std::unique_p
return MBRef;
}
-void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB) {
+void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB,
+ bool WholeArchive) {
MemoryBufferRef MBRef = takeBuffer(std::move(MB));
+ FilePaths.push_back(MBRef.getBufferIdentifier());
// File type is detected by contents, not by file extension.
- file_magic Magic = identify_magic(MBRef.getBuffer());
- if (Magic == file_magic::windows_resource) {
+ switch (identify_magic(MBRef.getBuffer())) {
+ case file_magic::windows_resource:
Resources.push_back(MBRef);
- return;
- }
+ break;
- FilePaths.push_back(MBRef.getBufferIdentifier());
- if (Magic == file_magic::archive)
- return Symtab.addFile(make<ArchiveFile>(MBRef));
- if (Magic == file_magic::bitcode)
- return Symtab.addFile(make<BitcodeFile>(MBRef));
+ case file_magic::archive:
+ if (WholeArchive) {
+ std::unique_ptr<Archive> File =
+ CHECK(Archive::create(MBRef),
+ MBRef.getBufferIdentifier() + ": failed to parse archive");
- if (Magic == file_magic::coff_cl_gl_object)
+ for (MemoryBufferRef M : getArchiveMembers(File.get()))
+ addArchiveBuffer(M, "<whole-archive>", MBRef.getBufferIdentifier());
+ return;
+ }
+ Symtab->addFile(make<ArchiveFile>(MBRef));
+ break;
+
+ case file_magic::bitcode:
+ Symtab->addFile(make<BitcodeFile>(MBRef));
+ break;
+
+ case file_magic::coff_cl_gl_object:
error(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
"Recompile without /GL");
- else
- Symtab.addFile(make<ObjectFile>(MBRef));
+ break;
+
+ default:
+ Symtab->addFile(make<ObjFile>(MBRef));
+ break;
+ }
}
-void LinkerDriver::enqueuePath(StringRef Path) {
+void LinkerDriver::enqueuePath(StringRef Path, bool WholeArchive) {
auto Future =
std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path));
std::string PathStr = Path;
@@ -139,7 +165,7 @@ void LinkerDriver::enqueuePath(StringRef Path) {
if (MBOrErr.second)
error("could not open " + PathStr + ": " + MBOrErr.second.message());
else
- Driver->addBuffer(std::move(MBOrErr.first));
+ Driver->addBuffer(std::move(MBOrErr.first), WholeArchive);
});
}
@@ -147,13 +173,13 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB
StringRef ParentName) {
file_magic Magic = identify_magic(MB.getBuffer());
if (Magic == file_magic::coff_import_library) {
- Symtab.addFile(make<ImportFile>(MB));
+ Symtab->addFile(make<ImportFile>(MB));
return;
}
InputFile *Obj;
if (Magic == file_magic::coff_object) {
- Obj = make<ObjectFile>(MB);
+ Obj = make<ObjFile>(MB);
} else if (Magic == file_magic::bitcode) {
Obj = make<BitcodeFile>(MB);
} else {
@@ -162,7 +188,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB
}
Obj->ParentName = ParentName;
- Symtab.addFile(Obj);
+ Symtab->addFile(Obj);
log("Loaded " + toString(Obj) + " for " + SymName);
}
@@ -170,7 +196,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive:
StringRef SymName,
StringRef ParentName) {
if (!C.getParent()->isThin()) {
- MemoryBufferRef MB = check(
+ MemoryBufferRef MB = CHECK(
C.getMemoryBufferRef(),
"could not get the buffer for the member defining symbol " + SymName);
enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
@@ -178,39 +204,54 @@ void LinkerDriver::enqueueArchiveMember(const Archive:
}
auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
- check(C.getFullName(),
+ CHECK(C.getFullName(),
"could not get the filename for the member defining symbol " +
SymName)));
enqueueTask([=]() {
auto MBOrErr = Future->get();
if (MBOrErr.second)
- fatal(MBOrErr.second,
- "could not get the buffer for the member defining " + SymName);
+ fatal("could not get the buffer for the member defining " + SymName +
+ ": " + MBOrErr.second.message());
Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
ParentName);
});
}
static bool isDecorated(StringRef Sym) {
- return Sym.startswith("_") || Sym.startswith("@") || Sym.startswith("?");
+ return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") ||
+ (!Config->MinGW && Sym.contains('@'));
}
// Parses .drectve section contents and returns a list of files
// specified by /defaultlib.
void LinkerDriver::parseDirectives(StringRef S) {
+ ArgParser Parser;
+ // .drectve is always tokenized using Windows shell rules.
opt::InputArgList Args = Parser.parse(S);
for (auto *Arg : Args) {
- switch (Arg->getOption().getID()) {
+ switch (Arg->getOption().getUnaliasedOption().getID()) {
+ case OPT_aligncomm:
+ parseAligncomm(Arg->getValue());
+ break;
case OPT_alternatename:
parseAlternateName(Arg->getValue());
break;
case OPT_defaultlib:
if (Optional<StringRef> Path = findLib(Arg->getValue()))
- enqueuePath(*Path);
+ enqueuePath(*Path, false);
break;
+ case OPT_entry:
+ Config->Entry = addUndefined(mangle(Arg->getValue()));
+ break;
case OPT_export: {
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;
@@ -230,9 +271,14 @@ void LinkerDriver::parseDirectives(StringRef S) {
case OPT_section:
parseSection(Arg->getValue());
break;
+ case OPT_subsystem:
+ parseSubsystem(Arg->getValue(), &Config->Subsystem,
+ &Config->MajorOSVersion, &Config->MinorOSVersion);
+ break;
case OPT_editandcontinue:
case OPT_fastfail:
case OPT_guardsym:
+ case OPT_natvis:
case OPT_throwingnew:
break;
default:
@@ -247,7 +293,7 @@ StringRef LinkerDriver::doFindFile(StringRef Filename)
bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
if (HasPathSep)
return Filename;
- bool HasExt = (Filename.find('.') != StringRef::npos);
+ bool HasExt = Filename.contains('.');
for (StringRef Dir : SearchPaths) {
SmallString<128> Path = Dir;
sys::path::append(Path, Filename);
@@ -269,13 +315,15 @@ Optional<StringRef> LinkerDriver::findFile(StringRef F
bool Seen = !VisitedFiles.insert(Path.lower()).second;
if (Seen)
return None;
+ if (Path.endswith_lower(".lib"))
+ VisitedLibs.insert(sys::path::filename(Path));
return Path;
}
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list