summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:48 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:48 +0000
commitb047fead11133644be3dbae34b85be39ce2819e9 (patch)
tree3e7f6a4c9e5ffd7af6044225e9be2962e4d8eabf
parentc09ce7fd2d62d85dcdf370f4bef732380fca4f1b (diff)
downloadsrc-test2-b047fead11133644be3dbae34b85be39ce2819e9.tar.gz
src-test2-b047fead11133644be3dbae34b85be39ce2819e9.zip
Notes
-rw-r--r--ELF/Driver.cpp24
-rw-r--r--ELF/Driver.h3
-rw-r--r--ELF/InputFiles.cpp57
-rw-r--r--ELF/InputFiles.h8
-rw-r--r--ELF/LinkerScript.cpp100
-rw-r--r--ELF/Symbols.cpp4
-rw-r--r--cmake/modules/AddLLD.cmake2
-rw-r--r--include/lld/Core/Reproduce.h3
-rw-r--r--lib/Config/CMakeLists.txt4
-rw-r--r--lib/Core/CMakeLists.txt4
-rw-r--r--lib/Core/Reproduce.cpp12
-rw-r--r--lib/Driver/CMakeLists.txt8
-rw-r--r--lib/ReaderWriter/CMakeLists.txt6
-rw-r--r--lib/ReaderWriter/MachO/CMakeLists.txt11
-rw-r--r--lib/ReaderWriter/YAML/CMakeLists.txt5
-rw-r--r--test/COFF/linkrepro.test2
-rw-r--r--test/ELF/comdat-linkonce.s9
-rw-r--r--test/ELF/linkerscript/symbol-assignexpr.s17
-rw-r--r--test/ELF/mips-gp-ext.s6
-rw-r--r--test/ELF/reproduce-linkerscript.s3
-rw-r--r--test/ELF/undefined-versioned-symbol.s74
-rw-r--r--tools/lld/CMakeLists.txt5
22 files changed, 259 insertions, 108 deletions
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 6afbe62e5ec7..c8ea821ec522 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TarWriter.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
@@ -51,6 +52,7 @@ bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
ErrorCount = 0;
ErrorOS = &Error;
Argv0 = Args[0];
+ Tar = nullptr;
Config = make<Configuration>();
Driver = make<LinkerDriver>();
@@ -170,25 +172,6 @@ void LinkerDriver::addFile(StringRef Path) {
}
}
-Optional<MemoryBufferRef> LinkerDriver::readFile(StringRef Path) {
- if (Config->Verbose)
- outs() << Path << "\n";
-
- auto MBOrErr = MemoryBuffer::getFile(Path);
- if (auto EC = MBOrErr.getError()) {
- error(EC, "cannot open " + Path);
- return None;
- }
- std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
- MemoryBufferRef MBRef = MB->getMemBufferRef();
- make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
-
- if (Tar)
- Tar->append(relativeToRoot(Path), MBRef.getBuffer());
-
- return MBRef;
-}
-
// Add a given library by searching it from input search paths.
void LinkerDriver::addLibrary(StringRef Name) {
if (Optional<std::string> Path = searchLibrary(Name))
@@ -313,9 +296,10 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
TarWriter::create(Path, path::stem(Path));
if (ErrOrWriter) {
- Tar = std::move(*ErrOrWriter);
+ Tar = ErrOrWriter->get();
Tar->append("response.txt", createResponseFile(Args));
Tar->append("version.txt", getLLDVersion() + "\n");
+ make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
} else {
error(Twine("--reproduce: failed to open ") + Path + ": " +
toString(ErrOrWriter.takeError()));
diff --git a/ELF/Driver.h b/ELF/Driver.h
index dadee5eef355..8bb2093e86ca 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -17,7 +17,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/ArgList.h"
-#include "llvm/Support/TarWriter.h"
#include "llvm/Support/raw_ostream.h"
namespace lld {
@@ -30,11 +29,9 @@ public:
void main(ArrayRef<const char *> Args, bool CanExitEarly);
void addFile(StringRef Path);
void addLibrary(StringRef Name);
- std::unique_ptr<llvm::TarWriter> Tar; // for reproduce
private:
std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef MB);
- llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
void readConfigs(llvm::opt::InputArgList &Args);
void createFiles(llvm::opt::InputArgList &Args);
void inferMachineType();
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index bd9f25873c87..1fddf40f5b22 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "InputFiles.h"
-#include "Driver.h"
#include "Error.h"
#include "InputSection.h"
#include "LinkerScript.h"
@@ -26,6 +25,7 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TarWriter.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -36,6 +36,8 @@ using namespace llvm::sys::fs;
using namespace lld;
using namespace lld::elf;
+TarWriter *elf::Tar;
+
namespace {
// In ELF object file all section addresses are zero. If we have multiple
// .text sections (when using -ffunction-section or comdat group) then
@@ -53,6 +55,24 @@ public:
};
}
+Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
+ if (Config->Verbose)
+ outs() << Path << "\n";
+
+ auto MBOrErr = MemoryBuffer::getFile(Path);
+ if (auto EC = MBOrErr.getError()) {
+ error(EC, "cannot open " + Path);
+ return None;
+ }
+ std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
+ MemoryBufferRef MBRef = MB->getMemBufferRef();
+ make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
+
+ if (Tar)
+ Tar->append(relativeToRoot(Path), MBRef.getBuffer());
+ return MBRef;
+}
+
template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() {
std::unique_ptr<object::ObjectFile> Obj =
check(object::ObjectFile::createObjectFile(this->MB),
@@ -398,6 +418,14 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec,
if (Config->Strip != StripPolicy::None && Name.startswith(".debug"))
return &InputSection<ELFT>::Discarded;
+ // The linkonce feature is a sort of proto-comdat. Some glibc i386 object
+ // files contain definitions of symbol "__x86.get_pc_thunk.bx" in linkonce
+ // sections. Drop those sections to avoid duplicate symbol errors.
+ // FIXME: This is glibc PR20543, we should remove this hack once that has been
+ // fixed for a while.
+ if (Name.startswith(".gnu.linkonce."))
+ return &InputSection<ELFT>::Discarded;
+
// The linker merges EH (exception handling) frames and creates a
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
@@ -524,9 +552,8 @@ ArchiveFile::getMember(const Archive::Symbol *Sym) {
"could not get the buffer for the member defining symbol " +
Sym->getName());
- if (C.getParent()->isThin() && Driver->Tar)
- Driver->Tar->append(relativeToRoot(check(C.getFullName())),
- Ret.getBuffer());
+ if (C.getParent()->isThin() && Tar)
+ Tar->append(relativeToRoot(check(C.getFullName())), Ret.getBuffer());
if (C.getParent()->isThin())
return {Ret, 0};
return {Ret, C.getChildOffset()};
@@ -651,6 +678,8 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
VersymIndex = Versym->vs_index;
++Versym;
}
+ bool Hidden = VersymIndex & VERSYM_HIDDEN;
+ VersymIndex = VersymIndex & ~VERSYM_HIDDEN;
StringRef Name = check(Sym.getName(this->StringTable));
if (Sym.isUndefined()) {
@@ -658,15 +687,23 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
continue;
}
- if (Versym) {
- // Ignore local symbols and non-default versions.
- if (VersymIndex == VER_NDX_LOCAL || (VersymIndex & VERSYM_HIDDEN))
- continue;
- }
+ // Ignore local symbols.
+ if (Versym && VersymIndex == VER_NDX_LOCAL)
+ continue;
const Elf_Verdef *V =
VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex];
- elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+
+ if (!Hidden)
+ elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+
+ // Also add the symbol with the versioned name to handle undefined symbols
+ // with explicit versions.
+ if (V) {
+ StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
+ Name = Saver.save(Twine(Name) + "@" + VerName);
+ elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+ }
}
}
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 8b188348199f..73dda7b566b8 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -29,6 +29,7 @@
namespace llvm {
class DWARFDebugLine;
+class TarWriter;
namespace lto {
class InputFile;
}
@@ -49,6 +50,13 @@ using llvm::object::Archive;
class Lazy;
class SymbolBody;
+// If -reproduce option is given, all input files are written
+// to this tar archive.
+extern llvm::TarWriter *Tar;
+
+// Opens a given file.
+llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
+
// The root class of input files.
class InputFile {
public:
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index ccc1059949db..59ef36c87de5 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -56,29 +56,30 @@ using namespace lld::elf;
LinkerScriptBase *elf::ScriptBase;
ScriptConfiguration *elf::ScriptConfig;
-template <class ELFT> static void addRegular(SymbolAssignment *Cmd) {
+template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
- Symbol *Sym = Symtab<ELFT>::X->addRegular(Cmd->Name, Visibility, STT_NOTYPE,
- 0, 0, STB_GLOBAL, nullptr, nullptr);
- Cmd->Sym = Sym->body();
+ Symbol *Sym = Symtab<ELFT>::X->addUndefined(
+ Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
+ /*Type*/ 0,
+ /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
- // If we have no SECTIONS then we don't have '.' and don't call
- // assignAddresses(). We calculate symbol value immediately in this case.
- if (!ScriptConfig->HasSections)
- cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
+ replaceBody<DefinedRegular<ELFT>>(Sym, Cmd->Name, /*IsLocal=*/false,
+ Visibility, STT_NOTYPE, 0, 0, nullptr,
+ nullptr);
+ return Sym->body();
}
-template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
- // If we have SECTIONS block then output sections haven't been created yet.
+template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
+ uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
const OutputSectionBase *Sec =
ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
- Symbol *Sym = Symtab<ELFT>::X->addSynthetic(
- Cmd->Name, Sec, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
- Cmd->Sym = Sym->body();
+ Symbol *Sym = Symtab<ELFT>::X->addUndefined(
+ Cmd->Name, /*IsLocal=*/false, STB_GLOBAL, Visibility,
+ /*Type*/ 0,
+ /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
- // If we already know section then we can calculate symbol value immediately.
- if (Sec)
- cast<DefinedSynthetic>(Cmd->Sym)->Value = Cmd->Expression(0) - Sec->Addr;
+ replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
+ return Sym->body();
}
static bool isUnderSysroot(StringRef Path) {
@@ -90,21 +91,39 @@ static bool isUnderSysroot(StringRef Path) {
return false;
}
-template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) {
- if (Cmd->Expression.IsAbsolute())
- addRegular<ELFT>(Cmd);
- else
- addSynthetic<ELFT>(Cmd);
+template <class ELFT> static void assignSymbol(SymbolAssignment *Cmd) {
+ // If there are sections, then let the value be assigned later in
+ // `assignAddresses`.
+ if (ScriptConfig->HasSections)
+ return;
+
+ uint64_t Value = Cmd->Expression(0);
+ if (Cmd->Expression.IsAbsolute()) {
+ cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Value;
+ } else {
+ const OutputSectionBase *Sec = Cmd->Expression.Section();
+ if (Sec)
+ cast<DefinedSynthetic>(Cmd->Sym)->Value = Value - Sec->Addr;
+ }
}
-// If a symbol was in PROVIDE(), we need to define it only when
-// it is an undefined symbol.
-template <class ELFT> static bool shouldDefine(SymbolAssignment *Cmd) {
+
+template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) {
if (Cmd->Name == ".")
- return false;
- if (!Cmd->Provide)
- return true;
+ return;
+
+ // If a symbol was in PROVIDE(), we need to define it only when
+ // it is a referenced undefined symbol.
SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
- return B && B->isUndefined();
+ if (Cmd->Provide && (!B || B->isDefined()))
+ return;
+
+ // Otherwise, create a new symbol if one does not exist or an
+ // undefined one does exist.
+ if (Cmd->Expression.IsAbsolute())
+ Cmd->Sym = addRegular<ELFT>(Cmd);
+ else
+ Cmd->Sym = addSynthetic<ELFT>(Cmd);
+ assignSymbol<ELFT>(Cmd);
}
bool SymbolAssignment::classof(const BaseCommand *C) {
@@ -283,8 +302,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
// Handle symbol assignments outside of any output section.
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
- if (shouldDefine<ELFT>(Cmd))
- addSymbol<ELFT>(Cmd);
+ addSymbol<ELFT>(Cmd);
continue;
}
@@ -326,8 +344,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
// ".foo : { ...; bar = .; }". Handle them.
for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)
if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base.get()))
- if (shouldDefine<ELFT>(OutCmd))
- addSymbol<ELFT>(OutCmd);
+ addSymbol<ELFT>(OutCmd);
// Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
// is given, input sections are aligned to that value, whether the
@@ -1143,20 +1160,21 @@ void ScriptParser::readGroup() {
void ScriptParser::readInclude() {
StringRef Tok = unquote(next());
+
// https://sourceware.org/binutils/docs/ld/File-Commands.html:
// The file will be searched for in the current directory, and in any
// directory specified with the -L option.
- auto MBOrErr = MemoryBuffer::getFile(Tok);
- if (!MBOrErr)
- if (Optional<std::string> Path = findFromSearchPaths(Tok))
- MBOrErr = MemoryBuffer::getFile(*Path);
- if (!MBOrErr) {
- setError("cannot open " + Tok);
+ if (sys::fs::exists(Tok)) {
+ if (Optional<MemoryBufferRef> MB = readFile(Tok))
+ tokenize(*MB);
+ return;
+ }
+ if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
+ if (Optional<MemoryBufferRef> MB = readFile(*Path))
+ tokenize(*MB);
return;
}
- MemoryBufferRef MBRef = (*MBOrErr)->getMemBufferRef();
- make<std::unique_ptr<MemoryBuffer>>(std::move(*MBOrErr)); // take MB ownership
- tokenize(MBRef);
+ setError("cannot open " + Tok);
}
void ScriptParser::readOutput() {
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 72bcff4e0f4d..f3edafaf4b78 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -202,6 +202,10 @@ void SymbolBody::parseSymbolVersion() {
// Truncate the symbol name so that it doesn't include the version string.
Name = {S.data(), Pos};
+ // If this is an undefined or shared symbol it is not a definition.
+ if (isUndefined() || isShared())
+ return;
+
// '@@' in a symbol name means the default version.
// It is usually the most recent one.
bool IsDefault = (Verstr[0] == '@');
diff --git a/cmake/modules/AddLLD.cmake b/cmake/modules/AddLLD.cmake
index 752ca7f6b43c..906b2952a943 100644
--- a/cmake/modules/AddLLD.cmake
+++ b/cmake/modules/AddLLD.cmake
@@ -1,5 +1,5 @@
macro(add_lld_library name)
- add_llvm_library(${name} ${ARGN})
+ llvm_add_library(${name} ${ARGN})
set_target_properties(${name} PROPERTIES FOLDER "lld libraries")
endmacro(add_lld_library)
diff --git a/include/lld/Core/Reproduce.h b/include/lld/Core/Reproduce.h
index 1b65f763acee..6e1d36a54916 100644
--- a/include/lld/Core/Reproduce.h
+++ b/include/lld/Core/Reproduce.h
@@ -34,9 +34,6 @@ std::string rewritePath(StringRef S);
// Returns the string form of the given argument.
std::string toString(llvm::opt::Arg *Arg);
-
-// Replaces backslashes with slashes if Windows.
-std::string convertToUnixPathSeparator(StringRef S);
}
#endif
diff --git a/lib/Config/CMakeLists.txt b/lib/Config/CMakeLists.txt
index e971b0b7aa62..3e142b66f578 100644
--- a/lib/Config/CMakeLists.txt
+++ b/lib/Config/CMakeLists.txt
@@ -4,6 +4,6 @@ add_lld_library(lldConfig
ADDITIONAL_HEADER_DIRS
${LLD_INCLUDE_DIR}/lld/Config
- LINK_LIBS
- LLVMSupport
+ LINK_COMPONENTS
+ Support
)
diff --git a/lib/Core/CMakeLists.txt b/lib/Core/CMakeLists.txt
index d89ca4a63d72..7f4c47f14b90 100644
--- a/lib/Core/CMakeLists.txt
+++ b/lib/Core/CMakeLists.txt
@@ -12,6 +12,6 @@ add_lld_library(lldCore
ADDITIONAL_HEADER_DIRS
${LLD_INCLUDE_DIR}/lld/Core
- LINK_LIBS
- LLVMSupport
+ LINK_COMPONENTS
+ Support
)
diff --git a/lib/Core/Reproduce.cpp b/lib/Core/Reproduce.cpp
index ab7261fa0e75..e3629a93cbe3 100644
--- a/lib/Core/Reproduce.cpp
+++ b/lib/Core/Reproduce.cpp
@@ -39,7 +39,7 @@ std::string lld::relativeToRoot(StringRef Path) {
Res = Root.substr(2);
path::append(Res, path::relative_path(Abs));
- return convertToUnixPathSeparator(Res);
+ return path::convert_to_slash(Res);
}
// Quote a given string if it contains a space character.
@@ -64,13 +64,3 @@ std::string lld::toString(opt::Arg *Arg) {
return K + V;
return K + " " + V;
}
-
-std::string lld::convertToUnixPathSeparator(StringRef S) {
-#ifdef LLVM_ON_WIN32
- std::string Ret = S.str();
- std::replace(Ret.begin(), Ret.end(), '\\', '/');
- return Ret;
-#else
- return S;
-#endif
-}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 1bd1f2125816..be75872869e6 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -8,15 +8,17 @@ add_lld_library(lldDriver
ADDITIONAL_HEADER_DIRS
${LLD_INCLUDE_DIR}/lld/Driver
+ LINK_COMPONENTS
+ Object
+ Option
+ Support
+
LINK_LIBS
lldConfig
lldMachO
lldCore
lldReaderWriter
lldYAML
- LLVMObject
- LLVMOption
- LLVMSupport
)
add_dependencies(lldDriver DriverOptionsTableGen)
diff --git a/lib/ReaderWriter/CMakeLists.txt b/lib/ReaderWriter/CMakeLists.txt
index 4408d9c18b8b..8751d569b754 100644
--- a/lib/ReaderWriter/CMakeLists.txt
+++ b/lib/ReaderWriter/CMakeLists.txt
@@ -11,9 +11,11 @@ add_lld_library(lldReaderWriter
ADDITIONAL_HEADER_DIRS
${LLD_INCLUDE_DIR}/lld/ReaderWriter
+ LINK_COMPONENTS
+ Object
+ Support
+
LINK_LIBS
lldCore
lldYAML
- LLVMObject
- LLVMSupport
)
diff --git a/lib/ReaderWriter/MachO/CMakeLists.txt b/lib/ReaderWriter/MachO/CMakeLists.txt
index 6a1064d6dfb5..3b0698525aa5 100644
--- a/lib/ReaderWriter/MachO/CMakeLists.txt
+++ b/lib/ReaderWriter/MachO/CMakeLists.txt
@@ -18,13 +18,16 @@ add_lld_library(lldMachO
StubsPass.cpp
TLVPass.cpp
WriterMachO.cpp
+
+ LINK_COMPONENTS
+ DebugInfoDWARF
+ Object
+ Support
+ Demangle
+
LINK_LIBS
lldCore
lldYAML
- LLVMDebugInfoDWARF
- LLVMObject
- LLVMSupport
- LLVMDemangle
${PTHREAD_LIB}
)
diff --git a/lib/ReaderWriter/YAML/CMakeLists.txt b/lib/ReaderWriter/YAML/CMakeLists.txt
index 5c25444e5dbc..0e63574a63d2 100644
--- a/lib/ReaderWriter/YAML/CMakeLists.txt
+++ b/lib/ReaderWriter/YAML/CMakeLists.txt
@@ -1,6 +1,9 @@
add_lld_library(lldYAML
ReaderWriterYAML.cpp
+
+ LINK_COMPONENTS
+ Support
+
LINK_LIBS
lldCore
- LLVMSupport
)
diff --git a/test/COFF/linkrepro.test b/test/COFF/linkrepro.test
index a1d85a159a72..8f4223420a40 100644
--- a/test/COFF/linkrepro.test
+++ b/test/COFF/linkrepro.test
@@ -1,3 +1,5 @@
+# REQUIRES: x86, shell
+
# RUN: rm -rf %t.dir
# RUN: mkdir -p %t.dir/build1 %t.dir/build2 %t.dir/build3
# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
diff --git a/test/ELF/comdat-linkonce.s b/test/ELF/comdat-linkonce.s
new file mode 100644
index 000000000000..78611b4a9f26
--- /dev/null
+++ b/test/ELF/comdat-linkonce.s
@@ -0,0 +1,9 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o
+// RUN: ld.lld -shared %t.o %t2.o -o %t
+// RUN: ld.lld -shared %t2.o %t.o -o %t
+
+.section .gnu.linkonce.t.zed
+.globl abc
+abc:
+nop
diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s
index b988abcdfe98..5132ab11d821 100644
--- a/test/ELF/linkerscript/symbol-assignexpr.s
+++ b/test/ELF/linkerscript/symbol-assignexpr.s
@@ -13,14 +13,20 @@
# RUN: symbol9 = - 4; \
# RUN: symbol10 = 0xfedcba9876543210; \
# RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \
+# RUN: symbol12 = 0x1234; \
+# RUN: symbol12 += 1; \
+# RUN: bar = 0x5678; \
+# RUN: baz = 0x9abc; \
# RUN: }" > %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -t %t1 | FileCheck %s
# CHECK: SYMBOL TABLE:
# CHECK-NEXT: 0000000000000000 *UND* 00000000
-# CHECK-NEXT: .text 00000000 _start
-# CHECK-NEXT: .text 00000000 foo
+# CHECK-NEXT: 0000000000000000 .text 00000000 _start
+# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
+# CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz
+# CHECK-NEXT: 0000000000000001 .text 00000000 foo
# CHECK-NEXT: 0000000000001000 *ABS* 00000000 symbol
# CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol2
# CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol3
@@ -32,6 +38,7 @@
# CHECK-NEXT: fffffffffffffffc *ABS* 00000000 symbol9
# CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10
# CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11
+# CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12
# RUN: echo "SECTIONS { \
# RUN: symbol2 = symbol; \
@@ -46,3 +53,9 @@ _start:
.global foo
foo:
+ nop
+
+.global bar
+bar = 0x1234
+
+.comm baz,8,8
diff --git a/test/ELF/mips-gp-ext.s b/test/ELF/mips-gp-ext.s
index b6c49e0fd422..212fd0fd21e4 100644
--- a/test/ELF/mips-gp-ext.s
+++ b/test/ELF/mips-gp-ext.s
@@ -1,8 +1,10 @@
# Check that the linker use a value of _gp symbol defined
# in a linker script to calculate GOT relocations.
-# FIXME: This test is xfailed because it depends on D27276 patch
-# that enables absolute symbols redefinition by a linker's script.
+# FIXME: This test is xfailed because there is currently a bug
+# that causes symbols defined by linker scripts to be put in the
+# wrong sections. In particular, `_gp = . + 0x100` ends up in
+# `.text` when it should be in `*ABS*`.
# XFAIL: *
# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
diff --git a/test/ELF/reproduce-linkerscript.s b/test/ELF/reproduce-linkerscript.s
index 1938e2b6cf94..2b0081501a62 100644
--- a/test/ELF/reproduce-linkerscript.s
+++ b/test/ELF/reproduce-linkerscript.s
@@ -4,10 +4,13 @@
# RUN: mkdir -p %t.dir/build
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o
# RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script
+# RUN: echo "INCLUDE \"%t.dir/build/bar.script\"" >> %t.dir/build/foo.script
+# RUN: echo "/* empty */" > %t.dir/build/bar.script
# RUN: cd %t.dir
# RUN: ld.lld build/foo.script -o bar --reproduce repro.tar
# RUN: tar xf repro.tar
# RUN: diff build/foo.script repro/%:t.dir/build/foo.script
+# RUN: diff build/bar.script repro/%:t.dir/build/bar.script
# RUN: diff build/foo.o repro/%:t.dir/build/foo.o
.globl _start
diff --git a/test/ELF/undefined-versioned-symbol.s b/test/ELF/undefined-versioned-symbol.s
new file mode 100644
index 000000000000..4e0957f25500
--- /dev/null
+++ b/test/ELF/undefined-versioned-symbol.s
@@ -0,0 +1,74 @@
+// REQUIRES: x86
+// RUN: echo ".data; \
+// RUN: .quad \"basename\"; \
+// RUN: .quad \"basename@FBSD_1.0\"; \
+// RUN: .quad \"basename@FBSD_1.1\" " > %t.s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
+// RUN: echo "FBSD_1.0 { local: *; }; FBSD_1.1 { };" > %t2.ver
+// RUN: ld.lld --shared --version-script %t2.ver %t2.o -o %t2.so
+// RUN: echo "LIBPKG_1.3 { };" > %t.ver
+// RUN: ld.lld --shared %t.o --version-script %t.ver %t2.so -o %t.so
+// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t.so | FileCheck %s
+
+// Test that each relocation points to the correct version.
+
+// CHECK: Section ({{.*}}) .rela.dyn {
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset: 0x2000
+// CHECK-NEXT: Type: R_X86_64_64 (1)
+// CHECK-NEXT: Symbol: basename (1)
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset: 0x2008
+// CHECK-NEXT: Type: R_X86_64_64 (1)
+// CHECK-NEXT: Symbol: basename (2)
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset: 0x2010
+// CHECK-NEXT: Type: R_X86_64_64 (1)
+// CHECK-NEXT: Symbol: basename (3)
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+
+
+// CHECK: DynamicSymbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name:
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section:
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: basename@FBSD_1.1
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section:
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: basename@FBSD_1.0
+// CHECK-NEXT: Value:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Binding:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Other:
+// CHECK-NEXT: Section:
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: basename@FBSD_1.1
+
+
+.global "basename@FBSD_1.0"
+"basename@FBSD_1.0":
+
+.global "basename@@FBSD_1.1"
+"basename@@FBSD_1.1":
diff --git a/tools/lld/CMakeLists.txt b/tools/lld/CMakeLists.txt
index 0c946a3f8ce0..2df10697ff66 100644
--- a/tools/lld/CMakeLists.txt
+++ b/tools/lld/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ )
+
add_lld_tool(lld
lld.cpp
)
@@ -6,7 +10,6 @@ target_link_libraries(lld
lldDriver
lldCOFF
lldELF
- LLVMSupport
)
install(TARGETS lld