summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:58 +0000
commitda06c7cfa0388de29a4024d8d386e48f2fb13ed6 (patch)
treedc28e84fc2bb9a4a4d9873fe4d04946fe3f7f4c0
parent267829774358b5aebd3e726ae318813bd48129bb (diff)
downloadsrc-test2-da06c7cfa0388de29a4024d8d386e48f2fb13ed6.tar.gz
src-test2-da06c7cfa0388de29a4024d8d386e48f2fb13ed6.zip
Notes
-rw-r--r--COFF/Chunks.cpp10
-rw-r--r--COFF/Chunks.h5
-rw-r--r--COFF/Config.h1
-rw-r--r--COFF/Driver.cpp37
-rw-r--r--COFF/PDB.cpp426
-rw-r--r--ELF/Arch/ARM.cpp45
-rw-r--r--ELF/Arch/MipsArchTree.cpp6
-rw-r--r--ELF/Config.h1
-rw-r--r--ELF/Driver.cpp4
-rw-r--r--ELF/EhFrame.h4
-rw-r--r--ELF/Filesystem.h4
-rw-r--r--ELF/GdbIndex.h2
-rw-r--r--ELF/ICF.h2
-rw-r--r--ELF/InputFiles.h4
-rw-r--r--ELF/LTO.h6
-rw-r--r--ELF/LinkerScript.cpp19
-rw-r--r--ELF/MapFile.cpp2
-rw-r--r--ELF/MapFile.h4
-rw-r--r--ELF/Memory.h4
-rw-r--r--ELF/Options.td7
-rw-r--r--ELF/OutputSections.cpp8
-rw-r--r--ELF/OutputSections.h7
-rw-r--r--ELF/Relocations.cpp81
-rw-r--r--ELF/Relocations.h11
-rw-r--r--ELF/ScriptParser.cpp10
-rw-r--r--ELF/Strings.cpp23
-rw-r--r--ELF/Strings.h7
-rw-r--r--ELF/SymbolTable.cpp43
-rw-r--r--ELF/Symbols.cpp2
-rw-r--r--ELF/SyntheticSections.cpp29
-rw-r--r--ELF/Target.cpp5
-rw-r--r--ELF/Target.h5
-rw-r--r--ELF/Threads.h4
-rw-r--r--ELF/Thunks.cpp18
-rw-r--r--ELF/Thunks.h2
-rw-r--r--ELF/Writer.cpp6
-rw-r--r--ELF/Writer.h4
-rw-r--r--docs/windows_support.rst5
-rw-r--r--test/COFF/Inputs/default.def2
-rw-r--r--test/COFF/Inputs/extension.def3
-rw-r--r--test/COFF/Inputs/named.def3
-rw-r--r--test/COFF/Inputs/object.s13
-rw-r--r--test/COFF/Inputs/pdb-type-server-simple-a.yaml255
-rw-r--r--test/COFF/Inputs/pdb-type-server-simple-b.yaml173
-rw-r--r--test/COFF/Inputs/pdb-type-server-simple-ts.yaml147
-rw-r--r--test/COFF/common.test1
-rw-r--r--test/COFF/conflict.test1
-rw-r--r--test/COFF/constant.test1
-rw-r--r--test/COFF/def-export-stdcall.s1
-rw-r--r--test/COFF/delayimports32.test1
-rw-r--r--test/COFF/entry-mangled.test1
-rw-r--r--test/COFF/entrylib.ll1
-rw-r--r--test/COFF/implib-name.test71
-rw-r--r--test/COFF/imports.test1
-rw-r--r--test/COFF/include-lto.ll1
-rw-r--r--test/COFF/msvclto-archive.ll1
-rw-r--r--test/COFF/msvclto-order.ll1
-rw-r--r--test/COFF/msvclto.ll1
-rw-r--r--test/COFF/pdb-comdat.test4
-rw-r--r--test/COFF/pdb-lib.s1
-rw-r--r--test/COFF/pdb-symbol-types.yaml2
-rw-r--r--test/COFF/pdb-type-server-missing.yaml132
-rw-r--r--test/COFF/pdb-type-server-simple.test91
-rw-r--r--test/COFF/reloc-discarded-dwarf.s15
-rw-r--r--test/COFF/reloc-oob.yaml62
-rw-r--r--test/COFF/savetemps.ll1
-rw-r--r--test/COFF/thinlto-archives.ll1
-rw-r--r--test/COFF/thinlto-mangled.ll1
-rw-r--r--test/COFF/thinlto.ll1
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority1.s4
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority2.s4
-rw-r--r--test/ELF/Inputs/ctors_dtors_priority3.s4
-rw-r--r--test/ELF/Inputs/gdb-index-a.elfbin3040 -> 0 bytes
-rw-r--r--test/ELF/Inputs/gdb-index-b.elfbin3048 -> 0 bytes
-rw-r--r--test/ELF/Inputs/gdb-index.s73
-rw-r--r--test/ELF/Inputs/symver-archive1.s6
-rw-r--r--test/ELF/Inputs/symver-archive2.s1
-rw-r--r--test/ELF/allow-shlib-undefined.s1
-rw-r--r--test/ELF/as-needed-no-reloc.s2
-rw-r--r--test/ELF/as-needed.s12
-rw-r--r--test/ELF/auxiliary.s1
-rw-r--r--test/ELF/compressed-debug-input.s2
-rw-r--r--test/ELF/ctors_dtors_priority.s31
-rw-r--r--test/ELF/debug-gnu-pubnames.s26
-rw-r--r--test/ELF/dynamic-reloc.s2
-rw-r--r--test/ELF/filter.s15
-rw-r--r--test/ELF/gc-sections-shared.s2
-rw-r--r--test/ELF/gdb-index-empty.s1
-rw-r--r--test/ELF/gdb-index-gc-sections.s1
-rw-r--r--test/ELF/gdb-index.s113
-rw-r--r--test/ELF/i386-reloc-large-addend.s1
-rw-r--r--test/ELF/i386-reloc-range.s1
-rw-r--r--test/ELF/invalid/tls-symbol.s4
-rw-r--r--test/ELF/linkerscript/exidx-crash.s7
-rw-r--r--test/ELF/linkerscript/got-write-offset.s23
-rw-r--r--test/ELF/linkerscript/output-too-large.s1
-rw-r--r--test/ELF/lto/available-externally.ll1
-rw-r--r--test/ELF/lto/comdat2.ll1
-rw-r--r--test/ELF/lto/common2.ll1
-rw-r--r--test/ELF/lto/common3.ll1
-rw-r--r--test/ELF/lto/discard-value-names.ll1
-rw-r--r--test/ELF/lto/opt-level.ll1
-rw-r--r--test/ELF/lto/opt-remarks.ll1
-rw-r--r--test/ELF/lto/relax-relocs.ll1
-rw-r--r--test/ELF/lto/thin-archivecollision.ll1
-rw-r--r--test/ELF/lto/thinlto.ll1
-rw-r--r--test/ELF/lto/type-merge2.ll1
-rw-r--r--test/ELF/lto/unnamed-addr-comdat.ll1
-rw-r--r--test/ELF/lto/unnamed-addr-drop.ll1
-rw-r--r--test/ELF/lto/unnamed-addr.ll1
-rw-r--r--test/ELF/many-alloc-sections.s1
-rw-r--r--test/ELF/many-sections.s1
-rw-r--r--test/ELF/map-gc-sections.s9
-rw-r--r--test/ELF/merge-section-types.s1
-rw-r--r--test/ELF/new-dtags.test1
-rw-r--r--test/ELF/no-obj.s1
-rw-r--r--test/ELF/no-soname.s9
-rw-r--r--test/ELF/no-symtab.s1
-rw-r--r--test/ELF/no-undefined.s1
-rw-r--r--test/ELF/pie-weak.s1
-rw-r--r--test/ELF/progname.s1
-rw-r--r--test/ELF/relative-dynamic-reloc-pie.s1
-rw-r--r--test/ELF/relative-dynamic-reloc.s1
-rw-r--r--test/ELF/relocatable-compressed-input.s2
-rw-r--r--test/ELF/relocatable-reloc.s1
-rw-r--r--test/ELF/relocatable-section-symbol.s1
-rw-r--r--test/ELF/relocatable-sections.s1
-rw-r--r--test/ELF/relocatable-tls.s1
-rw-r--r--test/ELF/relocation-shared.s1
-rw-r--r--test/ELF/shared-be.s2
-rw-r--r--test/ELF/shared.s2
-rw-r--r--test/ELF/soname.s2
-rw-r--r--test/ELF/soname2.s2
-rw-r--r--test/ELF/symver-archive.s15
-rw-r--r--test/ELF/version-script-twice.s14
135 files changed, 1880 insertions, 398 deletions
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index c0996f55f9d1..7d93c28c86c8 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -210,7 +210,15 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
memcpy(Buf + OutputSectionOff, A.data(), A.size());
// Apply relocations.
+ size_t InputSize = getSize();
for (const coff_relocation &Rel : Relocs) {
+ // Check for an invalid relocation offset. This check isn't perfect, because
+ // we don't have the relocation size, which is only known after checking the
+ // machine and relocation type. As a result, a relocation may overwrite the
+ // beginning of the following input section.
+ if (Rel.VirtualAddress >= InputSize)
+ fatal("relocation points beyond the end of its parent section");
+
uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
// Get the output section of the symbol for this relocation. The output
@@ -227,7 +235,7 @@ void SectionChunk::writeTo(uint8_t *Buf) const {
// sections are not GC roots and can end up with these kinds of relocations.
// Skip these relocations.
if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
- if (isCodeView())
+ if (isCodeView() || isDWARF())
continue;
fatal("relocation against symbol in discarded section: " +
Sym->getName());
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index fc3f5d0df4b6..ece5419e255e 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -112,7 +112,7 @@ protected:
};
// A chunk corresponding a section of an input file.
-class SectionChunk : public Chunk {
+class SectionChunk final : public Chunk {
// Identical COMDAT Folding feature accesses section internal data.
friend class ICF;
@@ -188,6 +188,9 @@ public:
return SectionName == ".debug" || SectionName.startswith(".debug$");
}
+ // True if this is a DWARF debug info chunk.
+ bool isDWARF() const { return SectionName.startswith(".debug_"); }
+
// Allow iteration over the bodies of this chunk's relocated symbols.
llvm::iterator_range<symbol_iterator> symbols() const {
return llvm::make_range(symbol_iterator(File, Relocs.begin()),
diff --git a/COFF/Config.h b/COFF/Config.h
index 25fdc7abd67b..a58e7d5585f2 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -82,6 +82,7 @@ struct Configuration {
SymbolBody *Entry = nullptr;
bool NoEntry = false;
std::string OutputFile;
+ std::string ImportName;
bool ColorDiagnostics;
bool DoGC = true;
bool DoICF = true;
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 3620297b8b94..35f4a04866c5 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -429,7 +429,32 @@ static std::string getImplibPath() {
return Out.str();
}
-static void createImportLibrary() {
+//
+// The import name is caculated as the following:
+//
+// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY
+// -----+----------------+---------------------+------------------
+// LINK | {value} | {value}.{.dll/.exe} | {output name}
+// LIB | {value} | {value}.dll | {output name}.dll
+//
+static std::string getImportName(bool AsLib) {
+ SmallString<128> Out;
+
+ if (Config->ImportName.empty()) {
+ Out.assign(sys::path::filename(Config->OutputFile));
+ if (AsLib)
+ sys::path::replace_extension(Out, ".dll");
+ } else {
+ Out.assign(Config->ImportName);
+ if (!sys::path::has_extension(Out))
+ sys::path::replace_extension(Out,
+ (Config->DLL || AsLib) ? ".dll" : ".exe");
+ }
+
+ return Out.str();
+}
+
+static void createImportLibrary(bool AsLib) {
std::vector<COFFShortExport> Exports;
for (Export &E1 : Config->Exports) {
COFFShortExport E2;
@@ -444,9 +469,8 @@ static void createImportLibrary() {
Exports.push_back(E2);
}
- std::string DLLName = sys::path::filename(Config->OutputFile);
- std::string Path = getImplibPath();
- writeImportLibrary(DLLName, Path, Exports, Config->Machine);
+ writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports,
+ Config->Machine);
}
static void parseModuleDefs(StringRef Path) {
@@ -457,6 +481,7 @@ static void parseModuleDefs(StringRef Path) {
if (Config->OutputFile.empty())
Config->OutputFile = Saver.save(M.OutputFile);
+ Config->ImportName = Saver.save(M.ImportName);
if (M.ImageBase)
Config->ImageBase = M.ImageBase;
if (M.StackReserve)
@@ -992,7 +1017,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// Handle generation of import library from a def file.
if (!Args.hasArgNoClaim(OPT_INPUT)) {
fixupExports();
- createImportLibrary();
+ createImportLibrary(/*AsLib=*/true);
exit(0);
}
@@ -1117,7 +1142,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// need to create a .lib file.
if (!Config->Exports.empty() || Config->DLL) {
fixupExports();
- createImportLibrary();
+ createImportLibrary(/*AsLib=*/false);
assignExportOrdinals();
}
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 508f59e3af1f..89462da93454 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -14,28 +14,29 @@
#include "SymbolTable.h"
#include "Symbols.h"
#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/Endian.h"
@@ -53,8 +54,81 @@ using llvm::object::coff_section;
static ExitOnError ExitOnErr;
+namespace {
+/// Map from type index and item index in a type server PDB to the
+/// corresponding index in the destination PDB.
+struct CVIndexMap {
+ SmallVector<TypeIndex, 0> TPIMap;
+ SmallVector<TypeIndex, 0> IPIMap;
+ bool IsTypeServerMap = false;
+};
+
+class PDBLinker {
+public:
+ PDBLinker(SymbolTable *Symtab)
+ : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
+ IDTable(Alloc) {}
+
+ /// Emit the basic PDB structure: initial streams, headers, etc.
+ void initialize(const llvm::codeview::DebugInfo *DI);
+
+ /// Link CodeView from each object file in the symbol table into the PDB.
+ void addObjectsToPDB();
+
+ /// Link CodeView from a single object file into the PDB.
+ void addObjectFile(ObjectFile *File);
+
+ /// Produce a mapping from the type and item indices used in the object
+ /// file to those in the destination PDB.
+ ///
+ /// If the object file uses a type server PDB (compiled with /Zi), merge TPI
+ /// and IPI from the type server PDB and return a map for it. Each unique type
+ /// server PDB is merged at most once, so this may return an existing index
+ /// mapping.
+ ///
+ /// If the object does not use a type server PDB (compiled with /Z7), we merge
+ /// all the type and item records from the .debug$S stream and fill in the
+ /// caller-provided ObjectIndexMap.
+ const CVIndexMap &mergeDebugT(ObjectFile *File, CVIndexMap &ObjectIndexMap);
+
+ const CVIndexMap &maybeMergeTypeServerPDB(ObjectFile *File,
+ TypeServer2Record &TS);
+
+ /// Add the section map and section contributions to the PDB.
+ void addSections(ArrayRef<uint8_t> SectionTable);
+
+ /// Write the PDB to disk.
+ void commit();
+
+private:
+ BumpPtrAllocator Alloc;
+
+ SymbolTable *Symtab;
+
+ pdb::PDBFileBuilder Builder;
+
+ /// Type records that will go into the PDB TPI stream.
+ TypeTableBuilder TypeTable;
+
+ /// Item records that will go into the PDB IPI stream.
+ TypeTableBuilder IDTable;
+
+ /// PDBs use a single global string table for filenames in the file checksum
+ /// table.
+ DebugStringTableSubsection PDBStrTab;
+
+ llvm::SmallString<128> NativePath;
+
+ std::vector<pdb::SecMapEntry> SectionMap;
+
+ /// Type index mappings of type server PDBs that we've loaded so far.
+ std::map<GUID, CVIndexMap> TypeServerIndexMappings;
+};
+}
+
// Returns a list of all SectionChunks.
-static void addSectionContribs(SymbolTable *Symtab, pdb::DbiStreamBuilder &DbiBuilder) {
+static void addSectionContribs(SymbolTable *Symtab,
+ pdb::DbiStreamBuilder &DbiBuilder) {
for (Chunk *C : Symtab->getChunks())
if (auto *SC = dyn_cast<SectionChunk>(C))
DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header);
@@ -96,24 +170,115 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
});
}
-static void mergeDebugT(ObjectFile *File,
- TypeTableBuilder &IDTable,
- TypeTableBuilder &TypeTable,
- SmallVectorImpl<TypeIndex> &TypeIndexMap,
- pdb::PDBTypeServerHandler &Handler) {
+static Optional<TypeServer2Record>
+maybeReadTypeServerRecord(CVTypeArray &Types) {
+ auto I = Types.begin();
+ if (I == Types.end())
+ return None;
+ const CVType &Type = *I;
+ if (Type.kind() != LF_TYPESERVER2)
+ return None;
+ TypeServer2Record TS;
+ if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))
+ fatal(EC, "error reading type server record");
+ return std::move(TS);
+}
+
+const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File,
+ CVIndexMap &ObjectIndexMap) {
ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
if (Data.empty())
- return;
+ return ObjectIndexMap;
BinaryByteStream Stream(Data, support::little);
CVTypeArray Types;
BinaryStreamReader Reader(Stream);
- Handler.addSearchPath(sys::path::parent_path(File->getName()));
if (auto EC = Reader.readArray(Types, Reader.getLength()))
fatal(EC, "Reader::readArray failed");
+
+ // Look through type servers. If we've already seen this type server, don't
+ // merge any type information.
+ if (Optional<TypeServer2Record> TS = maybeReadTypeServerRecord(Types))
+ return maybeMergeTypeServerPDB(File, *TS);
+
+ // This is a /Z7 object. Fill in the temporary, caller-provided
+ // ObjectIndexMap.
if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
- TypeIndexMap, &Handler, Types))
- fatal(Err, "codeview::mergeTypeStreams failed");
+ ObjectIndexMap.TPIMap, Types))
+ fatal(Err, "codeview::mergeTypeAndIdRecords failed");
+ return ObjectIndexMap;
+}
+
+static Expected<std::unique_ptr<pdb::NativeSession>>
+tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
+ std::unique_ptr<pdb::IPDBSession> ThisSession;
+ if (auto EC =
+ pdb::loadDataForPDB(pdb::PDB_ReaderType::Native, TSPath, ThisSession))
+ return std::move(EC);
+
+ std::unique_ptr<pdb::NativeSession> NS(
+ static_cast<pdb::NativeSession *>(ThisSession.release()));
+ pdb::PDBFile &File = NS->getPDBFile();
+ auto ExpectedInfo = File.getPDBInfoStream();
+ // All PDB Files should have an Info stream.
+ if (!ExpectedInfo)
+ return ExpectedInfo.takeError();
+
+ // Just because a file with a matching name was found and it was an actual
+ // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
+ // must match the GUID specified in the TypeServer2 record.
+ if (ExpectedInfo->getGuid() != GuidFromObj)
+ return make_error<pdb::GenericError>(
+ pdb::generic_error_code::type_server_not_found, TSPath);
+
+ return std::move(NS);
+}
+
+const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File,
+ TypeServer2Record &TS) {
+ // First, check if we already loaded a PDB with this GUID. Return the type
+ // index mapping if we have it.
+ auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()});
+ CVIndexMap &IndexMap = Insertion.first->second;
+ if (!Insertion.second)
+ return IndexMap;
+
+ // Mark this map as a type server map.
+ IndexMap.IsTypeServerMap = true;
+
+ // Check for a PDB at:
+ // 1. The given file path
+ // 2. Next to the object file or archive file
+ auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName());
+ if (!ExpectedSession) {
+ consumeError(ExpectedSession.takeError());
+ StringRef LocalPath =
+ !File->ParentName.empty() ? File->ParentName : File->getName();
+ SmallString<128> Path = sys::path::parent_path(LocalPath);
+ sys::path::append(
+ Path, sys::path::filename(TS.getName(), sys::path::Style::windows));
+ ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
+ }
+ if (auto E = ExpectedSession.takeError())
+ fatal(E, "Type server PDB was not found");
+
+ // Merge TPI first, because the IPI stream will reference type indices.
+ auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
+ if (auto E = ExpectedTpi.takeError())
+ fatal(E, "Type server does not have TPI stream");
+ if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
+ ExpectedTpi->typeArray()))
+ fatal(Err, "codeview::mergeTypeRecords failed");
+
+ // Merge IPI.
+ auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
+ if (auto E = ExpectedIpi.takeError())
+ fatal(E, "Type server does not have TPI stream");
+ if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
+ ExpectedIpi->typeArray()))
+ fatal(Err, "codeview::mergeIdRecords failed");
+
+ return IndexMap;
}
static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
@@ -127,16 +292,22 @@ static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
static void remapTypesInSymbolRecord(ObjectFile *File,
MutableArrayRef<uint8_t> Contents,
- ArrayRef<TypeIndex> TypeIndexMap,
+ const CVIndexMap &IndexMap,
ArrayRef<TiReference> TypeRefs) {
for (const TiReference &Ref : TypeRefs) {
unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
if (Contents.size() < Ref.Offset + ByteSize)
fatal("symbol record too short");
+
+ // This can be an item index or a type index. Choose the appropriate map.
+ ArrayRef<TypeIndex> TypeOrItemMap = IndexMap.TPIMap;
+ if (Ref.Kind == TiRefKind::IndexRef && IndexMap.IsTypeServerMap)
+ TypeOrItemMap = IndexMap.IPIMap;
+
MutableArrayRef<TypeIndex> TIs(
reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
for (TypeIndex &TI : TIs) {
- if (!remapTypeIndex(TI, TypeIndexMap)) {
+ if (!remapTypeIndex(TI, TypeOrItemMap)) {
TI = TypeIndex(SimpleTypeKind::NotTranslated);
log("ignoring symbol record in " + File->getName() +
" with bad type index 0x" + utohexstr(TI.getIndex()));
@@ -241,7 +412,7 @@ static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
}
static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
- ArrayRef<TypeIndex> TypeIndexMap,
+ const CVIndexMap &IndexMap,
BinaryStreamRef SymData) {
// FIXME: Improve error recovery by warning and skipping records when
// possible.
@@ -264,7 +435,7 @@ static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
// Re-map all the type index references.
MutableArrayRef<uint8_t> Contents =
NewData.drop_front(sizeof(RecordPrefix));
- remapTypesInSymbolRecord(File, Contents, TypeIndexMap, TypeRefs);
+ remapTypesInSymbolRecord(File, Contents, IndexMap, TypeRefs);
// Fill in "Parent" and "End" fields by maintaining a stack of scopes.
CVSymbol NewSym(Sym.kind(), NewData);
@@ -289,110 +460,105 @@ static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
".debug$S");
}
-// Add all object files to the PDB. Merge .debug$T sections into IpiData and
-// TpiData.
-static void addObjectsToPDB(BumpPtrAllocator &Alloc, SymbolTable *Symtab,
- pdb::PDBFileBuilder &Builder,
- TypeTableBuilder &TypeTable,
- TypeTableBuilder &IDTable) {
- // Follow type servers. If the same type server is encountered more than
- // once for this instance of `PDBTypeServerHandler` (for example if many
- // object files reference the same TypeServer), the types from the
- // TypeServer will only be visited once.
- pdb::PDBTypeServerHandler Handler;
-
- // PDBs use a single global string table for filenames in the file checksum
- // table.
- auto PDBStrTab = std::make_shared<DebugStringTableSubsection>();
-
- // Visit all .debug$T sections to add them to Builder.
- for (ObjectFile *File : Symtab->ObjectFiles) {
- // Add a module descriptor for every object file. We need to put an absolute
- // path to the object into the PDB. If this is a plain object, we make its
- // path absolute. If it's an object in an archive, we make the archive path
- // absolute.
- bool InArchive = !File->ParentName.empty();
- SmallString<128> Path = InArchive ? File->ParentName : File->getName();
- sys::fs::make_absolute(Path);
- sys::path::native(Path, llvm::sys::path::Style::windows);
- StringRef Name = InArchive ? File->getName() : StringRef(Path);
-
- File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
- File->ModuleDBI->setObjFileName(Path);
-
- // Before we can process symbol substreams from .debug$S, we need to process
- // type information, file checksums, and the string table. Add type info to
- // the PDB first, so that we can get the map from object file type and item
- // indices to PDB type and item indices.
- SmallVector<TypeIndex, 128> TypeIndexMap;
- mergeDebugT(File, IDTable, TypeTable, TypeIndexMap, Handler);
-
- // Now do all line info.
- for (SectionChunk *DebugChunk : File->getDebugChunks()) {
- if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
- continue;
+void PDBLinker::addObjectFile(ObjectFile *File) {
+ // Add a module descriptor for every object file. We need to put an absolute
+ // path to the object into the PDB. If this is a plain object, we make its
+ // path absolute. If it's an object in an archive, we make the archive path
+ // absolute.
+ bool InArchive = !File->ParentName.empty();
+ SmallString<128> Path = InArchive ? File->ParentName : File->getName();
+ sys::fs::make_absolute(Path);
+ sys::path::native(Path, sys::path::Style::windows);
+ StringRef Name = InArchive ? File->getName() : StringRef(Path);
+
+ File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
+ File->ModuleDBI->setObjFileName(Path);
+
+ // Before we can process symbol substreams from .debug$S, we need to process
+ // type information, file checksums, and the string table. Add type info to
+ // the PDB first, so that we can get the map from object file type and item
+ // indices to PDB type and item indices.
+ CVIndexMap ObjectIndexMap;
+ const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap);
+
+ // Now do all live .debug$S sections.
+ for (SectionChunk *DebugChunk : File->getDebugChunks()) {
+ if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
+ continue;
- ArrayRef<uint8_t> RelocatedDebugContents =
- relocateDebugChunk(Alloc, DebugChunk);
- if (RelocatedDebugContents.empty())
- continue;
+ ArrayRef<uint8_t> RelocatedDebugContents =
+ relocateDebugChunk(Alloc, DebugChunk);
+ if (RelocatedDebugContents.empty())
+ continue;
- DebugSubsectionArray Subsections;
- BinaryStreamReader Reader(RelocatedDebugContents, support::little);
- ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
-
- DebugStringTableSubsectionRef CVStrTab;
- DebugChecksumsSubsectionRef Checksums;
- for (const DebugSubsectionRecord &SS : Subsections) {
- switch (SS.kind()) {
- case DebugSubsectionKind::StringTable:
- ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
- break;
- case DebugSubsectionKind::FileChecksums:
- ExitOnErr(Checksums.initialize(SS.getRecordData()));
- break;
- case DebugSubsectionKind::Lines:
- // We can add the relocated line table directly to the PDB without
- // modification because the file checksum offsets will stay the same.
- File->ModuleDBI->addDebugSubsection(SS);
- break;
- case DebugSubsectionKind::Symbols:
- mergeSymbolRecords(Alloc, File, TypeIndexMap, SS.getRecordData());
- break;
- default:
- // FIXME: Process the rest of the subsections.
- break;
- }
+ DebugSubsectionArray Subsections;
+ BinaryStreamReader Reader(RelocatedDebugContents, support::little);
+ ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
+
+ DebugStringTableSubsectionRef CVStrTab;
+ DebugChecksumsSubsectionRef Checksums;
+ for (const DebugSubsectionRecord &SS : Subsections) {
+ switch (SS.kind()) {
+ case DebugSubsectionKind::StringTable:
+ ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
+ break;
+ case DebugSubsectionKind::FileChecksums:
+ ExitOnErr(Checksums.initialize(SS.getRecordData()));
+ break;
+ case DebugSubsectionKind::Lines:
+ // We can add the relocated line table directly to the PDB without
+ // modification because the file checksum offsets will stay the same.
+ File->ModuleDBI->addDebugSubsection(SS);
+ break;
+ case DebugSubsectionKind::Symbols:
+ mergeSymbolRecords(Alloc, File, IndexMap, SS.getRecordData());
+ break;
+ default:
+ // FIXME: Process the rest of the subsections.
+ break;
}
+ }
- if (Checksums.valid()) {
- // Make a new file checksum table that refers to offsets in the PDB-wide
- // string table. Generally the string table subsection appears after the
- // checksum table, so we have to do this after looping over all the
- // subsections.
- if (!CVStrTab.valid())
- fatal(".debug$S sections must have both a string table subsection "
- "and a checksum subsection table or neither");
- auto NewChecksums =
- make_unique<DebugChecksumsSubsection>(*PDBStrTab);
- for (FileChecksumEntry &FC : Checksums) {
- StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
- ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(
- *File->ModuleDBI, FileName));
- NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
- }
- File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
+ if (Checksums.valid()) {
+ // Make a new file checksum table that refers to offsets in the PDB-wide
+ // string table. Generally the string table subsection appears after the
+ // checksum table, so we have to do this after looping over all the
+ // subsections.
+ if (!CVStrTab.valid())
+ fatal(".debug$S sections must have both a string table subsection "
+ "and a checksum subsection table or neither");
+ auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab);
+ for (FileChecksumEntry &FC : Checksums) {
+ StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
+ ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI,
+ FileName));
+ NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
}
+ File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
}
}
+}
+
+// Add all object files to the PDB. Merge .debug$T sections into IpiData and
+// TpiData.
+void PDBLinker::addObjectsToPDB() {
+ for (ObjectFile *File : Symtab->ObjectFiles)
+ addObjectFile(File);
- Builder.getStringTableBuilder().setStrings(*PDBStrTab);
+ Builder.getStringTableBuilder().setStrings(PDBStrTab);
// Construct TPI stream contents.
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
// Construct IPI stream contents.
addTypeInfo(Builder.getIpiBuilder(), IDTable);
+
+ // Add public and symbol records stream.
+
+ // For now we don't actually write any thing useful to the publics stream, but
+ // the act of "getting" it also creates it lazily so that we write an empty
+ // stream.
+ (void)Builder.getPublicsBuilder();
}
static void addLinkerModuleSymbols(StringRef Path,
@@ -423,7 +589,7 @@ static void addLinkerModuleSymbols(StringRef Path,
std::string ArgStr = llvm::join(Args, " ");
EBS.Fields.push_back("cwd");
SmallString<64> cwd;
- llvm::sys::fs::current_path(cwd);
+ sys::fs::current_path(cwd);
EBS.Fields.push_back(cwd);
EBS.Fields.push_back("exe");
EBS.Fields.push_back(Config->Argv[0]);
@@ -442,8 +608,14 @@ static void addLinkerModuleSymbols(StringRef Path,
// Creates a PDB file.
void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
const llvm::codeview::DebugInfo *DI) {
- BumpPtrAllocator Alloc;
- pdb::PDBFileBuilder Builder(Alloc);
+ PDBLinker PDB(Symtab);
+ PDB.initialize(DI);
+ PDB.addObjectsToPDB();
+ PDB.addSections(SectionTable);
+ PDB.commit();
+}
+
+void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) {
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
// Create streams in MSF for predefined streams, namely
@@ -455,12 +627,7 @@ void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
auto &InfoBuilder = Builder.getInfoBuilder();
InfoBuilder.setAge(DI ? DI->PDB70.Age : 0);
- llvm::SmallString<128> NativePath(Config->PDBPath.begin(),
- Config->PDBPath.end());
- llvm::sys::fs::make_absolute(NativePath);
- llvm::sys::path::native(NativePath, llvm::sys::path::Style::windows);
-
- pdb::PDB_UniqueId uuid{};
+ GUID uuid{};
if (DI)
memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid));
InfoBuilder.setGuid(uuid);
@@ -471,32 +638,25 @@ void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {}));
+}
- // It's not entirely clear what this is, but the * Linker * module uses it.
- uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
-
- TypeTableBuilder TypeTable(BAlloc);
- TypeTableBuilder IDTable(BAlloc);
- addObjectsToPDB(Alloc, Symtab, Builder, TypeTable, IDTable);
-
- // Add public and symbol records stream.
-
- // For now we don't actually write any thing useful to the publics stream, but
- // the act of "getting" it also creates it lazily so that we write an empty
- // stream.
- (void)Builder.getPublicsBuilder();
-
+void PDBLinker::addSections(ArrayRef<uint8_t> SectionTable) {
// Add Section Contributions.
+ pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
addSectionContribs(Symtab, DbiBuilder);
// Add Section Map stream.
ArrayRef<object::coff_section> Sections = {
(const object::coff_section *)SectionTable.data(),
SectionTable.size() / sizeof(object::coff_section)};
- std::vector<pdb::SecMapEntry> SectionMap =
- pdb::DbiStreamBuilder::createSectionMap(Sections);
+ SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections);
DbiBuilder.setSectionMap(SectionMap);
+ // It's not entirely clear what this is, but the * Linker * module uses it.
+ NativePath = Config->PDBPath;
+ sys::fs::make_absolute(NativePath);
+ sys::path::native(NativePath, sys::path::Style::windows);
+ uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
LinkerModule.setPdbFilePathNI(PdbFilePathNI);
addLinkerModuleSymbols(NativePath, LinkerModule, Alloc);
@@ -504,7 +664,9 @@ void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
// Add COFF section header stream.
ExitOnErr(
DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
+}
+void PDBLinker::commit() {
// Write to a file.
ExitOnErr(Builder.commit(Config->PDBPath));
}
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index e4b06ade4487..106021de7d32 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -40,6 +40,8 @@ public:
void addPltHeaderSymbols(InputSectionBase *ISD) const override;
bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
const SymbolBody &S) const override;
+ bool inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const override;
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
};
} // namespace
@@ -218,6 +220,49 @@ bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
return false;
}
+bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const {
+ uint64_t Range;
+ uint64_t InstrSize;
+
+ switch (RelocType) {
+ case R_ARM_PC24:
+ case R_ARM_PLT32:
+ case R_ARM_JUMP24:
+ case R_ARM_CALL:
+ Range = 0x2000000;
+ InstrSize = 4;
+ break;
+ case R_ARM_THM_JUMP19:
+ Range = 0x100000;
+ InstrSize = 2;
+ break;
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_CALL:
+ Range = 0x1000000;
+ InstrSize = 2;
+ break;
+ default:
+ return true;
+ }
+ // PC at Src is 2 instructions ahead, immediate of branch is signed
+ if (Src > Dst)
+ Range -= 2 * InstrSize;
+ else
+ Range += InstrSize;
+
+ if ((Dst & 0x1) == 0)
+ // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
+ // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
+ // destination will be 4 byte aligned.
+ Src &= ~0x3;
+ else
+ // Bit 0 == 1 denotes Thumb state, it is not part of the range
+ Dst &= ~0x1;
+
+ uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
+ return Distance <= Range;
+}
+
void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
switch (Type) {
case R_ARM_ABS32:
diff --git a/ELF/Arch/MipsArchTree.cpp b/ELF/Arch/MipsArchTree.cpp
index ed183e9a3061..3d1dc1daf0c1 100644
--- a/ELF/Arch/MipsArchTree.cpp
+++ b/ELF/Arch/MipsArchTree.cpp
@@ -37,7 +37,7 @@ struct FileFlags {
StringRef Filename;
uint32_t Flags;
};
-}
+} // namespace
static StringRef getAbiName(uint32_t Flags) {
switch (Flags) {
@@ -337,8 +337,8 @@ uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
return NewFlag;
if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
- "' is incompatible with '" + getMipsFpAbiName(NewFlag) + "': " +
- FileName);
+ "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
+ "': " + FileName);
return OldFlag;
}
diff --git a/ELF/Config.h b/ELF/Config.h
index 5e3b77637316..23627dd812db 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -99,6 +99,7 @@ struct Configuration {
std::vector<VersionDefinition> VersionDefinitions;
std::vector<llvm::StringRef> Argv;
std::vector<llvm::StringRef> AuxiliaryList;
+ std::vector<llvm::StringRef> FilterList;
std::vector<llvm::StringRef> SearchPaths;
std::vector<llvm::StringRef> SymbolOrderingFile;
std::vector<llvm::StringRef> Undefined;
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 10ad13f214d5..4630e110bcd8 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -259,6 +259,9 @@ static void checkOptions(opt::InputArgList &Args) {
if (Config->Pie && Config->Shared)
error("-shared and -pie may not be used together");
+ if (!Config->Shared && !Config->FilterList.empty())
+ error("-F may not be used without -shared");
+
if (!Config->Shared && !Config->AuxiliaryList.empty())
error("-f may not be used without -shared");
@@ -631,6 +634,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false);
Config->FatalWarnings =
getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false);
+ Config->FilterList = getArgs(Args, OPT_filter);
Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);
Config->GdbIndex = Args.hasArg(OPT_gdb_index);
diff --git a/ELF/EhFrame.h b/ELF/EhFrame.h
index 4e2b6f83a294..07d1aaa3cbb3 100644
--- a/ELF/EhFrame.h
+++ b/ELF/EhFrame.h
@@ -19,7 +19,7 @@ struct EhSectionPiece;
template <class ELFT> size_t readEhRecordSize(InputSectionBase *S, size_t Off);
template <class ELFT> uint8_t getFdeEncoding(EhSectionPiece *P);
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/Filesystem.h b/ELF/Filesystem.h
index d56d067f7378..dbeadac5a96b 100644
--- a/ELF/Filesystem.h
+++ b/ELF/Filesystem.h
@@ -16,7 +16,7 @@ namespace lld {
namespace elf {
void unlinkAsync(StringRef Path);
std::error_code tryCreateFile(StringRef Path);
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/GdbIndex.h b/ELF/GdbIndex.h
index c49f8946e199..bc024e6689ef 100644
--- a/ELF/GdbIndex.h
+++ b/ELF/GdbIndex.h
@@ -11,8 +11,8 @@
#define LLD_ELF_GDB_INDEX_H
#include "InputFiles.h"
-#include "llvm/Object/ELF.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/ELF.h"
namespace lld {
namespace elf {
diff --git a/ELF/ICF.h b/ELF/ICF.h
index 502e128c8109..24219855fc17 100644
--- a/ELF/ICF.h
+++ b/ELF/ICF.h
@@ -14,6 +14,6 @@ namespace lld {
namespace elf {
template <class ELFT> void doIcf();
}
-}
+} // namespace lld
#endif
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 544a0b009b39..f6d3f907850c 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -11,8 +11,8 @@
#define LLD_ELF_INPUT_FILES_H
#include "Config.h"
-#include "InputSection.h"
#include "Error.h"
+#include "InputSection.h"
#include "Symbols.h"
#include "lld/Core/LLVM.h"
@@ -34,7 +34,7 @@ struct DILineInfo;
namespace lto {
class InputFile;
}
-}
+} // namespace llvm
namespace lld {
namespace elf {
diff --git a/ELF/LTO.h b/ELF/LTO.h
index 28afa0e83add..d19923c90a99 100644
--- a/ELF/LTO.h
+++ b/ELF/LTO.h
@@ -30,7 +30,7 @@ namespace llvm {
namespace lto {
class LTO;
}
-}
+} // namespace llvm
namespace lld {
namespace elf {
@@ -51,7 +51,7 @@ private:
std::vector<SmallString<0>> Buff;
std::vector<std::unique_ptr<MemoryBuffer>> Files;
};
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index a182d5a3a096..8bdbd8db20ad 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -229,6 +229,19 @@ bool LinkerScript::shouldKeep(InputSectionBase *S) {
return false;
}
+// If an input string is in the form of "foo.N" where N is a number,
+// return N. Otherwise, returns 65536, which is one greater than the
+// lowest priority.
+static int getPriority(StringRef S) {
+ size_t Pos = S.rfind('.');
+ if (Pos == StringRef::npos)
+ return 65536;
+ int V;
+ if (!to_integer(S.substr(Pos + 1), V, 10))
+ return 65536;
+ return V;
+}
+
// A helper function for the SORT() command.
static std::function<bool(InputSectionBase *, InputSectionBase *)>
getComparator(SortSectionPolicy K) {
@@ -449,7 +462,7 @@ void LinkerScript::fabricateDefaultCommands() {
// The Sections with -T<section> have been sorted in order of ascending
// address. We must lower StartAddr if the lowest -T<section address> as
// calls to setDot() must be monotonically increasing.
- for (auto& KV : Config->SectionStartMap)
+ for (auto &KV : Config->SectionStartMap)
StartAddr = std::min(StartAddr, KV.second);
Commands.push_back(make<SymbolAssignment>(
@@ -739,7 +752,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
Cmd->MemRegion = findMemoryRegion(Cmd);
// Handle align (e.g. ".foo : ALIGN(16) { ... }").
if (Cmd->AlignExpr)
- Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
+ Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
}
}
@@ -1071,7 +1084,7 @@ template <class ELFT> void OutputSectionCommand::finalize() {
}
if ((Sec->Flags & SHF_LINK_ORDER)) {
- std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
+ std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition);
for (int I = 0, N = Sections.size(); I < N; ++I)
*ScriptSections[I] = Sections[I];
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp
index e0c7d8cd8b1b..2b2a95c47cf9 100644
--- a/ELF/MapFile.cpp
+++ b/ELF/MapFile.cpp
@@ -55,7 +55,7 @@ template <class ELFT> std::vector<DefinedRegular *> getSymbols() {
for (SymbolBody *B : File->getSymbols())
if (B->File == File && !B->isSection())
if (auto *Sym = dyn_cast<DefinedRegular>(B))
- if (Sym->Section)
+ if (Sym->Section && Sym->Section->Live)
V.push_back(Sym);
return V;
}
diff --git a/ELF/MapFile.h b/ELF/MapFile.h
index 68d8ba8d4a04..460848ff24d3 100644
--- a/ELF/MapFile.h
+++ b/ELF/MapFile.h
@@ -17,7 +17,7 @@ namespace elf {
struct OutputSectionCommand;
template <class ELFT>
void writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script);
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/Memory.h b/ELF/Memory.h
index e5a04ed1e5a8..4000f2f9f1c9 100644
--- a/ELF/Memory.h
+++ b/ELF/Memory.h
@@ -61,7 +61,7 @@ inline void freeArena() {
Alloc->reset();
BAlloc.Reset();
}
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/Options.td b/ELF/Options.td
index 29e14c530c6a..9c78608118cc 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -104,6 +104,8 @@ def export_dynamic_symbol: S<"export-dynamic-symbol">,
def fatal_warnings: F<"fatal-warnings">,
HelpText<"Treat warnings as errors">;
+def filter: J<"filter=">, HelpText<"Set DT_FILTER field to the specified name">;
+
def fini: S<"fini">, MetaVarName<"<symbol>">,
HelpText<"Specify a finalizer function">;
@@ -305,6 +307,7 @@ def alias_exclude_libs: J<"exclude-libs=">, Alias<exclude_libs>;
def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
Alias<export_dynamic_symbol>;
+def alias_filter: Separate<["-"], "F">, Alias<filter>;
def alias_fini_fini: J<"fini=">, Alias<fini>;
def alias_format_b: S<"b">, Alias<format>;
def alias_hash_style_hash_style: J<"hash-style=">, Alias<hash_style>;
@@ -339,6 +342,7 @@ def alias_Ttext_segment: S<"Ttext-segment">, Alias<Ttext>;
def alias_Ttext_segment_eq: J<"Ttext-segment=">, Alias<Ttext>;
def alias_undefined_eq: J<"undefined=">, Alias<undefined>;
def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
+def alias_version_script_eq: J<"version-script=">, Alias<version_script>;
def alias_version_V: Flag<["-"], "V">, Alias<version>;
def alias_wrap_wrap: J<"wrap=">, Alias<wrap>;
@@ -406,6 +410,3 @@ def EL : F<"EL">;
def G: JoinedOrSeparate<["-"], "G">;
def Qy : F<"Qy">;
-// Aliases for ignored options
-def alias_version_script_version_script: J<"version-script=">,
- Alias<version_script>;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index d6ae5dcae167..abe548165866 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -222,16 +222,16 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
if (Sec) {
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
- error("incompatible section flags for " + Sec->Name +
- "\n>>> " + toString(IS) + ": 0x" + utohexstr(IS->Flags) +
+ error("incompatible section flags for " + Sec->Name + "\n>>> " +
+ toString(IS) + ": 0x" + utohexstr(IS->Flags) +
"\n>>> output section " + Sec->Name + ": 0x" +
utohexstr(Sec->Flags));
if (Sec->Type != IS->Type) {
if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type))
Sec->Type = SHT_PROGBITS;
else
- error("section type mismatch for " + IS->Name +
- "\n>>> " + toString(IS) + ": " +
+ error("section type mismatch for " + IS->Name + "\n>>> " +
+ toString(IS) + ": " +
getELFSectionTypeName(Config->EMachine, IS->Type) +
"\n>>> output section " + Sec->Name + ": " +
getELFSectionTypeName(Config->EMachine, Sec->Type));
diff --git a/ELF/OutputSections.h b/ELF/OutputSections.h
index 68ee066a13da..68b46ebf6a7b 100644
--- a/ELF/OutputSections.h
+++ b/ELF/OutputSections.h
@@ -111,8 +111,8 @@ struct SectionKey {
uint64_t Flags;
uint32_t Alignment;
};
-}
-}
+} // namespace elf
+} // namespace lld
namespace llvm {
template <> struct DenseMapInfo<lld::elf::SectionKey> {
static lld::elf::SectionKey getEmptyKey();
@@ -121,7 +121,7 @@ template <> struct DenseMapInfo<lld::elf::SectionKey> {
static bool isEqual(const lld::elf::SectionKey &LHS,
const lld::elf::SectionKey &RHS);
};
-}
+} // namespace llvm
namespace lld {
namespace elf {
@@ -150,5 +150,4 @@ extern std::vector<OutputSectionCommand *> OutputSectionCommands;
} // namespace elf
} // namespace lld
-
#endif
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 52dbe4b583d0..e5fcb2dcc582 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -276,7 +276,7 @@ handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C,
} else {
C.Relocations.push_back(
{Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
- Offset, Addend, &Body});
+ Offset, Addend, &Body});
}
return Target->TlsGdRelaxSkip;
}
@@ -1000,16 +1000,20 @@ void ThunkCreator::mergeThunks() {
}
}
-ThunkSection *ThunkCreator::getOSThunkSec(OutputSection *OS,
+static uint32_t findEndOfFirstNonExec(OutputSectionCommand &Cmd) {
+ for (BaseCommand *Base : Cmd.Commands)
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
+ for (auto *IS : ISD->Sections)
+ if ((IS->Flags & SHF_EXECINSTR) == 0)
+ return IS->OutSecOff + IS->getSize();
+ return 0;
+}
+
+ThunkSection *ThunkCreator::getOSThunkSec(OutputSectionCommand *Cmd,
std::vector<InputSection *> *ISR) {
if (CurTS == nullptr) {
- uint32_t Off = 0;
- for (auto *IS : OS->Sections) {
- Off = IS->OutSecOff + IS->getSize();
- if ((IS->Flags & SHF_EXECINSTR) == 0)
- break;
- }
- CurTS = addThunkSection(OS, ISR, Off);
+ uint32_t Off = findEndOfFirstNonExec(*Cmd);
+ CurTS = addThunkSection(Cmd->Sec, ISR, Off);
}
return CurTS;
}
@@ -1024,7 +1028,7 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
OutputSectionCommand *C = Script->getCmd(TOS);
std::vector<InputSection *> *Range = nullptr;
for (BaseCommand *BC : C->Commands)
- if (auto *ISD = dyn_cast<InputSectionDescription> (BC)) {
+ if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
InputSection *first = ISD->Sections.front();
InputSection *last = ISD->Sections.back();
if (IS->OutSecOff >= first->OutSecOff &&
@@ -1046,7 +1050,6 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
return TS;
}
-
std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
uint32_t Type) {
auto Res = ThunkedSymbols.insert({&Body, std::vector<Thunk *>()});
@@ -1066,7 +1069,7 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
// InputSectionDescription::Sections.
void ThunkCreator::forEachExecInputSection(
ArrayRef<OutputSectionCommand *> OutputSections,
- std::function<void(OutputSection *, std::vector<InputSection *> *,
+ std::function<void(OutputSectionCommand *, std::vector<InputSection *> *,
InputSection *)>
Fn) {
for (OutputSectionCommand *Cmd : OutputSections) {
@@ -1077,7 +1080,7 @@ void ThunkCreator::forEachExecInputSection(
if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
CurTS = nullptr;
for (InputSection *IS : ISD->Sections)
- Fn(OS, &ISD->Sections, IS);
+ Fn(Cmd, &ISD->Sections, IS);
}
}
}
@@ -1103,32 +1106,32 @@ bool ThunkCreator::createThunks(
// We separate the creation of ThunkSections from the insertion of the
// ThunkSections back into the OutputSection as ThunkSections are not always
// inserted into the same OutputSection as the caller.
- forEachExecInputSection(
- OutputSections, [&](OutputSection *OS, std::vector<InputSection*> *ISR,
- InputSection *IS) {
- for (Relocation &Rel : IS->Relocations) {
- SymbolBody &Body = *Rel.Sym;
- if (Thunks.find(&Body) != Thunks.end() ||
- !Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
- continue;
- Thunk *T;
- bool IsNew;
- std::tie(T, IsNew) = getThunk(Body, Rel.Type);
- if (IsNew) {
- // Find or create a ThunkSection for the new Thunk
- ThunkSection *TS;
- if (auto *TIS = T->getTargetInputSection())
- TS = getISThunkSec(TIS, OS);
- else
- TS = getOSThunkSec(OS, ISR);
- TS->addThunk(T);
- Thunks[T->ThunkSym] = T;
- }
- // Redirect relocation to Thunk, we never go via the PLT to a Thunk
- Rel.Sym = T->ThunkSym;
- Rel.Expr = fromPlt(Rel.Expr);
- }
- });
+ forEachExecInputSection(OutputSections, [&](OutputSectionCommand *Cmd,
+ std::vector<InputSection *> *ISR,
+ InputSection *IS) {
+ for (Relocation &Rel : IS->Relocations) {
+ SymbolBody &Body = *Rel.Sym;
+ if (Thunks.find(&Body) != Thunks.end() ||
+ !Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
+ continue;
+ Thunk *T;
+ bool IsNew;
+ std::tie(T, IsNew) = getThunk(Body, Rel.Type);
+ if (IsNew) {
+ // Find or create a ThunkSection for the new Thunk
+ ThunkSection *TS;
+ if (auto *TIS = T->getTargetInputSection())
+ TS = getISThunkSec(TIS, Cmd->Sec);
+ else
+ TS = getOSThunkSec(Cmd, ISR);
+ TS->addThunk(T);
+ Thunks[T->ThunkSym] = T;
+ }
+ // Redirect relocation to Thunk, we never go via the PLT to a Thunk
+ Rel.Sym = T->ThunkSym;
+ Rel.Expr = fromPlt(Rel.Expr);
+ }
+ });
// Merge all created synthetic ThunkSections back into OutputSection
mergeThunks();
++Pass;
diff --git a/ELF/Relocations.h b/ELF/Relocations.h
index fc3e3444ac24..ea046d248474 100644
--- a/ELF/Relocations.h
+++ b/ELF/Relocations.h
@@ -103,7 +103,8 @@ struct RelExprMaskBuilder<Head, Tail...> {
// RelExpr's as a constant bit mask and test for membership with a
// couple cheap bitwise operations.
template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) {
- assert(0 <= Expr && (int)Expr < 64 && "RelExpr is too large for 64-bit mask!");
+ assert(0 <= Expr && (int)Expr < 64 &&
+ "RelExpr is too large for 64-bit mask!");
return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build();
}
@@ -133,12 +134,12 @@ public:
private:
void mergeThunks();
- ThunkSection *getOSThunkSec(OutputSection *OS,
+ ThunkSection *getOSThunkSec(OutputSectionCommand *Cmd,
std::vector<InputSection *> *ISR);
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
void forEachExecInputSection(
ArrayRef<OutputSectionCommand *> OutputSections,
- std::function<void(OutputSection *, std::vector<InputSection *> *,
+ std::function<void(OutputSectionCommand *, std::vector<InputSection *> *,
InputSection *)>
Fn);
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
@@ -178,7 +179,7 @@ template <class ELFT>
static inline int64_t getAddend(const typename ELFT::Rela &Rel) {
return Rel.r_addend;
}
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/ScriptParser.cpp b/ELF/ScriptParser.cpp
index 72940ca0cfd4..b3847081697c 100644
--- a/ELF/ScriptParser.cpp
+++ b/ELF/ScriptParser.cpp
@@ -113,6 +113,12 @@ private:
};
} // namespace
+static StringRef unquote(StringRef S) {
+ if (S.startswith("\""))
+ return S.substr(1, S.size() - 2);
+ return S;
+}
+
static bool isUnderSysroot(StringRef Path) {
if (Config->Sysroot == "")
return false;
@@ -1103,6 +1109,10 @@ void ScriptParser::readVersionDeclaration(StringRef VerStr) {
expect(";");
}
+static bool hasWildcard(StringRef S) {
+ return S.find_first_of("?*[") != StringRef::npos;
+}
+
// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
ScriptParser::readSymbols() {
diff --git a/ELF/Strings.cpp b/ELF/Strings.cpp
index 2e88bfba0fc1..bca86384002d 100644
--- a/ELF/Strings.cpp
+++ b/ELF/Strings.cpp
@@ -38,29 +38,6 @@ bool StringMatcher::match(StringRef S) const {
return false;
}
-// If an input string is in the form of "foo.N" where N is a number,
-// return N. Otherwise, returns 65536, which is one greater than the
-// lowest priority.
-int elf::getPriority(StringRef S) {
- size_t Pos = S.rfind('.');
- if (Pos == StringRef::npos)
- return 65536;
- int V;
- if (!to_integer(S.substr(Pos + 1), V, 10))
- return 65536;
- return V;
-}
-
-bool elf::hasWildcard(StringRef S) {
- return S.find_first_of("?*[") != StringRef::npos;
-}
-
-StringRef elf::unquote(StringRef S) {
- if (!S.startswith("\""))
- return S;
- return S.substr(1, S.size() - 2);
-}
-
// Converts a hex string (e.g. "deadbeef") to a vector.
std::vector<uint8_t> elf::parseHex(StringRef S) {
std::vector<uint8_t> Hex;
diff --git a/ELF/Strings.h b/ELF/Strings.h
index fd1aa40539d2..68ccafa2ff17 100644
--- a/ELF/Strings.h
+++ b/ELF/Strings.h
@@ -21,11 +21,8 @@
namespace lld {
namespace elf {
-int getPriority(StringRef S);
-bool hasWildcard(StringRef S);
std::vector<uint8_t> parseHex(StringRef S);
bool isValidCIdentifier(StringRef S);
-StringRef unquote(StringRef S);
// This is a lazy version of StringRef. String size is computed lazily
// when it is needed. It is more efficient than StringRef to instantiate
@@ -76,7 +73,7 @@ llvm::Optional<std::string> demangle(StringRef Name);
inline ArrayRef<uint8_t> toArrayRef(StringRef S) {
return {(const uint8_t *)S.data(), S.size()};
}
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index c802d74b8ff8..83091057ebed 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -172,8 +172,8 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) {
}
// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
-template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias,
- StringRef Name) {
+template <class ELFT>
+void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, StringRef Name) {
SymbolBody *B = find(Name);
if (!B) {
error("-defsym: undefined symbol: " + Name);
@@ -211,13 +211,6 @@ static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
// Find an existing symbol or create and insert a new one.
template <class ELFT>
std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
- // <name>@@<version> means the symbol is the default version. In that
- // case symbol <name> must exist and <name>@@<version> will be used to
- // resolve references to <name>.
- size_t Pos = Name.find("@@");
- if (Pos != StringRef::npos)
- Name = Name.take_front(Pos);
-
auto P = Symtab.insert(
{CachedHashStringRef(Name), SymIndex((int)SymVector.size(), false)});
SymIndex &V = P.first->second;
@@ -400,9 +393,8 @@ static void warnOrError(const Twine &Msg) {
}
static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) {
- warnOrError("duplicate symbol: " + toString(*Sym) +
- "\n>>> defined in " + toString(Sym->File) +
- "\n>>> defined in " + toString(NewFile));
+ warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
+ toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
}
template <class ELFT>
@@ -680,7 +672,8 @@ template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() {
// Set symbol versions to symbols. This function handles patterns
// containing no wildcard characters.
template <class ELFT>
-void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
+void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver,
+ uint16_t VersionId,
StringRef VersionName) {
if (Ver.HasWildcard)
return;
@@ -724,13 +717,35 @@ void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver,
B->symbol()->VersionId = VersionId;
}
+static bool isDefaultVersion(SymbolBody *B) {
+ return B->isInCurrentDSO() && B->getName().find("@@") != StringRef::npos;
+}
+
// This function processes version scripts by updating VersionId
// member of symbols.
template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
+ // Symbol themselves might know their versions because symbols
+ // can contain versions in the form of <name>@<version>.
+ // Let them parse and update their names to exclude version suffix.
+ for (Symbol *Sym : SymVector) {
+ SymbolBody *Body = Sym->body();
+ bool IsDefault = isDefaultVersion(Body);
+ Body->parseSymbolVersion();
+
+ if (!IsDefault)
+ continue;
+
+ // <name>@@<version> means the symbol is the default version. If that's the
+ // case, the symbol is not used only to resolve <name> of version <version>
+ // but also undefined unversioned symbols with name <name>.
+ SymbolBody *S = find(Body->getName());
+ if (S && S->isUndefined())
+ S->copy(Body);
+ }
+
// Handle edge cases first.
handleAnonymousVersion();
-
// Now we have version definitions, so we need to set version ids to symbols.
// Each version definition has a glob pattern, and all symbols that match
// with the pattern get that version.
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 1d17f57f0c30..c69007e781a6 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -94,7 +94,7 @@ static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) {
if (D.isTls() && !Config->Relocatable) {
if (!Out::TlsPhdr)
fatal(toString(D.File) +
- " has a STT_TLS symbol but doesn't have a PT_TLS section");
+ " has an STT_TLS symbol but doesn't have an SHF_TLS section");
return VA - Out::TlsPhdr->p_vaddr;
}
return VA;
diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
index fd724fac327c..4bbec4ab34bd 100644
--- a/ELF/SyntheticSections.cpp
+++ b/ELF/SyntheticSections.cpp
@@ -662,7 +662,12 @@ bool GotSection::empty() const {
return NumEntries == 0 && !HasGotOffRel;
}
-void GotSection::writeTo(uint8_t *Buf) { relocateAlloc(Buf, Buf + Size); }
+void GotSection::writeTo(uint8_t *Buf) {
+ // Buf points to the start of this section's buffer,
+ // whereas InputSectionBase::relocateAlloc() expects its argument
+ // to point to the start of the output section.
+ relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
+}
MipsGotSection::MipsGotSection()
: SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
@@ -812,9 +817,7 @@ unsigned MipsGotSection::getLocalEntriesNum() const {
LocalEntries32.size();
}
-void MipsGotSection::finalizeContents() {
- updateAllocSize();
-}
+void MipsGotSection::finalizeContents() { updateAllocSize(); }
void MipsGotSection::updateAllocSize() {
PageEntriesNum = 0;
@@ -838,9 +841,7 @@ bool MipsGotSection::empty() const {
return Config->Relocatable;
}
-uint64_t MipsGotSection::getGp() const {
- return ElfSym::MipsGp->getVA(0);
-}
+uint64_t MipsGotSection::getGp() const { return ElfSym::MipsGp->getVA(0); }
static uint64_t readUint(uint8_t *Buf) {
if (Config->Is64)
@@ -1019,6 +1020,8 @@ DynamicSection<ELFT>::DynamicSection()
template <class ELFT> void DynamicSection<ELFT>::addEntries() {
// Add strings to .dynstr early so that .dynstr's size will be
// fixed early.
+ for (StringRef S : Config->FilterList)
+ add({DT_FILTER, InX::DynStrTab->addString(S)});
for (StringRef S : Config->AuxiliaryList)
add({DT_AUXILIARY, InX::DynStrTab->addString(S)});
if (!Config->Rpath.empty())
@@ -1607,7 +1610,7 @@ HashTableSection<ELFT>::HashTableSection()
template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
- unsigned NumEntries = 2; // nbucket and nchain.
+ unsigned NumEntries = 2; // nbucket and nchain.
NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
// Create as many buckets as there are symbols.
@@ -1926,9 +1929,7 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
StringPool.write(Buf);
}
-bool GdbIndexSection::empty() const {
- return !Out::DebugInfo;
-}
+bool GdbIndexSection::empty() const { return !Out::DebugInfo; }
template <class ELFT>
EhFrameHeader<ELFT>::EhFrameHeader()
@@ -2211,9 +2212,7 @@ void MergeSyntheticSection::finalizeContents() {
finalizeNoTailMerge();
}
-size_t MergeSyntheticSection::getSize() const {
- return Builder.getSize();
-}
+size_t MergeSyntheticSection::getSize() const { return Builder.getSize(); }
// This function decompresses compressed sections and scans over the input
// sections to create mergeable synthetic sections. It removes
@@ -2312,7 +2311,7 @@ ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
}
void ThunkSection::addThunk(Thunk *T) {
- uint64_t Off = alignTo(Size, T->alignment);
+ uint64_t Off = alignTo(Size, T->Alignment);
T->Offset = Off;
Thunks.push_back(T);
T->addSymbols(*this);
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index c886419971bc..11986efc746f 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -128,6 +128,11 @@ bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
return false;
}
+bool TargetInfo::inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const {
+ return true;
+}
+
void TargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
writeGotPlt(Buf, S);
}
diff --git a/ELF/Target.h b/ELF/Target.h
index 5914d9bbb7ef..1658a81c9b71 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -51,6 +51,9 @@ public:
// targeting S.
virtual bool needsThunk(RelExpr Expr, uint32_t RelocType,
const InputFile *File, const SymbolBody &S) const;
+ // Return true if we can reach Dst from Src with Relocation RelocType
+ virtual bool inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const;
virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
const uint8_t *Loc) const = 0;
virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0;
@@ -154,6 +157,6 @@ static void checkAlignment(uint8_t *Loc, uint64_t V, uint32_t Type) {
lld::toString(Type));
}
} // namespace elf
-}
+} // namespace lld
#endif
diff --git a/ELF/Threads.h b/ELF/Threads.h
index e01afd4d3fc9..9feb8683976c 100644
--- a/ELF/Threads.h
+++ b/ELF/Threads.h
@@ -82,7 +82,7 @@ inline void parallelForEachN(size_t Begin, size_t End,
else
for_each_n(llvm::parallel::seq, Begin, End, Fn);
}
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/ELF/Thunks.cpp b/ELF/Thunks.cpp
index cae31027e557..07289d0efdf1 100644
--- a/ELF/Thunks.cpp
+++ b/ELF/Thunks.cpp
@@ -72,9 +72,7 @@ public:
class ThumbV7ABSLongThunk final : public Thunk {
public:
- ThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {
- alignment = 2;
- }
+ ThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; }
uint32_t size() const override { return 10; }
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
@@ -84,9 +82,7 @@ public:
class ThumbV7PILongThunk final : public Thunk {
public:
- ThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {
- alignment = 2;
- }
+ ThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; }
uint32_t size() const override { return 12; }
void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
@@ -218,10 +214,10 @@ bool ThumbV7PILongThunk::isCompatibleWith(uint32_t RelocType) const {
// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const {
uint64_t S = Destination.getVA();
- write32(Buf, 0x3c190000, Config->Endianness); // lui $25, %hi(func)
+ write32(Buf, 0x3c190000, Config->Endianness); // lui $25, %hi(func)
write32(Buf + 4, 0x08000000 | (S >> 2), Config->Endianness); // j func
- write32(Buf + 8, 0x27390000, Config->Endianness); // addiu $25, $25, %lo(func)
- write32(Buf + 12, 0x00000000, Config->Endianness); // nop
+ write32(Buf + 8, 0x27390000, Config->Endianness); // addiu $25, $25, %lo(func)
+ write32(Buf + 12, 0x00000000, Config->Endianness); // nop
Target->relocateOne(Buf, R_MIPS_HI16, S);
Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
}
@@ -262,9 +258,7 @@ static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) {
fatal("unrecognized relocation type");
}
-static Thunk *addThunkMips(SymbolBody &S) {
- return make<MipsThunk>(S);
-}
+static Thunk *addThunkMips(SymbolBody &S) { return make<MipsThunk>(S); }
Thunk *addThunk(uint32_t RelocType, SymbolBody &S) {
if (Config->EMachine == EM_ARM)
diff --git a/ELF/Thunks.h b/ELF/Thunks.h
index 00b6b2cf2994..21eba699fe4f 100644
--- a/ELF/Thunks.h
+++ b/ELF/Thunks.h
@@ -50,7 +50,7 @@ public:
const SymbolBody &Destination;
SymbolBody *ThunkSym;
uint64_t Offset;
- uint32_t alignment = 4;
+ uint32_t Alignment = 4;
};
// For a Relocation to symbol S create a Thunk to be added to a synthetic
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index bf43ee5c5f91..1853f99bc600 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -257,7 +257,6 @@ template <class ELFT> void Writer<ELFT>::run() {
if (ErrorCount)
return;
-
// Handle -Map option.
writeMapFile<ELFT>(OutputSectionCommands);
if (ErrorCount)
@@ -1331,7 +1330,7 @@ template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
// ARM ABI requires .ARM.exidx to be terminated by some piece of data.
// We have the terminater synthetic section class. Add that at the end.
OutputSectionCommand *Cmd = findSectionCommand(".ARM.exidx");
- if (!Cmd || Cmd->Commands.empty() || Config->Relocatable)
+ if (!Cmd || !Cmd->Sec || Config->Relocatable)
return;
auto *Sentinel = make<ARMExidxSentinelSection>();
@@ -1392,7 +1391,8 @@ OutputSectionCommand *Writer<ELFT>::findSectionCommand(StringRef Name) {
return nullptr;
}
-template <class ELFT> OutputSection *Writer<ELFT>::findSectionInScript(StringRef Name) {
+template <class ELFT>
+OutputSection *Writer<ELFT>::findSectionInScript(StringRef Name) {
if (OutputSectionCommand *Cmd = findSectionCommand(Name))
return Cmd->Sec;
return nullptr;
diff --git a/ELF/Writer.h b/ELF/Writer.h
index e935b6419de6..7fa56bea1c35 100644
--- a/ELF/Writer.h
+++ b/ELF/Writer.h
@@ -55,7 +55,7 @@ uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
llvm::StringRef FileName);
bool isMipsN32Abi(const InputFile *F);
-}
-}
+} // namespace elf
+} // namespace lld
#endif
diff --git a/docs/windows_support.rst b/docs/windows_support.rst
index 56df45b32633..6b06d29afafd 100644
--- a/docs/windows_support.rst
+++ b/docs/windows_support.rst
@@ -29,8 +29,6 @@ Development status
Driver
:good:`Mostly done`. Some exotic command line options that are not usually
used for application develompent, such as ``/DRIVER``, are not supported.
- Options for Windows 8 app store are not recognized too
- (e.g. ``/APPCONTAINER``).
Linking against DLL
:good:`Done`. LLD can read import libraries needed to link against DLL. Both
@@ -44,8 +42,7 @@ Creating DLL
:good:`Done`. LLD creates a DLL if ``/DLL`` option is given. Exported
functions can be specified either via command line (``/EXPORT``) or via
module-definition file (.def). Both export-by-name and export-by-ordinal are
- supported. LLD uses Microsoft ``lib.exe`` tool to create an import library
- file.
+ supported.
Windows resource files support
:good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF
diff --git a/test/COFF/Inputs/default.def b/test/COFF/Inputs/default.def
new file mode 100644
index 000000000000..1d59beebbb26
--- /dev/null
+++ b/test/COFF/Inputs/default.def
@@ -0,0 +1,2 @@
+EXPORTS
+ f
diff --git a/test/COFF/Inputs/extension.def b/test/COFF/Inputs/extension.def
new file mode 100644
index 000000000000..d93f0dc1ecce
--- /dev/null
+++ b/test/COFF/Inputs/extension.def
@@ -0,0 +1,3 @@
+LIBRARY library.ext
+EXPORTS
+ f
diff --git a/test/COFF/Inputs/named.def b/test/COFF/Inputs/named.def
new file mode 100644
index 000000000000..07c8622189db
--- /dev/null
+++ b/test/COFF/Inputs/named.def
@@ -0,0 +1,3 @@
+LIBRARY library
+EXPORTS
+ f
diff --git a/test/COFF/Inputs/object.s b/test/COFF/Inputs/object.s
new file mode 100644
index 000000000000..b70599385591
--- /dev/null
+++ b/test/COFF/Inputs/object.s
@@ -0,0 +1,13 @@
+
+ .text
+
+ .def f
+ .scl 2
+ .type 32
+ .endef
+ .global f
+f:
+ retq $0
+
+ .section .drectve,"rd"
+ .ascii " /EXPORT:f"
diff --git a/test/COFF/Inputs/pdb-type-server-simple-a.yaml b/test/COFF/Inputs/pdb-type-server-simple-a.yaml
new file mode 100644
index 000000000000..78c68168127b
--- /dev/null
+++ b/test/COFF/Inputs/pdb-type-server-simple-a.yaml
@@ -0,0 +1,255 @@
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .drectve
+ Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+ Alignment: 1
+ SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_OBJNAME
+ ObjNameSym:
+ Signature: 0
+ ObjectName: 'C:\src\llvm-project\build\a.obj'
+ - Kind: S_COMPILE3
+ Compile3Sym:
+ Flags: [ SecurityChecks, HotPatch ]
+ Machine: X64
+ FrontendMajor: 19
+ FrontendMinor: 0
+ FrontendBuild: 24215
+ FrontendQFE: 1
+ BackendMajor: 19
+ BackendMinor: 0
+ BackendBuild: 24215
+ BackendQFE: 1
+ Version: 'Microsoft (R) Optimizing Compiler'
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ CodeSize: 27
+ DbgStart: 4
+ DbgEnd: 22
+ FunctionType: 4098
+ Flags: [ ]
+ DisplayName: main
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 56
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_REGREL32
+ RegRelativeSym:
+ Offset: 32
+ Type: 4102
+ Register: RSP
+ VarName: f
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 27
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\a.c'
+ Lines:
+ - Offset: 0
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 4
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 12
+ LineStart: 5
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 22
+ LineStart: 6
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !Symbols
+ Records:
+ - Kind: S_UDT
+ UDTSym:
+ Type: 4102
+ UDTName: Foo
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\a.c'
+ Kind: MD5
+ Checksum: BF69E7E933074E1B7ED1FE8FB395965B
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\a.c'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4107
+ Relocations:
+ - VirtualAddress: 152
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 156
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 224
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 228
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: '.debug$T'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Types:
+ - Kind: LF_TYPESERVER2
+ TypeServer2:
+ Guid: '{41414141-4141-4141-4141-414141414141}'
+ Age: 1
+ Name: 'C:\src\llvm-project\build\ts.pdb'
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC38C74424202A000000488D4C2420E8000000004883C438C3
+ Relocations:
+ - VirtualAddress: 18
+ SymbolName: g
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '0104010004620000'
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 000000001B00000000000000
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 4
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 8
+ SymbolName: '$unwind$main'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+symbols:
+ - Name: .drectve
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 47
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 388
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.debug$T'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 64
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 27
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1939996292
+ Number: 0
+ - Name: g
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: main
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: '$LN3'
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_LABEL
+ - Name: .xdata
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 931692337
+ Number: 0
+ - Name: '$unwind$main'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 12
+ NumberOfRelocations: 3
+ NumberOfLinenumbers: 0
+ CheckSum: 567356797
+ Number: 0
+ - Name: '$pdata$main'
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+...
diff --git a/test/COFF/Inputs/pdb-type-server-simple-b.yaml b/test/COFF/Inputs/pdb-type-server-simple-b.yaml
new file mode 100644
index 000000000000..56e97d530894
--- /dev/null
+++ b/test/COFF/Inputs/pdb-type-server-simple-b.yaml
@@ -0,0 +1,173 @@
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .drectve
+ Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+ Alignment: 1
+ SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_OBJNAME
+ ObjNameSym:
+ Signature: 0
+ ObjectName: 'C:\src\llvm-project\build\b.obj'
+ - Kind: S_COMPILE3
+ Compile3Sym:
+ Flags: [ SecurityChecks, HotPatch ]
+ Machine: X64
+ FrontendMajor: 19
+ FrontendMinor: 0
+ FrontendBuild: 24215
+ FrontendQFE: 1
+ BackendMajor: 19
+ BackendMinor: 0
+ BackendBuild: 24215
+ BackendQFE: 1
+ Version: 'Microsoft (R) Optimizing Compiler'
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ CodeSize: 13
+ DbgStart: 5
+ DbgEnd: 12
+ FunctionType: 4099
+ Flags: [ ]
+ DisplayName: g
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 0
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_REGREL32
+ RegRelativeSym:
+ Offset: 8
+ Type: 4097
+ Register: RSP
+ VarName: p
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 13
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\b.c'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !Symbols
+ Records:
+ - Kind: S_UDT
+ UDTSym:
+ Type: 4102
+ UDTName: Foo
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\b.c'
+ Kind: MD5
+ Checksum: DDF8FD35CD67990C5D4147516BE10D0C
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\b.c'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4111
+ Relocations:
+ - VirtualAddress: 152
+ SymbolName: g
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 156
+ SymbolName: g
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 220
+ SymbolName: g
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 224
+ SymbolName: g
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: '.debug$T'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Types:
+ - Kind: LF_TYPESERVER2
+ TypeServer2:
+ Guid: '{41414141-4141-4141-4141-414141414141}'
+ Age: 1
+ Name: 'C:\src\llvm-project\build\ts.pdb'
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 48894C2408488B4424088B00C3
+symbols:
+ - Name: .drectve
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 47
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 360
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.debug$T'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 64
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 13
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3246683207
+ Number: 0
+ - Name: g
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/Inputs/pdb-type-server-simple-ts.yaml b/test/COFF/Inputs/pdb-type-server-simple-ts.yaml
new file mode 100644
index 000000000000..73496571ac72
--- /dev/null
+++ b/test/COFF/Inputs/pdb-type-server-simple-ts.yaml
@@ -0,0 +1,147 @@
+---
+MSF:
+ SuperBlock:
+ BlockSize: 4096
+ FreeBlockMap: 1
+ NumBlocks: 19
+ NumDirectoryBytes: 64
+ Unknown1: 0
+ BlockMapAddr: 17
+ NumDirectoryBlocks: 1
+ DirectoryBlocks: [ 16 ]
+ NumStreams: 0
+ FileSize: 77824
+PdbStream:
+ Age: 1
+ Guid: '{41414141-4141-4141-4141-414141414141}'
+ Signature: 1500053944
+ Features: [ VC140 ]
+ Version: VC70
+TpiStream:
+ Version: VC80
+ Records:
+ - Kind: LF_STRUCTURE
+ Class:
+ MemberCount: 0
+ Options: [ None, ForwardReference, HasUniqueName ]
+ FieldList: 0
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 0
+ - Kind: LF_POINTER
+ Pointer:
+ ReferentType: 4096
+ Attrs: 65548
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ 4097 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 1
+ ArgumentList: 4098
+ - Kind: LF_POINTER
+ Pointer:
+ ReferentType: 4099
+ Attrs: 65548
+ - Kind: LF_FIELDLIST
+ FieldList:
+ - Kind: LF_MEMBER
+ DataMember:
+ Attrs: 3
+ Type: 116
+ FieldOffset: 0
+ Name: x
+ - Kind: LF_STRUCTURE
+ Class:
+ MemberCount: 1
+ Options: [ None, HasUniqueName ]
+ FieldList: 4101
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 4
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ 0 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4103
+IpiStream:
+ Version: VC80
+ Records:
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'c:\src\llvm-project\build\a.c'
+ - Kind: LF_UDT_SRC_LINE
+ UdtSourceLine:
+ UDT: 4102
+ SourceFile: 4096
+ LineNumber: 1
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4104
+ Name: main
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4099
+ Name: g
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: '-c -Zi -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
+ - Kind: LF_SUBSTR_LIST
+ StringList:
+ StringIndices: [ 4102 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4103
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: a.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\ts.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4100, 4101, 4105, 4106, 4104 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'c:\src\llvm-project\build\b.c'
+ - Kind: LF_UDT_SRC_LINE
+ UdtSourceLine:
+ UDT: 4102
+ SourceFile: 4108
+ LineNumber: 1
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: b.c
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4100, 4101, 4110, 4106, 4104 ]
+...
diff --git a/test/COFF/common.test b/test/COFF/common.test
index 007cfcfb6f92..4a00153f3e93 100644
--- a/test/COFF/common.test
+++ b/test/COFF/common.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: yaml2obj %s > %t.obj
# RUN: lld-link /out:%t.exe /entry:main %t.obj %t.obj
# RUN: llvm-objdump -d %t.exe | FileCheck %s
diff --git a/test/COFF/conflict.test b/test/COFF/conflict.test
index a634c7185675..ae8e6c8ad327 100644
--- a/test/COFF/conflict.test
+++ b/test/COFF/conflict.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: yaml2obj < %s > %t1.obj
# RUN: yaml2obj < %s > %t2.obj
# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
diff --git a/test/COFF/constant.test b/test/COFF/constant.test
index 3c8956beac9c..02d6b3e2ccae 100644
--- a/test/COFF/constant.test
+++ b/test/COFF/constant.test
@@ -1,3 +1,4 @@
+REQUIRES: x86
RUN: mkdir -p %t
RUN: llvm-mc -triple i686-unknown-windows-msvc -filetype obj -o %t/import.o %S/Inputs/constant-import.s
RUN: llc -mtriple i686-unknown-windows-msvc -filetype obj -o %t/export.o %S/Inputs/constant-export.ll
diff --git a/test/COFF/def-export-stdcall.s b/test/COFF/def-export-stdcall.s
index cdca7ae76acf..d7700d9e9535 100644
--- a/test/COFF/def-export-stdcall.s
+++ b/test/COFF/def-export-stdcall.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj
# RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall" > %t.def
# RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
diff --git a/test/COFF/delayimports32.test b/test/COFF/delayimports32.test
index 9c4fcae5b6a5..53aadbb6a185 100644
--- a/test/COFF/delayimports32.test
+++ b/test/COFF/delayimports32.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
# RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \
diff --git a/test/COFF/entry-mangled.test b/test/COFF/entry-mangled.test
index acf54ba07973..1140e8298fbc 100644
--- a/test/COFF/entry-mangled.test
+++ b/test/COFF/entry-mangled.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: yaml2obj < %s > %t.obj
# RUN: lld-link /out:%t.exe /entry:main %t.obj
# RUN: llvm-as -o %t.lto.obj %S/Inputs/entry-mangled.ll
diff --git a/test/COFF/entrylib.ll b/test/COFF/entrylib.ll
index 4ffa42c44a3e..602b4ff63336 100644
--- a/test/COFF/entrylib.ll
+++ b/test/COFF/entrylib.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as -o %t.obj %s
; RUN: rm -f %t.lib
; RUN: llvm-ar cru %t.lib %t.obj
diff --git a/test/COFF/implib-name.test b/test/COFF/implib-name.test
new file mode 100644
index 000000000000..81b5b258483f
--- /dev/null
+++ b/test/COFF/implib-name.test
@@ -0,0 +1,71 @@
+# RUN: mkdir -p %T
+# RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/named.def /out:%T/library.dll %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.lib
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
+
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+CHECK-DEFAULT-DLL-EXT: library.dll
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-EXE-EXT
+
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+CHECK-DEFAULT-EXE-EXT: library.exe
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.dll /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.exe /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.lib
+# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
+
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+CHECK-EXTENSION: library.ext
+
+# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/default.def /out:%T/default.dll /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.lib
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
+
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+CHECK-OUTPUT-NAME-DLL: default.dll
+
+# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-EXE
+
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+CHECK-OUTPUT-NAME-EXE: default.exe
+
+# RUN: lld-link /machine:x64 /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-EXE
+
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+CHECK-NODEF-EXE: default.exe
+
+# RUN: lld-link /machine:x64 /dll /out:%T/default.dll %T/object.obj /entry:f /subsystem:CONSOLE
+# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-DLL
+
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+CHECK-NODEF-DLL: default.dll
+
diff --git a/test/COFF/imports.test b/test/COFF/imports.test
index 584c24eb1b76..326bfbebbb05 100644
--- a/test/COFF/imports.test
+++ b/test/COFF/imports.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# Verify that the lld can handle .lib files and emit .idata sections.
#
# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
diff --git a/test/COFF/include-lto.ll b/test/COFF/include-lto.ll
index 6ca32fa71ad1..d5ae546ab719 100644
--- a/test/COFF/include-lto.ll
+++ b/test/COFF/include-lto.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as -o %t.obj %s
; RUN: lld-link /dll /out:%t.dll %t.obj
; RUN: llvm-objdump -d %t.dll | FileCheck %s
diff --git a/test/COFF/msvclto-archive.ll b/test/COFF/msvclto-archive.ll
index 047b19e76ddf..334565a1bef7 100644
--- a/test/COFF/msvclto-archive.ll
+++ b/test/COFF/msvclto-archive.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
;; Make sure we re-create archive files to strip bitcode files.
;; Do not create empty archives because the MSVC linker
diff --git a/test/COFF/msvclto-order.ll b/test/COFF/msvclto-order.ll
index 8991dce4a8d5..6f569af4af0c 100644
--- a/test/COFF/msvclto-order.ll
+++ b/test/COFF/msvclto-order.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: opt -thinlto-bc %s -o %t.obj
; RUN: llc -filetype=obj %S/Inputs/msvclto-order-a.ll -o %T/msvclto-order-a.obj
; RUN: llvm-ar crs %T/msvclto-order-a.lib %T/msvclto-order-a.obj
diff --git a/test/COFF/msvclto.ll b/test/COFF/msvclto.ll
index 7fa9c54711b4..66fabeb80c74 100644
--- a/test/COFF/msvclto.ll
+++ b/test/COFF/msvclto.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as -o %t.obj %s
; RUN: mkdir -p %t.dir
; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
diff --git a/test/COFF/pdb-comdat.test b/test/COFF/pdb-comdat.test
index ea691aec87ad..f85dacdbf4bb 100644
--- a/test/COFF/pdb-comdat.test
+++ b/test/COFF/pdb-comdat.test
@@ -56,7 +56,7 @@ CHECK: flags = has async eh | opt speed
CHECK: 196 | S_END [size = 4]
CHECK: 200 | S_GDATA32 [size = 24] `global`
CHECK: type = 0x0074 (int), addr = 0000:0000
-CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `4106`
+CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A`
CHECK: 232 | S_GPROC32_ID [size = 44] `foo`
CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15
CHECK: debug start = 0, debug end = 14, flags = none
@@ -81,7 +81,7 @@ CHECK: flags = has async eh | opt speed
CHECK: 196 | S_END [size = 4]
CHECK: 200 | S_GDATA32 [size = 24] `global`
CHECK: type = 0x0074 (int), addr = 0000:0000
-CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `4109`
+CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D`
CHECK-NOT: S_GPROC32_ID {{.*}} `foo`
CHECK-LABEL: Mod 0002 | `* Linker *`:
diff --git a/test/COFF/pdb-lib.s b/test/COFF/pdb-lib.s
index ab95f82a2a91..74d987eac814 100644
--- a/test/COFF/pdb-lib.s
+++ b/test/COFF/pdb-lib.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: rm -rf %t && mkdir -p %t && cd %t
# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o foo.obj
# RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj
diff --git a/test/COFF/pdb-symbol-types.yaml b/test/COFF/pdb-symbol-types.yaml
index 8abbc365b34e..2ad6f5b07bf4 100644
--- a/test/COFF/pdb-symbol-types.yaml
+++ b/test/COFF/pdb-symbol-types.yaml
@@ -35,7 +35,7 @@
# CHECK: original type = 0x1004
# CHECK: 240 | S_UDT [size = 12] `Foo`
# CHECK: original type = 0x1004
-# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `4106`
+# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A`
# CHECK-LABEL: Mod 0001 | `* Linker *`:
--- !COFF
diff --git a/test/COFF/pdb-type-server-missing.yaml b/test/COFF/pdb-type-server-missing.yaml
new file mode 100644
index 000000000000..91bb04f5622f
--- /dev/null
+++ b/test/COFF/pdb-type-server-missing.yaml
@@ -0,0 +1,132 @@
+# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
+# adjacent type server PDB. Test that LLD fails gracefully on it.
+
+# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug
+# info in the object with the missing PDB.
+
+# RUN: yaml2obj %s -o %t.obj
+# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
+
+# CHECK: error: Type server PDB was not found
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ CodeSize: 3
+ DbgStart: 0
+ DbgEnd: 2
+ FunctionType: 4199
+ Flags: [ ]
+ DisplayName: main
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 0
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 3
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\t.c'
+ Lines:
+ - Offset: 0
+ LineStart: 1
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\t.c'
+ Kind: MD5
+ Checksum: 270A878DCC1B845655B162F56C4F5020
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\t.c'
+ Relocations:
+ - VirtualAddress: 44
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 48
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 100
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 104
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: '.debug$T'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Types:
+ - Kind: LF_TYPESERVER2
+ TypeServer2:
+ Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
+ Age: 18
+ Name: 'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb'
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 33C0C3
+symbols:
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 328
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.debug$T'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 564
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 3
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 4021952397
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb-type-server-simple.test b/test/COFF/pdb-type-server-simple.test
new file mode 100644
index 000000000000..c0de4e390914
--- /dev/null
+++ b/test/COFF/pdb-type-server-simple.test
@@ -0,0 +1,91 @@
+Replicate this scenario:
+
+$ cat a.c
+struct Foo { int x; };
+int g(struct Foo *p);
+int main() {
+ struct Foo f = {42};
+ return g(&f);
+}
+
+$ cat b.c
+struct Foo { int x; };
+int g(struct Foo *p) { return p->x; }
+
+$ cl -c a.c b.c -Zi -Fdts.pdb
+
+$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe
+
+RUN: rm -rf %t && mkdir -p %t && cd %t
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
+RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
+RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib
+RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s
+
+
+CHECK-LABEL: Types (TPI Stream)
+CHECK: ============================================================
+
+CHECK: [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
+
+CHECK: [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12]
+CHECK-NEXT: referent = [[FOO_DECL]]
+
+CHECK: [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12]
+CHECK-NEXT: [[FOO_PTR]]: `Foo*`
+
+CHECK: [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
+CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]]
+CHECK-NEXT: calling conv = cdecl, options = None
+
+CHECK: [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
+CHECK-NEXT: unique name: `.?AUFoo@@`
+CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x{{.*}}
+CHECK: options: has unique name
+CHECK: [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
+CHECK: return type = 0x0074 (int), # args = 0, param list = 0x{{.*}}
+CHECK: calling conv = cdecl, options = None
+
+
+CHECK-LABEL: Types (IPI Stream)
+CHECK: ============================================================
+CHECK: [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20]
+CHECK: name = main, type = [[MAIN_PROTO]], parent scope = <no type>
+CHECK: [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16]
+CHECK: name = g, type = [[G_PROTO]], parent scope = <no type>
+CHECK: [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
+CHECK: {{.*}}: `a.c`
+CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
+CHECK: {{.*}}: `b.c`
+
+CHECK-LABEL: Symbols
+CHECK: ============================================================
+CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`:
+CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj`
+CHECK: 104 | S_GPROC32_ID [size = 44] `main`
+CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27
+CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none
+CHECK: 200 | S_UDT [size = 12] `Foo`
+CHECK: original type = [[FOO_COMPLETE]]
+CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]`
+CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`:
+CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj`
+CHECK: 44 | S_COMPILE3 [size = 60]
+CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
+CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
+CHECK: flags = security checks | hot patchable
+CHECK: 104 | S_GPROC32_ID [size = 44] `g`
+CHECK: parent = 0, end = 196, addr = 0002:0032, code size = 13
+CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none
+CHECK: 148 | S_FRAMEPROC [size = 32]
+CHECK: size = 0, padding size = 0, offset to padding = 0
+CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
+CHECK: flags = has async eh | opt speed
+CHECK: 180 | S_REGREL32 [size = 16] `p`
+CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8
+CHECK: 196 | S_END [size = 4]
+CHECK: 200 | S_UDT [size = 12] `Foo`
+CHECK: original type = [[FOO_COMPLETE]]
+CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
+CHECK-LABEL: Mod 0002 | `* Linker *`:
diff --git a/test/COFF/reloc-discarded-dwarf.s b/test/COFF/reloc-discarded-dwarf.s
new file mode 100644
index 000000000000..d779d2f5b8fc
--- /dev/null
+++ b/test/COFF/reloc-discarded-dwarf.s
@@ -0,0 +1,15 @@
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t1.obj %s
+# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %s
+
+# LLD should not error on relocations in DWARF debug sections against symbols in
+# discarded sections.
+# RUN: lld-link -entry:main -debug %t1.obj %t2.obj
+
+ .section .text,"xr",discard,main
+ .globl main
+main:
+f:
+ retq
+
+ .section .debug_info,"dr"
+ .quad f
diff --git a/test/COFF/reloc-oob.yaml b/test/COFF/reloc-oob.yaml
new file mode 100644
index 000000000000..0ed4c4d57976
--- /dev/null
+++ b/test/COFF/reloc-oob.yaml
@@ -0,0 +1,62 @@
+# Make sure LLD does some light relocation bounds checking.
+
+# RUN: yaml2obj %s -o %t.obj
+# RUN: not lld-link %t.obj -entry:main -nodefaultlib -out:%t.exe 2>&1 | FileCheck %s
+
+# CHECK: error: relocation points beyond the end of its parent section
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_I386
+ Characteristics: [ ]
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 5589E550C745FC00000000A10000000083C4045DC3
+ Relocations:
+ - VirtualAddress: 24
+ SymbolName: _g
+ Type: IMAGE_REL_I386_DIR32
+ - Name: .data
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 4
+ SectionData: 2A000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 21
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 662775349
+ Number: 1
+ - Name: .data
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 3482275674
+ Number: 2
+ - Name: _main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _g
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/savetemps.ll b/test/COFF/savetemps.ll
index 4e59812441a9..7f2e11c17715 100644
--- a/test/COFF/savetemps.ll
+++ b/test/COFF/savetemps.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: rm -fr %T/savetemps
; RUN: mkdir %T/savetemps
; RUN: llvm-as -o %T/savetemps/savetemps.obj %s
diff --git a/test/COFF/thinlto-archives.ll b/test/COFF/thinlto-archives.ll
index 7a5e36aa1fb9..9a47a3a6feb6 100644
--- a/test/COFF/thinlto-archives.ll
+++ b/test/COFF/thinlto-archives.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: rm -fr %T/thinlto-archives
; RUN: mkdir %T/thinlto-archives %T/thinlto-archives/a %T/thinlto-archives/b
; RUN: opt -thinlto-bc -o %T/thinlto-archives/main.obj %s
diff --git a/test/COFF/thinlto-mangled.ll b/test/COFF/thinlto-mangled.ll
index efcd9c3d2d0a..8c901cbd70ba 100644
--- a/test/COFF/thinlto-mangled.ll
+++ b/test/COFF/thinlto-mangled.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: opt -thinlto-bc %s -o %t.obj
; RUN: opt -thinlto-bc %S/Inputs/thinlto-mangled-qux.ll -o %T/thinlto-mangled-qux.obj
; RUN: lld-link -out:%t.exe -entry:main %t.obj %T/thinlto-mangled-qux.obj
diff --git a/test/COFF/thinlto.ll b/test/COFF/thinlto.ll
index 11b689d6327e..f01d0d802289 100644
--- a/test/COFF/thinlto.ll
+++ b/test/COFF/thinlto.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: rm -fr %T/thinlto
; RUN: mkdir %T/thinlto
; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s
diff --git a/test/ELF/Inputs/ctors_dtors_priority1.s b/test/ELF/Inputs/ctors_dtors_priority1.s
index 2eb19d7edad9..2102dba278dc 100644
--- a/test/ELF/Inputs/ctors_dtors_priority1.s
+++ b/test/ELF/Inputs/ctors_dtors_priority1.s
@@ -1,5 +1,5 @@
.section .ctors, "aw", @progbits
- .byte 0xA1
+ .quad 0xA1
.section .dtors, "aw", @progbits
- .byte 0xA2
+ .quad 0xA2
diff --git a/test/ELF/Inputs/ctors_dtors_priority2.s b/test/ELF/Inputs/ctors_dtors_priority2.s
index fb85ce87c5c5..e94b15e2b894 100644
--- a/test/ELF/Inputs/ctors_dtors_priority2.s
+++ b/test/ELF/Inputs/ctors_dtors_priority2.s
@@ -1,5 +1,5 @@
.section .ctors, "aw", @progbits
- .byte 0xB1
+ .quad 0xB1
.section .dtors, "aw", @progbits
- .byte 0xB2
+ .quad 0xB2
diff --git a/test/ELF/Inputs/ctors_dtors_priority3.s b/test/ELF/Inputs/ctors_dtors_priority3.s
index 96418d351a85..7bba90cc70f8 100644
--- a/test/ELF/Inputs/ctors_dtors_priority3.s
+++ b/test/ELF/Inputs/ctors_dtors_priority3.s
@@ -1,5 +1,5 @@
.section .ctors, "aw", @progbits
- .byte 0xC1
+ .quad 0xC1
.section .dtors, "aw", @progbits
- .byte 0xC2
+ .quad 0xC2
diff --git a/test/ELF/Inputs/gdb-index-a.elf b/test/ELF/Inputs/gdb-index-a.elf
deleted file mode 100644
index 9b90b0dc233e..000000000000
--- a/test/ELF/Inputs/gdb-index-a.elf
+++ /dev/null
Binary files differ
diff --git a/test/ELF/Inputs/gdb-index-b.elf b/test/ELF/Inputs/gdb-index-b.elf
deleted file mode 100644
index b3356d8c773b..000000000000
--- a/test/ELF/Inputs/gdb-index-b.elf
+++ /dev/null
Binary files differ
diff --git a/test/ELF/Inputs/gdb-index.s b/test/ELF/Inputs/gdb-index.s
new file mode 100644
index 000000000000..907a66d350b0
--- /dev/null
+++ b/test/ELF/Inputs/gdb-index.s
@@ -0,0 +1,73 @@
+.text
+.Ltext0:
+.globl main2
+.type main2, @function
+main2:
+ nop
+ nop
+.Letext0:
+
+.section .debug_info,"",@progbits
+.long 0x30
+.value 0x4
+.long 0
+.byte 0x8
+.uleb128 0x1
+.quad .Ltext0
+.quad .Letext0-.Ltext0
+.long 0
+.long 0
+.long 0
+.long 0
+.byte 0x63
+.byte 0x88
+.byte 0xb4
+.byte 0x61
+.byte 0xaa
+.byte 0xb6
+.byte 0xb0
+.byte 0x67
+
+.section .debug_abbrev,"",@progbits
+.uleb128 0x1
+.uleb128 0x11
+.byte 0
+.uleb128 0x11
+.uleb128 0x1
+.uleb128 0x12
+.uleb128 0x7
+.uleb128 0x10
+.uleb128 0x17
+.uleb128 0x2130
+.uleb128 0xe
+.uleb128 0x1b
+.uleb128 0xe
+.uleb128 0x2134
+.uleb128 0x19
+.uleb128 0x2133
+.uleb128 0x17
+.uleb128 0x2131
+.uleb128 0x7
+.byte 0
+.byte 0
+.byte 0
+
+.section .debug_gnu_pubnames,"",@progbits
+.long 0x18
+.value 0x2
+.long 0
+.long 0x33
+.long 0x18
+.byte 0x30
+.string "main2"
+.long 0
+
+.section .debug_gnu_pubtypes,"",@progbits
+.long 0x17
+.value 0x2
+.long 0
+.long 0x33
+.long 0x2b
+.byte 0x90
+.string "int"
+.long 0
diff --git a/test/ELF/Inputs/symver-archive1.s b/test/ELF/Inputs/symver-archive1.s
deleted file mode 100644
index be7c64494215..000000000000
--- a/test/ELF/Inputs/symver-archive1.s
+++ /dev/null
@@ -1,6 +0,0 @@
-.text
-.globl x
-.type x, @function
-x:
-
-.symver x, xx@@VER
diff --git a/test/ELF/Inputs/symver-archive2.s b/test/ELF/Inputs/symver-archive2.s
deleted file mode 100644
index a9b9d0b0a35b..000000000000
--- a/test/ELF/Inputs/symver-archive2.s
+++ /dev/null
@@ -1 +0,0 @@
-call xx@PLT
diff --git a/test/ELF/allow-shlib-undefined.s b/test/ELF/allow-shlib-undefined.s
index 2d068b0f60ed..abb0351db723 100644
--- a/test/ELF/allow-shlib-undefined.s
+++ b/test/ELF/allow-shlib-undefined.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# --allow-shlib-undefined and --no-allow-shlib-undefined are fully
# ignored in linker implementation.
# --allow-shlib-undefined is set by default
diff --git a/test/ELF/as-needed-no-reloc.s b/test/ELF/as-needed-no-reloc.s
index 68f03d782c24..f8c34f80a595 100644
--- a/test/ELF/as-needed-no-reloc.s
+++ b/test/ELF/as-needed-no-reloc.s
@@ -16,7 +16,7 @@
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
-# CHECK: NEEDED SharedLibrary ({{.*}}as-needed-no-reloc{{.*}}2.so)
+# CHECK: NEEDED Shared library: [{{.*}}as-needed-no-reloc{{.*}}2.so]
.globl _start
_start:
diff --git a/test/ELF/as-needed.s b/test/ELF/as-needed.s
index 4f1a48abac36..37c6103b0ed0 100644
--- a/test/ELF/as-needed.s
+++ b/test/ELF/as-needed.s
@@ -28,13 +28,13 @@
// RUN: ld.lld %t.o %t.script -o %t2
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
-// CHECK: NEEDED SharedLibrary (shared1)
-// CHECK: NEEDED SharedLibrary (shared2)
-// CHECK: NEEDED SharedLibrary (shared3)
+// CHECK: NEEDED Shared library: [shared1]
+// CHECK: NEEDED Shared library: [shared2]
+// CHECK: NEEDED Shared library: [shared3]
-// CHECK2: NEEDED SharedLibrary (shared1)
-// CHECK2-NOT: NEEDED SharedLibrary (shared2)
-// CHECK2-NOT: NEEDED SharedLibrary (shared3)
+// CHECK2: NEEDED Shared library: [shared1]
+// CHECK2-NOT: NEEDED Shared library: [shared2]
+// CHECK2-NOT: NEEDED Shared library: [shared3]
.global _start
_start:
diff --git a/test/ELF/auxiliary.s b/test/ELF/auxiliary.s
index 236d0a421d4f..18fbdf05f9ec 100644
--- a/test/ELF/auxiliary.s
+++ b/test/ELF/auxiliary.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t
# RUN: llvm-readobj --dynamic-table %t | FileCheck %s
diff --git a/test/ELF/compressed-debug-input.s b/test/ELF/compressed-debug-input.s
index fbd5b02a07f0..d96ebdcb30b4 100644
--- a/test/ELF/compressed-debug-input.s
+++ b/test/ELF/compressed-debug-input.s
@@ -1,4 +1,4 @@
-# REQUIRES: zlib
+# REQUIRES: zlib, x86
# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=ZLIB %s
diff --git a/test/ELF/ctors_dtors_priority.s b/test/ELF/ctors_dtors_priority.s
index 10d6471f953a..fcddcbb020f3 100644
--- a/test/ELF/ctors_dtors_priority.s
+++ b/test/ELF/ctors_dtors_priority.s
@@ -14,28 +14,35 @@ _start:
nop
.section .ctors, "aw", @progbits
- .byte 1
+ .quad 1
.section .ctors.100, "aw", @progbits
- .byte 2
+ .quad 2
.section .ctors.005, "aw", @progbits
- .byte 3
+ .quad 3
.section .ctors, "aw", @progbits
- .byte 4
+ .quad 4
.section .ctors, "aw", @progbits
- .byte 5
+ .quad 5
.section .dtors, "aw", @progbits
- .byte 0x11
+ .quad 0x11
.section .dtors.100, "aw", @progbits
- .byte 0x12
+ .quad 0x12
.section .dtors.005, "aw", @progbits
- .byte 0x13
+ .quad 0x13
.section .dtors, "aw", @progbits
- .byte 0x14
+ .quad 0x14
.section .dtors, "aw", @progbits
- .byte 0x15
+ .quad 0x15
// CHECK: Contents of section .ctors:
-// CHECK-NEXT: a1010405 b10302c1
+// CHECK-NEXT: 202000 a1000000 00000000 01000000 00000000
+// CHECK-NEXT: 202010 04000000 00000000 05000000 00000000
+// CHECK-NEXT: 202020 b1000000 00000000 03000000 00000000
+// CHECK-NEXT: 202030 02000000 00000000 c1000000 00000000
+
// CHECK: Contents of section .dtors:
-// CHECK-NEXT: a2111415 b21312c2
+// CHECK-NEXT: 202040 a2000000 00000000 11000000 00000000
+// CHECK-NEXT: 202050 14000000 00000000 15000000 00000000
+// CHECK-NEXT: 202060 b2000000 00000000 13000000 00000000
+// CHECK-NEXT: 202070 12000000 00000000 c2000000 00000000
diff --git a/test/ELF/debug-gnu-pubnames.s b/test/ELF/debug-gnu-pubnames.s
index 0a8693c97eb8..aebfdfd0fb91 100644
--- a/test/ELF/debug-gnu-pubnames.s
+++ b/test/ELF/debug-gnu-pubnames.s
@@ -1,10 +1,18 @@
# REQUIRES: x86
-# RUN: ld.lld -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t1.exe
-# RUN: llvm-readobj -sections %t1.exe | FileCheck -check-prefix=CHECK1 %s
-# CHECK1: Name: .debug_gnu_pubnames
-# CHECK1: Name: .debug_gnu_pubtypes
-
-# RUN: ld.lld -gdb-index -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t2.exe
-# RUN: llvm-readobj -sections %t2.exe | FileCheck -check-prefix=CHECK2 %s
-# CHECK2-NOT: Name: .debug_gnu_pubnames
-# CHECK2-NOT: Name: .debug_gnu_pubtypes
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: ld.lld %t.o -o %t1.exe
+# RUN: llvm-readobj -sections %t1.exe | FileCheck %s
+# CHECK: .debug_gnu_pubnames
+# CHECK: .debug_gnu_pubtypes
+
+# RUN: ld.lld -gdb-index %t.o -o %t2.exe
+# RUN: llvm-readobj -sections %t2.exe | FileCheck %s --check-prefix=GDB
+# GDB-NOT: .debug_gnu_pubnames
+# GDB-NOT: .debug_gnu_pubtypes
+
+.section .debug_gnu_pubnames,"",@progbits
+.long 0
+
+.section .debug_gnu_pubtypes,"",@progbits
+.long 0
diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s
index 8fda0b45abea..939093c17b41 100644
--- a/test/ELF/dynamic-reloc.s
+++ b/test/ELF/dynamic-reloc.s
@@ -43,7 +43,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so]
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000017 JMPREL
// CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes)
diff --git a/test/ELF/filter.s b/test/ELF/filter.s
new file mode 100644
index 000000000000..fa8e5267b18b
--- /dev/null
+++ b/test/ELF/filter.s
@@ -0,0 +1,15 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1
+# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s
+
+# Test alias.
+# RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2
+# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK-NEXT: Tag Type Name/Value
+# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so]
+# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so]
+
+# RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s
+# ERR: -F may not be used without -shared
diff --git a/test/ELF/gc-sections-shared.s b/test/ELF/gc-sections-shared.s
index a88f2b443479..efb21faee6bd 100644
--- a/test/ELF/gc-sections-shared.s
+++ b/test/ELF/gc-sections-shared.s
@@ -38,7 +38,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: ]
-# CHECK: NEEDED SharedLibrary ({{.*}}.so)
+# CHECK: NEEDED Shared library: [{{.*}}.so]
.section .text.foo, "ax"
.globl foo
diff --git a/test/ELF/gdb-index-empty.s b/test/ELF/gdb-index-empty.s
index 24f20803a008..0158357c9bfd 100644
--- a/test/ELF/gdb-index-empty.s
+++ b/test/ELF/gdb-index-empty.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s
# RUN: ld.lld --gdb-index --gc-sections -o %t2 %t
# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s
diff --git a/test/ELF/gdb-index-gc-sections.s b/test/ELF/gdb-index-gc-sections.s
index 70a14754656c..58c47ae5e987 100644
--- a/test/ELF/gdb-index-gc-sections.s
+++ b/test/ELF/gdb-index-gc-sections.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s
# RUN: ld.lld --gdb-index --gc-sections -o %t2 %t
# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s
diff --git a/test/ELF/gdb-index.s b/test/ELF/gdb-index.s
index b7d8a708ace5..e04845e022c3 100644
--- a/test/ELF/gdb-index.s
+++ b/test/ELF/gdb-index.s
@@ -1,32 +1,19 @@
-## gdb-index-a.elf and gdb-index-b.elf are a test.o and test2.o renamed,
-## were generated in this way:
-## test.cpp:
-## int main() { return 0; }
-## test2.cpp:
-## int main2() { return 0; }
-## Compiled with:
-## gcc -gsplit-dwarf -c test.cpp test2.cpp
-## gcc version 5.3.1 20160413
-## Info about gdb-index: https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
-
# REQUIRES: x86
-# RUN: ld.lld --gdb-index -e main %p/Inputs/gdb-index-a.elf %p/Inputs/gdb-index-b.elf -o %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index.s -o %t2.o
+# RUN: ld.lld --gdb-index -e main %t1.o %t2.o -o %t
# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s
# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM
# DISASM: Disassembly of section .text:
# DISASM: main:
-# DISASM-CHECK: 11000: 55 pushq %rbp
-# DISASM-CHECK: 11001: 48 89 e5 movq %rsp, %rbp
-# DISASM-CHECK: 11004: b8 00 00 00 00 movl $0, %eax
-# DISASM-CHECK: 11009: 5d popq %rbp
-# DISASM-CHECK: 1100a: c3 retq
-# DISASM: _Z5main2v:
-# DISASM-CHECK: 1100b: 55 pushq %rbp
-# DISASM-CHECK: 1100c: 48 89 e5 movq %rsp, %rbp
-# DISASM-CHECK: 1100f: b8 00 00 00 00 movl $0, %eax
-# DISASM-CHECK: 11014: 5d popq %rbp
-# DISASM-CHECK: 11015: c3 retq
+# DISASM-CHECK: 201000: 90 nop
+# DISASM-CHECK: 201001: cc int3
+# DISASM-CHECK: 201002: cc int3
+# DISASM-CHECK: 201003: cc int3
+# DISASM: main2:
+# DISASM-CHECK: 201004: 90 nop
+# DISASM-CHECK: 201005: 90 nop
# CHECK: .gnu_index contents:
# CHECK-NEXT: Version = 7
@@ -34,8 +21,8 @@
# CHECK-NEXT: 0: Offset = 0x0, Length = 0x34
# CHECK-NEXT: 1: Offset = 0x34, Length = 0x34
# CHECK: Address area offset = 0x38, has 2 entries:
-# CHECK-NEXT: Low/High address = [0x201000, 0x20100b) (Size: 0xb), CU id = 0
-# CHECK-NEXT: Low/High address = [0x20100b, 0x201016) (Size: 0xb), CU id = 1
+# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
+# CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1
# CHECK: Symbol table offset = 0x60, size = 1024, filled slots:
# CHECK-NEXT: 489: Name offset = 0x1d, CU vector offset = 0x0
# CHECK-NEXT: String name: main, CU vector index: 0
@@ -47,3 +34,79 @@
# CHECK-NEXT: 0(0x0): 0x30000000
# CHECK-NEXT: 1(0x8): 0x90000000 0x90000001
# CHECK-NEXT: 2(0x14): 0x30000001
+
+## The following section contents are created by this using gcc 7.1.0:
+## echo 'int main() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- -
+
+.text
+.Ltext0:
+.globl main
+.type main, @function
+main:
+ nop
+.Letext0:
+
+.section .debug_info,"",@progbits
+.long 0x30
+.value 0x4
+.long 0
+.byte 0x8
+.uleb128 0x1
+.quad .Ltext0
+.quad .Letext0-.Ltext0
+.long 0
+.long 0
+.long 0
+.long 0
+.byte 0x63
+.byte 0x88
+.byte 0xb4
+.byte 0x61
+.byte 0xaa
+.byte 0xb6
+.byte 0xb0
+.byte 0x67
+
+.section .debug_abbrev,"",@progbits
+.uleb128 0x1
+.uleb128 0x11
+.byte 0
+.uleb128 0x11
+.uleb128 0x1
+.uleb128 0x12
+.uleb128 0x7
+.uleb128 0x10
+.uleb128 0x17
+.uleb128 0x2130
+.uleb128 0xe
+.uleb128 0x1b
+.uleb128 0xe
+.uleb128 0x2134
+.uleb128 0x19
+.uleb128 0x2133
+.uleb128 0x17
+.uleb128 0x2131
+.uleb128 0x7
+.byte 0
+.byte 0
+.byte 0
+
+.section .debug_gnu_pubnames,"",@progbits
+.long 0x18
+.value 0x2
+.long 0
+.long 0x33
+.long 0x18
+.byte 0x30
+.string "main"
+.long 0
+
+.section .debug_gnu_pubtypes,"",@progbits
+.long 0x17
+.value 0x2
+.long 0
+.long 0x33
+.long 0x2b
+.byte 0x90
+.string "int"
+.long 0
diff --git a/test/ELF/i386-reloc-large-addend.s b/test/ELF/i386-reloc-large-addend.s
index b644640404e2..5af584475562 100644
--- a/test/ELF/i386-reloc-large-addend.s
+++ b/test/ELF/i386-reloc-large-addend.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj
// RUN: echo ".global foo; foo = 0x1" > %t1.s
diff --git a/test/ELF/i386-reloc-range.s b/test/ELF/i386-reloc-range.s
index 47447d0efa32..4fb5325e5434 100644
--- a/test/ELF/i386-reloc-range.s
+++ b/test/ELF/i386-reloc-range.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj
// RUN: echo ".global foo; foo = 0x10202" > %t1.s
diff --git a/test/ELF/invalid/tls-symbol.s b/test/ELF/invalid/tls-symbol.s
index 7c65c6c9f2c7..354ca573d5c0 100644
--- a/test/ELF/invalid/tls-symbol.s
+++ b/test/ELF/invalid/tls-symbol.s
@@ -1,5 +1,5 @@
# REQUIRES: x86
-## The test file contains a STT_TLS symbol but has no TLS section.
+## The test file contains an STT_TLS symbol but has no TLS section.
# RUN: not ld.lld %S/Inputs/tls-symbol.elf -o %t 2>&1 | FileCheck %s
-# CHECK: has a STT_TLS symbol but doesn't have a PT_TLS section
+# CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section
diff --git a/test/ELF/linkerscript/exidx-crash.s b/test/ELF/linkerscript/exidx-crash.s
new file mode 100644
index 000000000000..c29d0135414d
--- /dev/null
+++ b/test/ELF/linkerscript/exidx-crash.s
@@ -0,0 +1,7 @@
+# REQUIRES: aarch64
+
+# We used to crash on this.
+
+# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
+# RUN: echo "SECTIONS { .ARM.exidx : { *(.foo) } }" > %t.script
+# RUN: ld.lld -T %t.script %t.o -o %t
diff --git a/test/ELF/linkerscript/got-write-offset.s b/test/ELF/linkerscript/got-write-offset.s
new file mode 100644
index 000000000000..323da7b4a46b
--- /dev/null
+++ b/test/ELF/linkerscript/got-write-offset.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux-gnu %s -o %t
+# RUN: echo "SECTIONS { \
+# RUN: .data 0x1000 : { *(.data) } \
+# RUN: .got 0x2000 : { \
+# RUN: LONG(0) \
+# RUN: *(.got) \
+# RUN: } \
+# RUN: };" > %t.script
+# RUN: ld.lld -shared -o %t.out --script %t.script %t
+# RUN: llvm-objdump -s %t.out | FileCheck %s
+.text
+.global foo
+foo:
+ movl bar@GOT, %eax
+.data
+.local bar
+bar:
+ .zero 4
+# CHECK: Contents of section .data:
+# CHECK-NEXT: 1000 00000000
+# CHECK: Contents of section .got:
+# CHECK-NEXT: 2000 00000000 00100000
diff --git a/test/ELF/linkerscript/output-too-large.s b/test/ELF/linkerscript/output-too-large.s
index db021eaa99e0..c892a88a947e 100644
--- a/test/ELF/linkerscript/output-too-large.s
+++ b/test/ELF/linkerscript/output-too-large.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s
diff --git a/test/ELF/lto/available-externally.ll b/test/ELF/lto/available-externally.ll
index 181042b9d1e1..315e710ec87c 100644
--- a/test/ELF/lto/available-externally.ll
+++ b/test/ELF/lto/available-externally.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t1.o
; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o
; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps
diff --git a/test/ELF/lto/comdat2.ll b/test/ELF/lto/comdat2.ll
index 1509585f1553..283182155ae6 100644
--- a/test/ELF/lto/comdat2.ll
+++ b/test/ELF/lto/comdat2.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
diff --git a/test/ELF/lto/common2.ll b/test/ELF/lto/common2.ll
index b44bbac4fda3..2345a203b24c 100644
--- a/test/ELF/lto/common2.ll
+++ b/test/ELF/lto/common2.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t1.o
; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps
; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
diff --git a/test/ELF/lto/common3.ll b/test/ELF/lto/common3.ll
index 6d40de547fcd..aea33f443f4c 100644
--- a/test/ELF/lto/common3.ll
+++ b/test/ELF/lto/common3.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t1.o
; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o
; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps
diff --git a/test/ELF/lto/discard-value-names.ll b/test/ELF/lto/discard-value-names.ll
index c71dc386113d..f1e95fe75000 100644
--- a/test/ELF/lto/discard-value-names.ll
+++ b/test/ELF/lto/discard-value-names.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o
diff --git a/test/ELF/lto/opt-level.ll b/test/ELF/lto/opt-level.ll
index 934bf01b6c32..1065ca775751 100644
--- a/test/ELF/lto/opt-level.ll
+++ b/test/ELF/lto/opt-level.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as -o %t.o %s
; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o
; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s
diff --git a/test/ELF/lto/opt-remarks.ll b/test/ELF/lto/opt-remarks.ll
index 88304205caba..e29cc72bb3cc 100644
--- a/test/ELF/lto/opt-remarks.ll
+++ b/test/ELF/lto/opt-remarks.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: rm -f %t.yaml
diff --git a/test/ELF/lto/relax-relocs.ll b/test/ELF/lto/relax-relocs.ll
index 929e124b2d8e..8e8d9d165787 100644
--- a/test/ELF/lto/relax-relocs.ll
+++ b/test/ELF/lto/relax-relocs.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so
; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s
diff --git a/test/ELF/lto/thin-archivecollision.ll b/test/ELF/lto/thin-archivecollision.ll
index f1dd5ae4d85f..554c2b02fc40 100644
--- a/test/ELF/lto/thin-archivecollision.ll
+++ b/test/ELF/lto/thin-archivecollision.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: opt -module-summary %s -o %t.o
; RUN: mkdir -p %t1 %t2
; RUN: opt -module-summary %p/Inputs/thin1.ll -o %t1/t.coll.o
diff --git a/test/ELF/lto/thinlto.ll b/test/ELF/lto/thinlto.ll
index 2036c554a76d..99dd19130d28 100644
--- a/test/ELF/lto/thinlto.ll
+++ b/test/ELF/lto/thinlto.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; Basic ThinLTO tests.
; RUN: opt -module-summary %s -o %t.o
; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
diff --git a/test/ELF/lto/type-merge2.ll b/test/ELF/lto/type-merge2.ll
index 45777a7e6a48..6ebbf778dd8e 100644
--- a/test/ELF/lto/type-merge2.ll
+++ b/test/ELF/lto/type-merge2.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o
; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps
diff --git a/test/ELF/lto/unnamed-addr-comdat.ll b/test/ELF/lto/unnamed-addr-comdat.ll
index ed48f3ba5e04..29a59415851b 100644
--- a/test/ELF/lto/unnamed-addr-comdat.ll
+++ b/test/ELF/lto/unnamed-addr-comdat.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared
; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
diff --git a/test/ELF/lto/unnamed-addr-drop.ll b/test/ELF/lto/unnamed-addr-drop.ll
index 9142537fe57d..e827cbb435e6 100644
--- a/test/ELF/lto/unnamed-addr-drop.ll
+++ b/test/ELF/lto/unnamed-addr-drop.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t1.o
; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o
; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared
diff --git a/test/ELF/lto/unnamed-addr.ll b/test/ELF/lto/unnamed-addr.ll
index 6a6dd73dad86..56fe148b0995 100644
--- a/test/ELF/lto/unnamed-addr.ll
+++ b/test/ELF/lto/unnamed-addr.ll
@@ -1,3 +1,4 @@
+; REQUIRES: x86
; RUN: llvm-as %s -o %t.o
; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared
; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
diff --git a/test/ELF/many-alloc-sections.s b/test/ELF/many-alloc-sections.s
index 441e5ff32d08..648ab8250286 100644
--- a/test/ELF/many-alloc-sections.s
+++ b/test/ELF/many-alloc-sections.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script
// FIXME: threads are disable because the test is too slow with them (PR32942).
diff --git a/test/ELF/many-sections.s b/test/ELF/many-sections.s
index ae923889ddc1..7ef0f7ceaac4 100644
--- a/test/ELF/many-sections.s
+++ b/test/ELF/many-sections.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
// RUN: llvm-readobj -t %t | FileCheck %s
diff --git a/test/ELF/map-gc-sections.s b/test/ELF/map-gc-sections.s
new file mode 100644
index 000000000000..717ab819889d
--- /dev/null
+++ b/test/ELF/map-gc-sections.s
@@ -0,0 +1,9 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -Map=- --gc-sections | FileCheck %s
+
+.section .tbss,"awT",@nobits
+// CHECK-NOT: foo
+.globl foo
+foo:
+.align 8
+.long 0
diff --git a/test/ELF/merge-section-types.s b/test/ELF/merge-section-types.s
index ee80fe177fe0..f8462824684f 100644
--- a/test/ELF/merge-section-types.s
+++ b/test/ELF/merge-section-types.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t
// RUN: llvm-readobj -s %t | FileCheck %s
diff --git a/test/ELF/new-dtags.test b/test/ELF/new-dtags.test
index 334d477622a7..1ae328c6b502 100644
--- a/test/ELF/new-dtags.test
+++ b/test/ELF/new-dtags.test
@@ -1,3 +1,4 @@
+# REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags -o %t
// RUN: ld.lld %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2
diff --git a/test/ELF/no-obj.s b/test/ELF/no-obj.s
index eea10a45d879..693cdf1e9d3f 100644
--- a/test/ELF/no-obj.s
+++ b/test/ELF/no-obj.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: llvm-ar rcs %t.a %t.o
// RUN: not ld.lld -o %t2 -u _start %t.a 2>&1 | FileCheck %s
diff --git a/test/ELF/no-soname.s b/test/ELF/no-soname.s
index d2c15ed8f9cd..e3869ff5a03c 100644
--- a/test/ELF/no-soname.s
+++ b/test/ELF/no-soname.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: mkdir -p %T/no-soname
// RUN: ld.lld %t.o -shared -o %T/no-soname/libfoo.so
@@ -5,26 +6,26 @@
// RUN: ld.lld %t.o %T/no-soname/libfoo.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
-// CHECK: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/libfoo.so)
+// CHECK: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/libfoo.so]
// CHECK-NOT: NEEDED
// RUN: ld.lld %t.o %T/no-soname/../no-soname/libfoo.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK2
-// CHECK2: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}/no-soname/../no-soname/libfoo.so)
+// CHECK2: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/../no-soname/libfoo.so]
// CHECK2-NOT: NEEDED
// RUN: ld.lld %t.o -L%T/no-soname/../no-soname -lfoo -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK3
-// CHECK3: 0x0000000000000001 NEEDED SharedLibrary (libfoo.so)
+// CHECK3: 0x0000000000000001 NEEDED Shared library: [libfoo.so]
// CHECK3-NOT: NEEDED
// RUN: ld.lld %t.o -shared -soname libbar.so -o %T/no-soname/libbar.so
// RUN: ld.lld %t.o %T/no-soname/libbar.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK4
-// CHECK4: 0x0000000000000001 NEEDED SharedLibrary (libbar.so)
+// CHECK4: 0x0000000000000001 NEEDED Shared library: [libbar.so]
// CHECK4-NOT: NEEDED
.global _start
diff --git a/test/ELF/no-symtab.s b/test/ELF/no-symtab.s
index 158bd727f251..af9df13e9768 100644
--- a/test/ELF/no-symtab.s
+++ b/test/ELF/no-symtab.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld %t.o %p/Inputs/no-symtab.o -o %t
.global _start
diff --git a/test/ELF/no-undefined.s b/test/ELF/no-undefined.s
index fa4d5e928763..493a38987091 100644
--- a/test/ELF/no-undefined.s
+++ b/test/ELF/no-undefined.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: not ld.lld --no-undefined -shared %t -o %t.so
# RUN: ld.lld -shared %t -o %t1.so
diff --git a/test/ELF/pie-weak.s b/test/ELF/pie-weak.s
index e74bcdfc09c0..99dbd47488fc 100644
--- a/test/ELF/pie-weak.s
+++ b/test/ELF/pie-weak.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld -pie %t.o -o %t
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s
diff --git a/test/ELF/progname.s b/test/ELF/progname.s
index 6d91823c9481..be8ab9e31c4f 100644
--- a/test/ELF/progname.s
+++ b/test/ELF/progname.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: echo .global __progname > %t2.s
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
diff --git a/test/ELF/relative-dynamic-reloc-pie.s b/test/ELF/relative-dynamic-reloc-pie.s
index 25b3e0ac2333..f7c8b3c1516c 100644
--- a/test/ELF/relative-dynamic-reloc-pie.s
+++ b/test/ELF/relative-dynamic-reloc-pie.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
# RUN: ld.lld -pie %t.o -o %t.pie
# RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s
diff --git a/test/ELF/relative-dynamic-reloc.s b/test/ELF/relative-dynamic-reloc.s
index 39382124e889..0ed7e40f7436 100644
--- a/test/ELF/relative-dynamic-reloc.s
+++ b/test/ELF/relative-dynamic-reloc.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t.so
// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
diff --git a/test/ELF/relocatable-compressed-input.s b/test/ELF/relocatable-compressed-input.s
index bdfb2073a1e0..3c0199c33f7d 100644
--- a/test/ELF/relocatable-compressed-input.s
+++ b/test/ELF/relocatable-compressed-input.s
@@ -1,4 +1,4 @@
-# REQUIRES: zlib
+# REQUIRES: x86, zlib
# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
# RUN: llvm-readobj -sections %t1 | FileCheck -check-prefix=GNU %s
diff --git a/test/ELF/relocatable-reloc.s b/test/ELF/relocatable-reloc.s
index c576073a7510..7c699b9bf314 100644
--- a/test/ELF/relocatable-reloc.s
+++ b/test/ELF/relocatable-reloc.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj %s -o %t.o -triple=x86_64-pc-linux
// RUN: ld.lld %t.o %t.o -r -o %t2.o
// RUN: llvm-readobj -r %t2.o | FileCheck %s
diff --git a/test/ELF/relocatable-section-symbol.s b/test/ELF/relocatable-section-symbol.s
index 9ac3a91d2c24..57a75ab92f11 100644
--- a/test/ELF/relocatable-section-symbol.s
+++ b/test/ELF/relocatable-section-symbol.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: ld.lld -r -o %t %t.o %t.o
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELA %s
diff --git a/test/ELF/relocatable-sections.s b/test/ELF/relocatable-sections.s
index d6a922fba482..75ede137293c 100644
--- a/test/ELF/relocatable-sections.s
+++ b/test/ELF/relocatable-sections.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
# RUN: ld.lld -r %t1.o -o %t
# RUN: llvm-objdump -section-headers %t | FileCheck %s
diff --git a/test/ELF/relocatable-tls.s b/test/ELF/relocatable-tls.s
index 88d38c2ae4b4..ff04dd2dfccb 100644
--- a/test/ELF/relocatable-tls.s
+++ b/test/ELF/relocatable-tls.s
@@ -1,3 +1,4 @@
+# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
# RUN: %S/Inputs/relocatable-tls.s -o %t2.o
diff --git a/test/ELF/relocation-shared.s b/test/ELF/relocation-shared.s
index e1850944c459..4fba7a5683b0 100644
--- a/test/ELF/relocation-shared.s
+++ b/test/ELF/relocation-shared.s
@@ -1,3 +1,4 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
// RUN: ld.lld %t.o -shared -o %t.so
// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
diff --git a/test/ELF/shared-be.s b/test/ELF/shared-be.s
index c969793d9d21..0b941d373720 100644
--- a/test/ELF/shared-be.s
+++ b/test/ELF/shared-be.s
@@ -21,7 +21,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so]
// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
// CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes)
diff --git a/test/ELF/shared.s b/test/ELF/shared.s
index 350ef5c602d0..d4c79d914ffb 100644
--- a/test/ELF/shared.s
+++ b/test/ELF/shared.s
@@ -254,7 +254,7 @@
// CHECK: DynamicSection [
// CHECK-NEXT: Tag Type Name/Value
// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
-// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so)
+// CHECK-NEXT: 0x00000001 NEEDED Shared library: [{{.*}}2.so]
// CHECK-NEXT: 0x00000015 DEBUG 0x0
// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
diff --git a/test/ELF/soname.s b/test/ELF/soname.s
index 65e95ce85add..a26bb30f7a17 100644
--- a/test/ELF/soname.s
+++ b/test/ELF/soname.s
@@ -4,7 +4,7 @@
// RUN: ld.lld %t.o %t.so %t2.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
-// CHECK: 0x0000000000000001 NEEDED SharedLibrary (bar)
+// CHECK: 0x0000000000000001 NEEDED Shared library: [bar]
// CHECK-NOT: NEEDED
.global _start
diff --git a/test/ELF/soname2.s b/test/ELF/soname2.s
index d446766a799d..9fb8da519bfb 100644
--- a/test/ELF/soname2.s
+++ b/test/ELF/soname2.s
@@ -2,7 +2,7 @@
// RUN: ld.lld %t.o -shared -soname=foo.so -o %t
// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
-// CHECK: 0x000000000000000E SONAME LibrarySoname (foo.so)
+// CHECK: 0x000000000000000E SONAME Library soname: [foo.so]
.global _start
_start:
diff --git a/test/ELF/symver-archive.s b/test/ELF/symver-archive.s
deleted file mode 100644
index be50503a3f5d..000000000000
--- a/test/ELF/symver-archive.s
+++ /dev/null
@@ -1,15 +0,0 @@
-# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1
-# RUN: rm -f %t.a
-# RUN: llvm-ar rcs %t.a %t1
-# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive1.s -o %t2.o
-# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive2.s -o %t3.o
-# RUN: ld.lld -o %t.out %t2.o %t3.o %t.a
-
-.text
-.globl x
-.type x, @function
-x:
-
-.globl xx
-xx = x
diff --git a/test/ELF/version-script-twice.s b/test/ELF/version-script-twice.s
new file mode 100644
index 000000000000..3aeedd5b5ddc
--- /dev/null
+++ b/test/ELF/version-script-twice.s
@@ -0,0 +1,14 @@
+# REQUIRES: x86
+
+# RUN: echo "FBSD_1.1 {}; FBSD_1.2 {};" > %t.ver
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t.so --version-script=%t.ver
+# RUN: llvm-readobj --dyn-symbols --elf-output-style=GNU %t.so | FileCheck %s
+
+ .weak openat
+openat:
+openat@FBSD_1.1 = openat
+openat@@FBSD_1.2 = openat
+
+# CHECK-DAG: openat@FBSD_1.1
+# CHECK-DAG: openat@@FBSD_1.2