svn commit: r311144 - in projects/clang400-import/contrib/llvm/tools/lld: . COFF ELF include/lld/Config include/lld/Core include/lld/Driver include/lld/ReaderWriter include/lld/Support lib/Config l...
Dimitry Andric
dim at FreeBSD.org
Mon Jan 2 21:32:54 UTC 2017
Author: dim
Date: Mon Jan 2 21:32:52 2017
New Revision: 311144
URL: https://svnweb.freebsd.org/changeset/base/311144
Log:
Update lld to trunk r290819 and resolve conflicts.
Added:
projects/clang400-import/contrib/llvm/tools/lld/COFF/Memory.h
- copied unchanged from r311143, vendor/lld/dist/COFF/Memory.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/PDB.h
- copied unchanged from r311143, vendor/lld/dist/COFF/PDB.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/Strings.cpp
- copied unchanged from r311143, vendor/lld/dist/COFF/Strings.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Strings.h
- copied unchanged from r311143, vendor/lld/dist/COFF/Strings.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/GdbIndex.cpp
- copied unchanged from r311143, vendor/lld/dist/ELF/GdbIndex.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/GdbIndex.h
- copied unchanged from r311143, vendor/lld/dist/ELF/GdbIndex.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Memory.h
- copied unchanged from r311143, vendor/lld/dist/ELF/Memory.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Mips.cpp
- copied unchanged from r311143, vendor/lld/dist/ELF/Mips.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
- copied unchanged from r311143, vendor/lld/dist/ELF/SyntheticSections.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/SyntheticSections.h
- copied unchanged from r311143, vendor/lld/dist/ELF/SyntheticSections.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Threads.h
- copied unchanged from r311143, vendor/lld/dist/ELF/Threads.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Reproduce.h
- copied unchanged from r311143, vendor/lld/dist/include/lld/Core/Reproduce.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Support/
- copied from r311143, vendor/lld/dist/include/lld/Support/
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/Reproduce.cpp
- copied unchanged from r311143, vendor/lld/dist/lib/Core/Reproduce.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/DebugInfo.h
- copied unchanged from r311143, vendor/lld/dist/lib/ReaderWriter/MachO/DebugInfo.h
projects/clang400-import/contrib/llvm/tools/lld/lib/Support/
- copied from r311143, vendor/lld/dist/lib/Support/
Deleted:
projects/clang400-import/contrib/llvm/tools/lld/ELF/SymbolListFile.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/SymbolListFile.h
Modified:
projects/clang400-import/contrib/llvm/tools/lld/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/Config.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/DLL.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Driver.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Driver.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/DriverUtils.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Error.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Error.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/ICF.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/InputFiles.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/InputFiles.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/Librarian.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/MarkLive.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/ModuleDef.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Options.td
projects/clang400-import/contrib/llvm/tools/lld/COFF/PDB.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/SymbolTable.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/SymbolTable.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/Symbols.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Symbols.h
projects/clang400-import/contrib/llvm/tools/lld/COFF/Writer.cpp
projects/clang400-import/contrib/llvm/tools/lld/COFF/Writer.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/ELF/Config.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Driver.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Driver.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/DriverUtils.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/EhFrame.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/EhFrame.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Error.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Error.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/ICF.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/InputFiles.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/InputFiles.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/InputSection.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/InputSection.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/LTO.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/LTO.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/LinkerScript.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/LinkerScript.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/MarkLive.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Options.td
projects/clang400-import/contrib/llvm/tools/lld/ELF/OutputSections.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/OutputSections.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Relocations.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Relocations.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/ScriptParser.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/ScriptParser.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Strings.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Strings.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/SymbolTable.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/SymbolTable.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Symbols.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Symbols.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Target.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Target.h
projects/clang400-import/contrib/llvm/tools/lld/ELF/Thunks.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Writer.cpp
projects/clang400-import/contrib/llvm/tools/lld/ELF/Writer.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Config/Version.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Config/Version.inc.in
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Atom.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/DefinedAtom.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/LinkingContext.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Node.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Parallel.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Pass.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/PassManager.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Reader.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Reference.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/Simple.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Core/SymbolTable.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/Driver/Driver.h
projects/clang400-import/contrib/llvm/tools/lld/include/lld/ReaderWriter/MachOLinkingContext.h
projects/clang400-import/contrib/llvm/tools/lld/lib/Config/Version.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/DefinedAtom.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/Error.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/File.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/LinkingContext.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/Reader.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/Resolver.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/SymbolTable.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Core/Writer.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/Driver/DarwinLdDriver.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/FileArchive.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/File.h
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/GOTPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/LayoutPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ObjCPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ShimPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/StubsPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/MachO/TLVPass.cpp
projects/clang400-import/contrib/llvm/tools/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
projects/clang400-import/contrib/llvm/tools/lld/tools/lld/CMakeLists.txt
projects/clang400-import/contrib/llvm/tools/lld/tools/lld/lld.cpp
Directory Properties:
projects/clang400-import/contrib/llvm/tools/lld/ (props changed)
Modified: projects/clang400-import/contrib/llvm/tools/lld/CMakeLists.txt
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/CMakeLists.txt Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/CMakeLists.txt Mon Jan 2 21:32:52 2017 (r311144)
@@ -1,3 +1,54 @@
+# Check if lld is built as a standalone project.
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+ project(lld)
+ cmake_minimum_required(VERSION 3.4.3)
+
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+ set(LLD_BUILT_STANDALONE TRUE)
+
+ find_program(LLVM_CONFIG_PATH "llvm-config" DOC "Path to llvm-config binary")
+ if(NOT LLVM_CONFIG_PATH)
+ message(FATAL_ERROR "llvm-config not found: specify LLVM_CONFIG_PATH")
+ endif()
+
+ execute_process(COMMAND "${LLVM_CONFIG_PATH}" "--obj-root" "--includedir"
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE LLVM_CONFIG_OUTPUT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(HAD_ERROR)
+ message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
+ endif()
+
+ string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" LLVM_CONFIG_OUTPUT "${LLVM_CONFIG_OUTPUT}")
+
+ list(GET LLVM_CONFIG_OUTPUT 0 OBJ_ROOT)
+ list(GET LLVM_CONFIG_OUTPUT 1 MAIN_INCLUDE_DIR)
+
+ set(LLVM_OBJ_ROOT ${OBJ_ROOT} CACHE PATH "path to LLVM build tree")
+ set(LLVM_MAIN_INCLUDE_DIR ${MAIN_INCLUDE_DIR} CACHE PATH "path to llvm/include")
+
+ file(TO_CMAKE_PATH ${LLVM_OBJ_ROOT} LLVM_BINARY_DIR)
+ set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
+
+ if(NOT EXISTS "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
+ message(FATAL_ERROR "LLVMConfig.cmake not found")
+ endif()
+ include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
+
+ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
+
+ set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
+ include_directories("${LLVM_BINARY_DIR}/include" ${LLVM_INCLUDE_DIRS})
+ link_directories(${LLVM_LIBRARY_DIRS})
+
+ set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
+ find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
+
+ include(AddLLVM)
+ include(TableGen)
+ include(HandleLLVMOptions)
+endif()
+
set(LLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LLD_INCLUDE_DIR ${LLD_SOURCE_DIR}/include )
set(LLD_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -55,6 +106,8 @@ endif()
list (APPEND CMAKE_MODULE_PATH "${LLD_SOURCE_DIR}/cmake/modules")
+include(AddLLD)
+
option(LLD_USE_VTUNE
"Enable VTune user task tracking."
OFF)
@@ -67,6 +120,8 @@ if (LLD_USE_VTUNE)
endif()
endif()
+option(LLD_BUILD_TOOLS
+ "Build the lld tools. If OFF, just generate build targets." ON)
if (MSVC)
add_definitions(-wd4530) # Suppress 'warning C4530: C++ exception handler used, but unwind semantics are not enabled.'
@@ -87,12 +142,6 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
)
endif()
-macro(add_lld_library name)
- add_llvm_library(${name} ${ARGN})
- set_target_properties(${name} PROPERTIES FOLDER "lld libraries")
-endmacro(add_lld_library)
-
-
add_subdirectory(lib)
add_subdirectory(tools/lld)
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/CMakeLists.txt Mon Jan 2 21:32:52 2017 (r311144)
@@ -2,6 +2,10 @@ set(LLVM_TARGET_DEFINITIONS Options.td)
tablegen(LLVM Options.inc -gen-opt-parser-defs)
add_public_tablegen_target(COFFOptionsTableGen)
+if(NOT LLD_BUILT_STANDALONE)
+ set(tablegen_deps intrinsics_gen)
+endif()
+
add_lld_library(lldCOFF
Chunks.cpp
DLL.cpp
@@ -14,6 +18,7 @@ add_lld_library(lldCOFF
MarkLive.cpp
ModuleDef.cpp
PDB.cpp
+ Strings.cpp
SymbolTable.cpp
Symbols.cpp
Writer.cpp
@@ -21,6 +26,9 @@ add_lld_library(lldCOFF
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Core
+ DebugInfoCodeView
+ DebugInfoMSF
+ DebugInfoPDB
LTO
LibDriver
Object
@@ -30,7 +38,11 @@ add_lld_library(lldCOFF
Option
Support
- LINK_LIBS ${PTHREAD_LIB}
- )
+ LINK_LIBS
+ lldCore
+ ${PTHREAD_LIB}
-add_dependencies(lldCOFF COFFOptionsTableGen intrinsics_gen)
+ DEPENDS
+ COFFOptionsTableGen
+ ${tablegen_deps}
+ )
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.cpp
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.cpp Mon Jan 2 21:32:52 2017 (r311144)
@@ -28,7 +28,7 @@ namespace lld {
namespace coff {
SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
- : Chunk(SectionKind), Repl(this), File(F), Header(H),
+ : Chunk(SectionKind), Repl(this), Header(H), File(F),
Relocs(File->getCOFFObj()->getRelocations(Header)),
NumRelocs(std::distance(Relocs.begin(), Relocs.end())) {
// Initialize SectionName.
@@ -81,11 +81,23 @@ void SectionChunk::applyRelX86(uint8_t *
}
static void applyMOV(uint8_t *Off, uint16_t V) {
- or16(Off, ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
- or16(Off + 2, ((V & 0x700) << 4) | (V & 0xff));
+ write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
+ write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
+}
+
+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;
}
static 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);
+ V += Imm; // add the immediate offset
applyMOV(Off, V); // set MOVW operand
applyMOV(Off + 4, V >> 16); // set MOVT operand
}
@@ -99,11 +111,14 @@ static void applyBranch20T(uint8_t *Off,
}
static void applyBranch24T(uint8_t *Off, int32_t V) {
+ if (!isInt<25>(V))
+ fatal("relocation out of range");
uint32_t S = V < 0 ? 1 : 0;
uint32_t J1 = ((~V >> 23) & 1) ^ S;
uint32_t J2 = ((~V >> 22) & 1) ^ S;
or16(Off, (S << 10) | ((V >> 12) & 0x3ff));
- or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
+ // Clear out the J1 and J2 bits which may be set.
+ write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
}
void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
@@ -119,6 +134,7 @@ void SectionChunk::applyRelARM(uint8_t *
case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, S - P - 4); break;
case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, S - P - 4); break;
case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, S - P - 4); break;
+ case IMAGE_REL_ARM_SECREL: add32(Off, Sym->getSecrel()); break;
default:
fatal("unsupported relocation type");
}
@@ -134,7 +150,7 @@ void SectionChunk::writeTo(uint8_t *Buf)
// Apply relocations.
for (const coff_relocation &Rel : Relocs) {
uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
- SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
+ SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
Defined *Sym = cast<Defined>(Body);
uint64_t P = RVA + Rel.VirtualAddress;
switch (Config->Machine) {
@@ -187,7 +203,7 @@ void SectionChunk::getBaserels(std::vect
uint8_t Ty = getBaserelType(Rel);
if (Ty == IMAGE_REL_BASED_ABSOLUTE)
continue;
- SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
+ SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
if (isa<DefinedAbsolute>(Body))
continue;
Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
@@ -210,7 +226,7 @@ void SectionChunk::printDiscardedMessage
// 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)
- llvm::outs() << "Discarded " << Sym->getName() << "\n";
+ outs() << "Discarded " << Sym->getName() << "\n";
}
StringRef SectionChunk::getDebugName() {
@@ -233,7 +249,7 @@ void SectionChunk::replace(SectionChunk
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), NextPowerOf2(Sym.getValue()));
+ Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
}
uint32_t CommonChunk::getPermissions() const {
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.h
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.h Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/Chunks.h Mon Jan 2 21:32:52 2017 (r311144)
@@ -17,7 +17,6 @@
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/COFF.h"
-#include <atomic>
#include <utility>
#include <vector>
@@ -29,7 +28,6 @@ using llvm::object::COFFSymbolRef;
using llvm::object::SectionRef;
using llvm::object::coff_relocation;
using llvm::object::coff_section;
-using llvm::sys::fs::file_magic;
class Baserel;
class Defined;
@@ -187,11 +185,12 @@ public:
// Auxiliary Format 5: Section Definitions. Used for ICF.
uint32_t Checksum = 0;
+ const coff_section *Header;
+
private:
// A file this chunk was created from.
ObjectFile *File;
- const coff_section *Header;
StringRef SectionName;
std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
@@ -202,7 +201,7 @@ private:
// Used for ICF (Identical COMDAT Folding)
void replace(SectionChunk *Other);
- std::atomic<uint64_t> GroupID = { 0 };
+ uint32_t Color[2] = {0, 0};
// Sym points to a section symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/Config.h
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/Config.h Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/Config.h Mon Jan 2 21:32:52 2017 (r311144)
@@ -26,7 +26,8 @@ using llvm::StringRef;
class DefinedAbsolute;
class DefinedRelative;
class StringChunk;
-class Undefined;
+struct Symbol;
+class SymbolBody;
// Short aliases.
static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
@@ -37,7 +38,7 @@ static const auto I386 = llvm::COFF::IMA
struct Export {
StringRef Name; // N in /export:N or /export:E=N
StringRef ExtName; // E in /export:E=N
- Undefined *Sym = nullptr;
+ SymbolBody *Sym = nullptr;
uint16_t Ordinal = 0;
bool Noname = false;
bool Data = false;
@@ -61,6 +62,13 @@ struct Export {
}
};
+enum class DebugType {
+ None = 0x0,
+ CV = 0x1, /// CodeView
+ PData = 0x2, /// Procedure Data
+ Fixup = 0x4, /// Relocation Table
+};
+
// Global configuration.
struct Configuration {
enum ManifestKind { SideBySide, Embed, No };
@@ -69,7 +77,7 @@ struct Configuration {
llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
bool Verbose = false;
WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
- Undefined *Entry = nullptr;
+ SymbolBody *Entry = nullptr;
bool NoEntry = false;
std::string OutputFile;
bool DoGC = true;
@@ -78,9 +86,11 @@ struct Configuration {
bool Force = false;
bool Debug = false;
bool WriteSymtab = true;
+ unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
+ StringRef PDBPath;
// Symbols in this set are considered as live by the garbage collector.
- std::set<Undefined *> GCRoot;
+ std::set<SymbolBody *> GCRoot;
std::set<StringRef> NoDefaultLibs;
bool NoDefaultLibAll = false;
@@ -91,11 +101,11 @@ struct Configuration {
std::vector<Export> Exports;
std::set<std::string> DelayLoads;
std::map<std::string, int> DLLOrder;
- Undefined *DelayLoadHelper = nullptr;
+ SymbolBody *DelayLoadHelper = nullptr;
// Used for SafeSEH.
- DefinedRelative *SEHTable = nullptr;
- DefinedAbsolute *SEHCount = nullptr;
+ Symbol *SEHTable = nullptr;
+ Symbol *SEHCount = nullptr;
// Used for /opt:lldlto=N
unsigned LTOOptLevel = 2;
@@ -141,6 +151,10 @@ struct Configuration {
bool TerminalServerAware = true;
bool LargeAddressAware = false;
bool HighEntropyVA = false;
+
+ // This is for debugging.
+ bool DebugPdb = false;
+ bool DumpPdb = false;
};
extern Configuration *Config;
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/DLL.cpp
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/DLL.cpp Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/DLL.cpp Mon Jan 2 21:32:52 2017 (r311144)
@@ -324,7 +324,7 @@ public:
if (E.ForwardChunk) {
write32le(P, E.ForwardChunk->getRVA());
} else {
- write32le(P, cast<Defined>(E.Sym->repl())->getRVA());
+ write32le(P, cast<Defined>(E.Sym)->getRVA());
}
}
}
Modified: projects/clang400-import/contrib/llvm/tools/lld/COFF/Driver.cpp
==============================================================================
--- projects/clang400-import/contrib/llvm/tools/lld/COFF/Driver.cpp Mon Jan 2 21:29:30 2017 (r311143)
+++ projects/clang400-import/contrib/llvm/tools/lld/COFF/Driver.cpp Mon Jan 2 21:32:52 2017 (r311144)
@@ -7,15 +7,17 @@
//
//===----------------------------------------------------------------------===//
-#include "Config.h"
#include "Driver.h"
+#include "Config.h"
#include "Error.h"
#include "InputFiles.h"
+#include "Memory.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
#include "lld/Driver/Driver.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/LibDriver/LibDriver.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -28,6 +30,13 @@
#include <algorithm>
#include <memory>
+#ifdef _MSC_VER
+// <future> depends on <eh.h> for __uncaught_exception.
+#include <eh.h>
+#endif
+
+#include <future>
+
using namespace llvm;
using namespace llvm::COFF;
using llvm::sys::Process;
@@ -41,11 +50,13 @@ namespace coff {
Configuration *Config;
LinkerDriver *Driver;
-bool link(llvm::ArrayRef<const char *> Args) {
- Configuration C;
- LinkerDriver D;
- Config = &C;
- Driver = &D;
+BumpPtrAllocator BAlloc;
+StringSaver Saver{BAlloc};
+std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;
+
+bool link(ArrayRef<const char *> Args) {
+ Config = make<Configuration>();
+ Driver = make<LinkerDriver>();
Driver->link(Args);
return true;
}
@@ -58,26 +69,123 @@ static std::string getOutputPath(StringR
return (S.substr(0, S.rfind('.')) + E).str();
}
-// Opens a file. Path has to be resolved already.
-// Newly created memory buffers are owned by this driver.
-MemoryBufferRef LinkerDriver::openFile(StringRef Path) {
- std::unique_ptr<MemoryBuffer> MB =
- check(MemoryBuffer::getFile(Path), "could not open " + Path);
- MemoryBufferRef MBRef = MB->getMemBufferRef();
- OwningMBs.push_back(std::move(MB)); // take ownership
+// ErrorOr is not default constructible, so it cannot be used as the type
+// parameter of a future.
+// FIXME: We could open the file in createFutureForFile and avoid needing to
+// return an error here, but for the moment that would cost us a file descriptor
+// (a limited resource on Windows) for the duration that the future is pending.
+typedef std::pair<std::unique_ptr<MemoryBuffer>, std::error_code> MBErrPair;
+
+// 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
+ // On Windows, file I/O is relatively slow so it is best to do this
+ // asynchronously.
+ auto Strategy = std::launch::async;
+#else
+ auto Strategy = std::launch::deferred;
+#endif
+ return std::async(Strategy, [=]() {
+ auto MBOrErr = MemoryBuffer::getFile(Path);
+ if (!MBOrErr)
+ return MBErrPair{nullptr, MBOrErr.getError()};
+ return MBErrPair{std::move(*MBOrErr), std::error_code()};
+ });
+}
+
+MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
+ MemoryBufferRef MBRef = *MB;
+ OwningMBs.push_back(std::move(MB));
+
+ if (Driver->Cpio)
+ Driver->Cpio->append(relativeToRoot(MBRef.getBufferIdentifier()),
+ MBRef.getBuffer());
+
return MBRef;
}
-static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
+void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB) {
+ MemoryBufferRef MBRef = takeBuffer(std::move(MB));
+
// File type is detected by contents, not by file extension.
- file_magic Magic = identify_magic(MB.getBuffer());
+ file_magic Magic = identify_magic(MBRef.getBuffer());
+ if (Magic == file_magic::windows_resource) {
+ Resources.push_back(MBRef);
+ return;
+ }
+
+ FilePaths.push_back(MBRef.getBufferIdentifier());
if (Magic == file_magic::archive)
- return std::unique_ptr<InputFile>(new ArchiveFile(MB));
+ return Symtab.addFile(make<ArchiveFile>(MBRef));
if (Magic == file_magic::bitcode)
- return std::unique_ptr<InputFile>(new BitcodeFile(MB));
+ return Symtab.addFile(make<BitcodeFile>(MBRef));
+ if (Magic == file_magic::coff_cl_gl_object)
+ fatal(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
+ "Recompile without /GL");
+ Symtab.addFile(make<ObjectFile>(MBRef));
+}
+
+void LinkerDriver::enqueuePath(StringRef Path) {
+ auto Future =
+ std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path));
+ std::string PathStr = Path;
+ enqueueTask([=]() {
+ auto MBOrErr = Future->get();
+ if (MBOrErr.second)
+ fatal(MBOrErr.second, "could not open " + PathStr);
+ Driver->addBuffer(std::move(MBOrErr.first));
+ });
+
if (Config->OutputFile == "")
- Config->OutputFile = getOutputPath(MB.getBufferIdentifier());
- return std::unique_ptr<InputFile>(new ObjectFile(MB));
+ Config->OutputFile = getOutputPath(Path);
+}
+
+void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
+ StringRef ParentName) {
+ file_magic Magic = identify_magic(MB.getBuffer());
+ if (Magic == file_magic::coff_import_library) {
+ Symtab.addFile(make<ImportFile>(MB));
+ return;
+ }
+
+ InputFile *Obj;
+ if (Magic == file_magic::coff_object)
+ Obj = make<ObjectFile>(MB);
+ else if (Magic == file_magic::bitcode)
+ Obj = make<BitcodeFile>(MB);
+ else
+ fatal("unknown file type: " + MB.getBufferIdentifier());
+
+ Obj->ParentName = ParentName;
+ Symtab.addFile(Obj);
+ if (Config->Verbose)
+ outs() << "Loaded " << toString(Obj) << " for " << SymName << "\n";
+}
+
+void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
+ StringRef SymName,
+ StringRef ParentName) {
+ if (!C.getParent()->isThin()) {
+ MemoryBufferRef MB = check(
+ C.getMemoryBufferRef(),
+ "could not get the buffer for the member defining symbol " + SymName);
+ enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
+ return;
+ }
+
+ auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
+ 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);
+ Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
+ ParentName);
+ });
}
static bool isDecorated(StringRef Sym) {
@@ -87,7 +195,7 @@ static bool isDecorated(StringRef Sym) {
// Parses .drectve section contents and returns a list of files
// specified by /defaultlib.
void LinkerDriver::parseDirectives(StringRef S) {
- llvm::opt::InputArgList Args = Parser.parse(S);
+ opt::InputArgList Args = Parser.parse(S);
for (auto *Arg : Args) {
switch (Arg->getOption().getID()) {
@@ -95,10 +203,8 @@ void LinkerDriver::parseDirectives(Strin
parseAlternateName(Arg->getValue());
break;
case OPT_defaultlib:
- if (Optional<StringRef> Path = findLib(Arg->getValue())) {
- MemoryBufferRef MB = openFile(*Path);
- Symtab.addFile(createFile(MB));
- }
+ if (Optional<StringRef> Path = findLib(Arg->getValue()))
+ enqueuePath(*Path);
break;
case OPT_export: {
Export E = parseExport(Arg->getValue());
@@ -135,19 +241,19 @@ void LinkerDriver::parseDirectives(Strin
// Find file from search paths. You can omit ".obj", this function takes
// care of that. Note that the returned path is not guaranteed to exist.
StringRef LinkerDriver::doFindFile(StringRef Filename) {
- bool hasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
- if (hasPathSep)
+ bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
+ if (HasPathSep)
return Filename;
- bool hasExt = (Filename.find('.') != StringRef::npos);
+ bool HasExt = (Filename.find('.') != StringRef::npos);
for (StringRef Dir : SearchPaths) {
SmallString<128> Path = Dir;
- llvm::sys::path::append(Path, Filename);
- if (llvm::sys::fs::exists(Path.str()))
- return Alloc.save(Path.str());
- if (!hasExt) {
+ sys::path::append(Path, Filename);
+ if (sys::fs::exists(Path.str()))
+ return Saver.save(Path.str());
+ if (!HasExt) {
Path.append(".obj");
- if (llvm::sys::fs::exists(Path.str()))
- return Alloc.save(Path.str());
+ if (sys::fs::exists(Path.str()))
+ return Saver.save(Path.str());
}
}
return Filename;
@@ -166,9 +272,9 @@ Optional<StringRef> LinkerDriver::findFi
// Find library file from search path.
StringRef LinkerDriver::doFindLib(StringRef Filename) {
// Add ".lib" to Filename if that has no file extension.
- bool hasExt = (Filename.find('.') != StringRef::npos);
- if (!hasExt)
- Filename = Alloc.save(Filename + ".lib");
+ bool HasExt = (Filename.find('.') != StringRef::npos);
+ if (!HasExt)
+ Filename = Saver.save(Filename + ".lib");
return doFindFile(Filename);
}
@@ -178,11 +284,12 @@ StringRef LinkerDriver::doFindLib(String
Optional<StringRef> LinkerDriver::findLib(StringRef Filename) {
if (Config->NoDefaultLibAll)
return None;
+ if (!VisitedLibs.insert(Filename.lower()).second)
+ return None;
StringRef Path = doFindLib(Filename);
if (Config->NoDefaultLibs.count(Path))
return None;
- bool Seen = !VisitedFiles.insert(Path.lower()).second;
- if (Seen)
+ if (!VisitedFiles.insert(Path.lower()).second)
return None;
return Path;
}
@@ -192,7 +299,7 @@ void LinkerDriver::addLibSearchPaths() {
Optional<std::string> EnvOpt = Process::GetEnv("LIB");
if (!EnvOpt.hasValue())
return;
- StringRef Env = Alloc.save(*EnvOpt);
+ StringRef Env = Saver.save(*EnvOpt);
while (!Env.empty()) {
StringRef Path;
std::tie(Path, Env) = Env.split(';');
@@ -200,17 +307,17 @@ void LinkerDriver::addLibSearchPaths() {
}
}
-Undefined *LinkerDriver::addUndefined(StringRef Name) {
- Undefined *U = Symtab.addUndefined(Name);
- Config->GCRoot.insert(U);
- return U;
+SymbolBody *LinkerDriver::addUndefined(StringRef Name) {
+ SymbolBody *B = Symtab.addUndefined(Name);
+ Config->GCRoot.insert(B);
+ return B;
}
// Symbol names are mangled by appending "_" prefix on x86.
StringRef LinkerDriver::mangle(StringRef Sym) {
assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN);
if (Config->Machine == I386)
- return Alloc.save("_" + Sym);
+ return Saver.save("_" + Sym);
return Sym;
}
@@ -225,7 +332,7 @@ StringRef LinkerDriver::findDefaultEntry
};
for (auto E : Entries) {
StringRef Entry = Symtab.findMangle(mangle(E[0]));
- if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->Body))
+ if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->body()))
return mangle(E[1]);
}
return "";
@@ -247,7 +354,83 @@ static uint64_t getDefaultImageBase() {
return Config->DLL ? 0x10000000 : 0x400000;
}
-void LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
+static std::string createResponseFile(const opt::InputArgList &Args,
+ ArrayRef<StringRef> FilePaths,
+ ArrayRef<StringRef> SearchPaths) {
+ SmallString<0> Data;
+ raw_svector_ostream OS(Data);
+
+ for (auto *Arg : Args) {
+ switch (Arg->getOption().getID()) {
+ case OPT_linkrepro:
+ case OPT_INPUT:
+ case OPT_defaultlib:
+ case OPT_libpath:
+ break;
+ default:
+ OS << stringize(Arg) << "\n";
+ }
+ }
+
+ for (StringRef Path : SearchPaths) {
+ std::string RelPath = relativeToRoot(Path);
+ OS << "/libpath:" << quote(RelPath) << "\n";
+ }
+
+ for (StringRef Path : FilePaths)
+ OS << quote(relativeToRoot(Path)) << "\n";
+
+ return Data.str();
+}
+
+static unsigned getDefaultDebugType(const opt::InputArgList &Args) {
+ unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);
+ if (Args.hasArg(OPT_driver))
+ DebugTypes |= static_cast<unsigned>(DebugType::PData);
+ if (Args.hasArg(OPT_profile))
+ DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
+ return DebugTypes;
+}
+
+static unsigned parseDebugType(StringRef Arg) {
+ SmallVector<StringRef, 3> Types;
+ Arg.split(Types, ',', /*KeepEmpty=*/false);
+
+ unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
+ for (StringRef Type : Types)
+ DebugTypes |= StringSwitch<unsigned>(Type.lower())
+ .Case("cv", static_cast<unsigned>(DebugType::CV))
+ .Case("pdata", static_cast<unsigned>(DebugType::PData))
+ .Case("fixup", static_cast<unsigned>(DebugType::Fixup));
+ return DebugTypes;
+}
+
+static std::string getMapFile(const opt::InputArgList &Args) {
+ auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file);
+ if (!Arg)
+ return "";
+ if (Arg->getOption().getID() == OPT_lldmap_file)
+ return Arg->getValue();
+
+ assert(Arg->getOption().getID() == OPT_lldmap);
+ StringRef OutFile = Config->OutputFile;
+ return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
+}
+
+void LinkerDriver::enqueueTask(std::function<void()> Task) {
+ TaskQueue.push_back(std::move(Task));
+}
+
+bool LinkerDriver::run() {
+ bool DidWork = !TaskQueue.empty();
+ while (!TaskQueue.empty()) {
+ TaskQueue.front()();
+ TaskQueue.pop_front();
+ }
+ return DidWork;
+}
+
+void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// If the first command line argument is "/lib", link.exe acts like lib.exe.
// We call our own implementation of lib.exe that understands bitcode files.
if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) {
@@ -257,15 +440,15 @@ void LinkerDriver::link(llvm::ArrayRef<c
}
// Needed for LTO.
- llvm::InitializeAllTargetInfos();
- llvm::InitializeAllTargets();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllAsmPrinters();
- llvm::InitializeAllDisassemblers();
+ InitializeAllTargetInfos();
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmParsers();
+ InitializeAllAsmPrinters();
+ InitializeAllDisassemblers();
// Parse command line options.
- llvm::opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1));
+ opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1));
// Handle /help
if (Args.hasArg(OPT_help)) {
@@ -273,6 +456,17 @@ void LinkerDriver::link(llvm::ArrayRef<c
return;
}
+ if (auto *Arg = Args.getLastArg(OPT_linkrepro)) {
+ SmallString<64> Path = StringRef(Arg->getValue());
+ sys::path::append(Path, "repro");
+ ErrorOr<CpioFile *> F = CpioFile::create(Path);
+ if (F)
+ Cpio.reset(*F);
+ else
+ errs() << "/linkrepro: failed to open " << Path
+ << ".cpio: " << F.getError().message() << '\n';
+ }
+
if (Args.filtered_begin(OPT_INPUT) == Args.filtered_end())
fatal("no input files");
@@ -295,8 +489,17 @@ void LinkerDriver::link(llvm::ArrayRef<c
Config->Force = true;
// Handle /debug
- if (Args.hasArg(OPT_debug))
+ if (Args.hasArg(OPT_debug)) {
Config->Debug = true;
+ Config->DebugTypes =
+ Args.hasArg(OPT_debugtype)
+ ? parseDebugType(Args.getLastArg(OPT_debugtype)->getValue())
+ : getDefaultDebugType(Args);
+ }
+
+ // Create a dummy PDB file to satisfy build sytem rules.
+ if (auto *Arg = Args.getLastArg(OPT_pdb))
+ Config->PDBPath = Arg->getValue();
// Handle /noentry
if (Args.hasArg(OPT_noentry)) {
@@ -447,72 +650,43 @@ void LinkerDriver::link(llvm::ArrayRef<c
Config->TerminalServerAware = false;
if (Args.hasArg(OPT_nosymtab))
Config->WriteSymtab = false;
+ Config->DumpPdb = Args.hasArg(OPT_dumppdb);
+ Config->DebugPdb = Args.hasArg(OPT_debugpdb);
// Create a list of input files. Files can be given as arguments
// for /defaultlib option.
- std::vector<StringRef> Paths;
std::vector<MemoryBufferRef> MBs;
for (auto *Arg : Args.filtered(OPT_INPUT))
if (Optional<StringRef> Path = findFile(Arg->getValue()))
- Paths.push_back(*Path);
+ enqueuePath(*Path);
for (auto *Arg : Args.filtered(OPT_defaultlib))
if (Optional<StringRef> Path = findLib(Arg->getValue()))
- Paths.push_back(*Path);
- for (StringRef Path : Paths)
- MBs.push_back(openFile(Path));
+ enqueuePath(*Path);
// Windows specific -- Create a resource file containing a manifest file.
- if (Config->Manifest == Configuration::Embed) {
- std::unique_ptr<MemoryBuffer> MB = createManifestRes();
- MBs.push_back(MB->getMemBufferRef());
- OwningMBs.push_back(std::move(MB)); // take ownership
+ if (Config->Manifest == Configuration::Embed)
+ addBuffer(createManifestRes());
+
+ // Read all input files given via the command line.
+ run();
+
+ // We should have inferred a machine type by now from the input files, but if
+ // not we assume x64.
+ if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
+ errs() << "warning: /machine is not specified. x64 is assumed.\n";
+ Config->Machine = AMD64;
}
// Windows specific -- Input files can be Windows resource files (.res files).
// We invoke cvtres.exe to convert resource files to a regular COFF file
// then link the result file normally.
- std::vector<MemoryBufferRef> Resources;
- auto NotResource = [](MemoryBufferRef MB) {
- return identify_magic(MB.getBuffer()) != file_magic::windows_resource;
- };
- auto It = std::stable_partition(MBs.begin(), MBs.end(), NotResource);
- if (It != MBs.end()) {
- Resources.insert(Resources.end(), It, MBs.end());
- MBs.erase(It, MBs.end());
- }
-
- // Read all input files given via the command line. Note that step()
- // doesn't read files that are specified by directive sections.
- for (MemoryBufferRef MB : MBs)
- Symtab.addFile(createFile(MB));
- Symtab.step();
-
- // Determine machine type and check if all object files are
- // for the same CPU type. Note that this needs to be done before
- // any call to mangle().
- for (std::unique_ptr<InputFile> &File : Symtab.getFiles()) {
- MachineTypes MT = File->getMachineType();
- if (MT == IMAGE_FILE_MACHINE_UNKNOWN)
- continue;
- if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
- Config->Machine = MT;
- continue;
- }
- if (Config->Machine != MT)
- fatal(File->getShortName() + ": machine type " + machineToStr(MT) +
- " conflicts with " + machineToStr(Config->Machine));
- }
- if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
- llvm::errs() << "warning: /machine is not specified. x64 is assumed.\n";
- Config->Machine = AMD64;
- }
+ if (!Resources.empty())
+ addBuffer(convertResToCOFF(Resources));
- // Windows specific -- Convert Windows resource files to a COFF file.
- if (!Resources.empty()) {
- std::unique_ptr<MemoryBuffer> MB = convertResToCOFF(Resources);
- Symtab.addFile(createFile(MB->getMemBufferRef()));
- OwningMBs.push_back(std::move(MB)); // take ownership
- }
+ if (Cpio)
+ Cpio->append("response.txt",
+ createResponseFile(Args, FilePaths,
+ ArrayRef<StringRef>(SearchPaths).slice(1)));
// Handle /largeaddressaware
if (Config->is64() || Args.hasArg(OPT_largeaddressaware))
@@ -537,7 +711,7 @@ void LinkerDriver::link(llvm::ArrayRef<c
fatal("entry point must be defined");
Config->Entry = addUndefined(S);
if (Config->Verbose)
- llvm::outs() << "Entry name inferred: " << S << "\n";
+ outs() << "Entry name inferred: " << S << "\n";
}
// Handle /export
@@ -545,18 +719,19 @@ void LinkerDriver::link(llvm::ArrayRef<c
Export E = parseExport(Arg->getValue());
if (Config->Machine == I386) {
if (!isDecorated(E.Name))
- E.Name = Alloc.save("_" + E.Name);
+ E.Name = Saver.save("_" + E.Name);
if (!E.ExtName.empty() && !isDecorated(E.ExtName))
- E.ExtName = Alloc.save("_" + E.ExtName);
+ E.ExtName = Saver.save("_" + E.ExtName);
}
Config->Exports.push_back(E);
}
// Handle /def
if (auto *Arg = Args.getLastArg(OPT_deffile)) {
- MemoryBufferRef MB = openFile(Arg->getValue());
// parseModuleDefs mutates Config object.
- parseModuleDefs(MB, &Alloc);
+ parseModuleDefs(
+ takeBuffer(check(MemoryBuffer::getFile(Arg->getValue()),
+ Twine("could not open ") + Arg->getValue())));
}
// Handle /delayload
@@ -585,14 +760,10 @@ void LinkerDriver::link(llvm::ArrayRef<c
Symtab.addAbsolute(mangle("__guard_fids_count"), 0);
Symtab.addAbsolute(mangle("__guard_flags"), 0x100);
- // Read as much files as we can from directives sections.
- Symtab.run();
-
- // Resolve auxiliary symbols until we get a convergence.
- // (Trying to resolve a symbol may trigger a Lazy symbol to load a new file.
- // A new file may contain a directive section to add new command line options.
- // That's why we have to repeat until converge.)
- for (;;) {
+ // This code may add new undefined symbols to the link, which may enqueue more
+ // symbol resolution tasks, so we need to continue executing tasks until we
+ // converge.
+ do {
// Windows specific -- if entry point is not found,
// search for its mangled names.
if (Config->Entry)
@@ -615,7 +786,7 @@ void LinkerDriver::link(llvm::ArrayRef<c
Symbol *Sym = Symtab.find(From);
if (!Sym)
continue;
- if (auto *U = dyn_cast<Undefined>(Sym->Body))
+ if (auto *U = dyn_cast<Undefined>(Sym->body()))
if (!U->WeakAlias)
U->WeakAlias = Symtab.addUndefined(To);
}
@@ -623,18 +794,15 @@ void LinkerDriver::link(llvm::ArrayRef<c
// Windows specific -- if __load_config_used can be resolved, resolve it.
if (Symtab.findUnderscore("_load_config_used"))
addUndefined(mangle("_load_config_used"));
-
- if (Symtab.queueEmpty())
- break;
- Symtab.run();
- }
+ } while (run());
// Do LTO by compiling bitcode input files to a set of native COFF files then
// link those files.
Symtab.addCombinedLTOObjects();
+ run();
// Make sure we have resolved all symbols.
- Symtab.reportRemainingUndefines(/*Resolve=*/true);
+ Symtab.reportRemainingUndefines();
// Windows specific -- if no /subsystem is given, we need to infer
// that from entry point name.
@@ -662,10 +830,6 @@ void LinkerDriver::link(llvm::ArrayRef<c
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list