aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-26 20:33:45 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-26 20:33:45 +0000
commit4ea16835ba66f2240d050ffcaee44cee6c97cab9 (patch)
treed2f3d66f3352a3ec22362de0b7a5c1366fc25df8
parent15f7a1a3796209b21af2817fdf11ca9932165c70 (diff)
downloadsrc-4ea16835ba66f2240d050ffcaee44cee6c97cab9.tar.gz
src-4ea16835ba66f2240d050ffcaee44cee6c97cab9.zip
Vendor import of lld trunk r306325:vendor/lld/lld-trunk-r306325
Notes
Notes: svn path=/vendor/lld/dist/; revision=320382 svn path=/vendor/lld/lld-trunk-r306325/; revision=320383; tag=vendor/lld/lld-trunk-r306325
-rw-r--r--COFF/Chunks.cpp33
-rw-r--r--COFF/Chunks.h30
-rw-r--r--COFF/Config.h3
-rw-r--r--COFF/Driver.cpp19
-rw-r--r--COFF/Driver.h2
-rw-r--r--COFF/DriverUtils.cpp160
-rw-r--r--COFF/InputFiles.cpp22
-rw-r--r--COFF/Options.td1
-rw-r--r--COFF/PDB.cpp297
-rw-r--r--COFF/Strings.cpp5
-rw-r--r--COFF/SymbolTable.cpp10
-rw-r--r--COFF/SymbolTable.h2
-rw-r--r--COFF/Symbols.cpp2
-rw-r--r--COFF/Symbols.h45
-rw-r--r--COFF/Writer.cpp92
-rw-r--r--ELF/Arch/AArch64.cpp6
-rw-r--r--ELF/Arch/AMDGPU.cpp6
-rw-r--r--ELF/Arch/ARM.cpp7
-rw-r--r--ELF/Arch/AVR.cpp6
-rw-r--r--ELF/Arch/Mips.cpp15
-rw-r--r--ELF/Arch/MipsArchTree.cpp (renamed from ELF/Mips.cpp)2
-rw-r--r--ELF/Arch/PPC.cpp8
-rw-r--r--ELF/Arch/PPC64.cpp6
-rw-r--r--ELF/Arch/X86.cpp11
-rw-r--r--ELF/Arch/X86_64.cpp17
-rw-r--r--ELF/CMakeLists.txt2
-rw-r--r--ELF/Config.h2
-rw-r--r--ELF/Driver.cpp53
-rw-r--r--ELF/Driver.h2
-rw-r--r--ELF/DriverUtils.cpp6
-rw-r--r--ELF/InputFiles.cpp3
-rw-r--r--ELF/InputFiles.h2
-rw-r--r--ELF/InputSection.cpp27
-rw-r--r--ELF/LinkerScript.cpp36
-rw-r--r--ELF/MarkLive.cpp2
-rw-r--r--ELF/Options.td4
-rw-r--r--ELF/OutputSections.cpp4
-rw-r--r--ELF/Relocations.cpp2
-rw-r--r--ELF/SymbolTable.cpp35
-rw-r--r--ELF/SymbolTable.h2
-rw-r--r--ELF/Symbols.cpp1
-rw-r--r--ELF/Symbols.h6
-rw-r--r--ELF/Target.cpp28
-rw-r--r--ELF/Target.h26
-rw-r--r--ELF/Writer.cpp31
-rw-r--r--README.md1
-rw-r--r--docs/windows_support.rst2
-rw-r--r--lib/Driver/DarwinLdDriver.cpp16
-rw-r--r--lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp4
-rw-r--r--test/COFF/Inputs/associative-comdat-2.s13
-rw-r--r--test/COFF/Inputs/pdb1.yaml4
-rw-r--r--test/COFF/Inputs/pdb_comdat_bar.yaml440
-rw-r--r--test/COFF/Inputs/pdb_comdat_main.yaml446
-rw-r--r--test/COFF/Inputs/pdb_lines_1.yaml480
-rw-r--r--test/COFF/Inputs/pdb_lines_2.yaml209
-rw-r--r--test/COFF/associative-comdat.s46
-rw-r--r--test/COFF/def-name.test2
-rw-r--r--test/COFF/dll.test2
-rw-r--r--test/COFF/dllimport-gc.test2
-rw-r--r--test/COFF/guardcf.test74
-rw-r--r--test/COFF/hello32.test2
-rw-r--r--test/COFF/icf-associative.test8
-rw-r--r--test/COFF/manifestinput.test27
-rw-r--r--test/COFF/noentry.test2
-rw-r--r--test/COFF/out.test1
-rw-r--r--test/COFF/pdb-comdat.test100
-rw-r--r--test/COFF/pdb-lib.s2
-rw-r--r--test/COFF/pdb-safeseh.yaml85
-rw-r--r--test/COFF/pdb-secrel-absolute.yaml84
-rw-r--r--test/COFF/pdb-source-lines.test124
-rw-r--r--test/COFF/pdb-symbol-types.yaml344
-rw-r--r--test/COFF/pdb.test8
-rw-r--r--test/COFF/resource.test2
-rw-r--r--test/COFF/safeseh-diag-feat.test (renamed from test/COFF/safeseh.test)0
-rw-r--r--test/COFF/safeseh.s60
-rw-r--r--test/COFF/secidx-absolute.s33
-rw-r--r--test/COFF/secrel-absolute.s14
-rw-r--r--test/COFF/secrel-common.s41
-rw-r--r--test/ELF/Inputs/exclude-libs.s3
-rw-r--r--test/ELF/arm-gnu-ifunc-plt.s6
-rw-r--r--test/ELF/arm-got-relative.s16
-rw-r--r--test/ELF/arm-thumb-branch.s2
-rw-r--r--test/ELF/arm-thumb-plt-reloc.s4
-rw-r--r--test/ELF/defsym.s4
-rw-r--r--test/ELF/exclude-libs.s30
-rw-r--r--test/ELF/global-offset-table-position-aarch64.s30
-rw-r--r--test/ELF/global-offset-table-position-arm.s35
-rw-r--r--test/ELF/global-offset-table-position-i386.s31
-rw-r--r--test/ELF/global-offset-table-position-mips.s33
-rw-r--r--test/ELF/global-offset-table-position.s31
-rw-r--r--test/ELF/global_offset_table_shared.s9
-rw-r--r--test/ELF/invalid-z.s9
-rw-r--r--test/ELF/linkerscript/discard-section-err.s23
-rw-r--r--test/ELF/linkerscript/sections.s6
-rw-r--r--test/ELF/linkerscript/segment-none.s39
-rw-r--r--test/ELF/linkerscript/ttext-script.s11
-rw-r--r--test/ELF/lto/cache.ll11
-rw-r--r--test/ELF/lto/wrap-2.ll2
-rw-r--r--test/ELF/mips-got16-relocatable.s8
-rw-r--r--test/ELF/mips-npic-call-pic-os.s32
-rw-r--r--test/ELF/mips-npic-call-pic-script.s170
-rw-r--r--test/ELF/mips-npic-call-pic.s32
-rw-r--r--test/ELF/mips-plt-r6.s4
-rw-r--r--test/ELF/wrap.s8
-rw-r--r--test/lit.cfg11
-rw-r--r--test/mach-o/executable-exports.yaml4
106 files changed, 3814 insertions, 549 deletions
diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp
index 359dbe69559f..56124acaf9a1 100644
--- a/COFF/Chunks.cpp
+++ b/COFF/Chunks.cpp
@@ -37,8 +37,14 @@ SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
Align = Header->getAlignment();
- // Only COMDAT sections are subject of dead-stripping.
- Live = !isCOMDAT();
+ // Chunks may be discarded during comdat merging.
+ Discarded = false;
+
+ // If linker GC is disabled, every chunk starts out alive. If linker GC is
+ // enabled, treat non-comdat sections as roots. Generally optimized object
+ // files will be built with -ffunction-sections or /Gy, so most things worth
+ // stripping will be in a comdat.
+ Live = !Config->DoGC || !isCOMDAT();
}
static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
@@ -46,6 +52,15 @@ static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
+static void applySecRel(const SectionChunk *Sec, uint8_t *Off, Defined *Sym) {
+ // Don't apply section relative relocations to absolute symbols in codeview
+ // debug info sections. MSVC does not treat such relocations as fatal errors,
+ // and they can be found in the standard library for linker-provided symbols
+ // like __guard_fids_table and __safe_se_handler_table.
+ if (!(isa<DefinedAbsolute>(Sym) && Sec->isCodeView()))
+ add32(Off, Sym->getSecrel());
+}
+
void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
uint64_t P) const {
uint64_t S = Sym->getRVA();
@@ -60,7 +75,7 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
case IMAGE_REL_AMD64_SECTION: add16(Off, Sym->getSectionIndex()); break;
- case IMAGE_REL_AMD64_SECREL: add32(Off, Sym->getSecrel()); break;
+ case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, Sym); break;
default:
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
}
@@ -75,7 +90,7 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym,
case IMAGE_REL_I386_DIR32NB: add32(Off, S); break;
case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break;
case IMAGE_REL_I386_SECTION: add16(Off, Sym->getSectionIndex()); break;
- case IMAGE_REL_I386_SECREL: add32(Off, Sym->getSecrel()); break;
+ case IMAGE_REL_I386_SECREL: applySecRel(this, Off, Sym); break;
default:
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
}
@@ -135,7 +150,7 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, S - P - 4); break;
case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, S - P - 4); break;
case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, S - P - 4); break;
- case IMAGE_REL_ARM_SECREL: add32(Off, Sym->getSecrel()); break;
+ case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, Sym); break;
default:
fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
}
@@ -226,8 +241,12 @@ bool SectionChunk::isCOMDAT() const {
void SectionChunk::printDiscardedMessage() const {
// Removed by dead-stripping. If it's removed by ICF, ICF already
// printed out the name, so don't repeat that here.
- if (Sym && this == Repl)
- message("Discarded " + Sym->getName());
+ if (Sym && this == Repl) {
+ if (Discarded)
+ message("Discarded comdat symbol " + Sym->getName());
+ else if (!Live)
+ message("Discarded " + Sym->getName());
+ }
}
StringRef SectionChunk::getDebugName() {
diff --git a/COFF/Chunks.h b/COFF/Chunks.h
index f7412517765c..54fffc5f6d08 100644
--- a/COFF/Chunks.h
+++ b/COFF/Chunks.h
@@ -64,7 +64,6 @@ public:
uint64_t getRVA() const { return RVA; }
uint32_t getAlign() const { return Align; }
void setRVA(uint64_t V) { RVA = V; }
- void setOutputSectionOff(uint64_t V) { OutputSectionOff = V; }
// Returns true if this has non-zero data. BSS chunks return
// false. If false is returned, the space occupied by this chunk
@@ -97,17 +96,19 @@ protected:
Chunk(Kind K = OtherKind) : ChunkKind(K) {}
const Kind ChunkKind;
+ // The alignment of this chunk. The writer uses the value.
+ uint32_t Align = 1;
+
// The RVA of this chunk in the output. The writer sets a value.
uint64_t RVA = 0;
+public:
// The offset from beginning of the output section. The writer sets a value.
uint64_t OutputSectionOff = 0;
+protected:
// The output section for this chunk.
OutputSection *Out = nullptr;
-
- // The alignment of this chunk. The writer uses the value.
- uint32_t Align = 1;
};
// A chunk corresponding a section of an input file.
@@ -159,13 +160,29 @@ public:
StringRef getDebugName() override;
void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }
+ // Returns true if the chunk was not dropped by GC or COMDAT deduplication.
+ bool isLive() { return Live && !Discarded; }
+
// Used by the garbage collector.
- bool isLive() { return !Config->DoGC || Live; }
void markLive() {
+ assert(Config->DoGC && "should only mark things live from GC");
assert(!isLive() && "Cannot mark an already live section!");
Live = true;
}
+ // Returns true if this chunk was dropped by COMDAT deduplication.
+ bool isDiscarded() const { return Discarded; }
+
+ // Used by the SymbolTable when discarding unused comdat sections. This is
+ // redundant when GC is enabled, as all comdat sections will start out dead.
+ void markDiscarded() { Discarded = true; }
+
+ // True if this is a codeview debug info chunk. These will not be laid out in
+ // the image. Instead they will end up in the PDB, if one is requested.
+ bool isCodeView() const {
+ return SectionName == ".debug" || SectionName.startswith(".debug$");
+ }
+
// 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()),
@@ -196,6 +213,9 @@ private:
llvm::iterator_range<const coff_relocation *> Relocs;
size_t NumRelocs;
+ // True if this chunk was discarded because it was a duplicate comdat section.
+ bool Discarded;
+
// Used by the garbage collector.
bool Live;
diff --git a/COFF/Config.h b/COFF/Config.h
index d859b1fbb7d9..9fcea96d65d3 100644
--- a/COFF/Config.h
+++ b/COFF/Config.h
@@ -161,9 +161,6 @@ struct Configuration {
bool LargeAddressAware = false;
bool HighEntropyVA = false;
bool AppContainer = false;
-
- // This is for debugging.
- bool DumpPdb = false;
};
extern Configuration *Config;
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index 71a9c679d19f..22efb312ae49 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -905,7 +905,6 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->TerminalServerAware = false;
if (Args.hasArg(OPT_nosymtab))
Config->WriteSymtab = false;
- Config->DumpPdb = Args.hasArg(OPT_dumppdb);
Config->MapFile = getMapFile(Args);
@@ -936,9 +935,9 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->Machine = AMD64;
}
- // Windows specific -- Input files can be Windows resource files (.res files).
- // We invoke cvtres.exe to convert resource files to a regular COFF file
- // then link the result file normally.
+ // Input files can be Windows resource files (.res files). We use
+ // WindowsResource to convert resource files to a regular COFF file,
+ // then link the resulting file normally.
if (!Resources.empty())
addBuffer(convertResToCOFF(Resources));
@@ -1027,17 +1026,21 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
if (Config->ImageBase == uint64_t(-1))
Config->ImageBase = getDefaultImageBase();
- Symtab.addRelative(mangle("__ImageBase"), 0);
+ Symtab.addSynthetic(mangle("__ImageBase"), nullptr);
if (Config->Machine == I386) {
- Config->SEHTable = Symtab.addRelative("___safe_se_handler_table", 0);
- Config->SEHCount = Symtab.addAbsolute("___safe_se_handler_count", 0);
+ Symtab.addAbsolute("___safe_se_handler_table", 0);
+ Symtab.addAbsolute("___safe_se_handler_count", 0);
}
// We do not support /guard:cf (control flow protection) yet.
// Define CFG symbols anyway so that we can link MSVC 2015 CRT.
- Symtab.addAbsolute(mangle("__guard_fids_table"), 0);
Symtab.addAbsolute(mangle("__guard_fids_count"), 0);
+ Symtab.addAbsolute(mangle("__guard_fids_table"), 0);
Symtab.addAbsolute(mangle("__guard_flags"), 0x100);
+ Symtab.addAbsolute(mangle("__guard_iat_count"), 0);
+ Symtab.addAbsolute(mangle("__guard_iat_table"), 0);
+ Symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
+ Symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
// This code may add new undefined symbols to the link, which may enqueue more
// symbol resolution tasks, so we need to continue executing tasks until we
diff --git a/COFF/Driver.h b/COFF/Driver.h
index 3eb950cca25c..2b5d1e7ae28b 100644
--- a/COFF/Driver.h
+++ b/COFF/Driver.h
@@ -178,7 +178,7 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
// Create enum with OPT_xxx values for each option in Options.td
enum {
OPT_INVALID = 0,
-#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
+#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index 42619b8fa438..d0152b0917b6 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -20,12 +20,15 @@
#include "Symbols.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/WindowsResource.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
@@ -41,6 +44,9 @@ namespace lld {
namespace coff {
namespace {
+const uint16_t SUBLANG_ENGLISH_US = 0x0409;
+const uint16_t RT_MANIFEST = 24;
+
class Executor {
public:
explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
@@ -257,26 +263,6 @@ void parseManifestUAC(StringRef Arg) {
}
}
-// Quote each line with "". Existing double-quote is converted
-// to two double-quotes.
-static void quoteAndPrint(raw_ostream &Out, StringRef S) {
- while (!S.empty()) {
- StringRef Line;
- std::tie(Line, S) = S.split("\n");
- if (Line.empty())
- continue;
- Out << '\"';
- for (int I = 0, E = Line.size(); I != E; ++I) {
- if (Line[I] == '\"') {
- Out << "\"\"";
- } else {
- Out << Line[I];
- }
- }
- Out << "\"\n";
- }
-}
-
// An RAII temporary file class that automatically removes a temporary file.
namespace {
class TemporaryFile {
@@ -390,38 +376,64 @@ static std::string createManifestXml() {
return readFile(File2.Path);
}
+static std::unique_ptr<MemoryBuffer>
+createMemoryBufferForManifestRes(size_t ManifestSize) {
+ size_t ResSize = alignTo(object::WIN_RES_MAGIC_SIZE +
+ object::WIN_RES_NULL_ENTRY_SIZE +
+ sizeof(object::WinResHeaderPrefix) +
+ sizeof(object::WinResIDs) +
+ sizeof(object::WinResHeaderSuffix) +
+ ManifestSize,
+ object::WIN_RES_DATA_ALIGNMENT);
+ return MemoryBuffer::getNewMemBuffer(ResSize);
+}
+
+static void writeResFileHeader(char *&Buf) {
+ memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
+ Buf += sizeof(COFF::WinResMagic);
+ memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
+ Buf += object::WIN_RES_NULL_ENTRY_SIZE;
+}
+
+static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
+ // Write the prefix.
+ auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
+ Prefix->DataSize = ManifestSize;
+ Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
+ sizeof(object::WinResIDs) +
+ sizeof(object::WinResHeaderSuffix);
+ Buf += sizeof(object::WinResHeaderPrefix);
+
+ // Write the Type/Name IDs.
+ auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
+ IDs->setType(RT_MANIFEST);
+ IDs->setName(Config->ManifestID);
+ Buf += sizeof(object::WinResIDs);
+
+ // Write the suffix.
+ auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
+ Suffix->DataVersion = 0;
+ Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
+ Suffix->Language = SUBLANG_ENGLISH_US;
+ Suffix->Version = 0;
+ Suffix->Characteristics = 0;
+ Buf += sizeof(object::WinResHeaderSuffix);
+}
+
// Create a resource file containing a manifest XML.
std::unique_ptr<MemoryBuffer> createManifestRes() {
- // Create a temporary file for the resource script file.
- TemporaryFile RCFile("manifest", "rc");
+ std::string Manifest = createManifestXml();
- // Open the temporary file for writing.
- std::error_code EC;
- raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text);
- if (EC)
- fatal(EC, "failed to open " + RCFile.Path);
-
- // Write resource script to the RC file.
- Out << "#define LANG_ENGLISH 9\n"
- << "#define SUBLANG_DEFAULT 1\n"
- << "#define APP_MANIFEST " << Config->ManifestID << "\n"
- << "#define RT_MANIFEST 24\n"
- << "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n"
- << "APP_MANIFEST RT_MANIFEST {\n";
- quoteAndPrint(Out, createManifestXml());
- Out << "}\n";
- Out.close();
-
- // Create output resource file.
- TemporaryFile ResFile("output-resource", "res");
-
- Executor E("rc.exe");
- E.add("/fo");
- E.add(ResFile.Path);
- E.add("/nologo");
- E.add(RCFile.Path);
- E.run();
- return ResFile.getMemoryBuffer();
+ std::unique_ptr<MemoryBuffer> Res =
+ createMemoryBufferForManifestRes(Manifest.size());
+
+ char *Buf = const_cast<char *>(Res->getBufferStart());
+ writeResFileHeader(Buf);
+ writeResEntryHeader(Buf, Manifest.size());
+
+ // Copy the manifest data into the .res file.
+ std::copy(Manifest.begin(), Manifest.end(), Buf);
+ return Res;
}
void createSideBySideManifest() {
@@ -592,40 +604,22 @@ void checkFailIfMismatch(StringRef Arg) {
// using cvtres.exe.
std::unique_ptr<MemoryBuffer>
convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
- // Create an output file path.
- TemporaryFile File("resource-file", "obj");
+ object::WindowsResourceParser Parser;
- // Execute cvtres.exe.
- Executor E("cvtres.exe");
- E.add("/machine:" + machineToStr(Config->Machine));
- E.add("/readonly");
- E.add("/nologo");
- E.add("/out:" + Twine(File.Path));
-
- // We must create new files because the memory buffers we have may have no
- // underlying file still existing on the disk.
- // It happens if it was created from a TemporaryFile, which usually delete
- // the file just after creating the MemoryBuffer.
- std::vector<TemporaryFile> ResFiles;
- ResFiles.reserve(MBs.size());
for (MemoryBufferRef MB : MBs) {
- // We store the temporary file in a vector to avoid deletion
- // before running cvtres
- ResFiles.emplace_back("resource-file", "res");
- TemporaryFile& ResFile = ResFiles.back();
- // Write the content of the resource in a temporary file
- std::error_code EC;
- raw_fd_ostream OS(ResFile.Path, EC, sys::fs::F_None);
- if (EC)
- fatal(EC, "failed to open " + ResFile.Path);
- OS << MB.getBuffer();
- OS.close();
-
- E.add(ResFile.Path);
+ std::unique_ptr<object::Binary> Bin = check(object::createBinary(MB));
+ object::WindowsResource *RF = dyn_cast<object::WindowsResource>(Bin.get());
+ if (!RF)
+ fatal("cannot compile non-resource file as resource");
+ if (auto EC = Parser.parse(RF))
+ fatal(EC, "failed to parse .res file");
}
- E.run();
- return File.getMemoryBuffer();
+ Expected<std::unique_ptr<MemoryBuffer>> E =
+ llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
+ if (!E)
+ fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF");
+ return std::move(E.get());
}
// Run MSVC link.exe for given in-memory object files.
@@ -657,11 +651,9 @@ void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
// Create table mapping all options defined in Options.td
static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
- { \
- X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
- OPT_##GROUP, OPT_##ALIAS, X6 \
- },
+#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
+ {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \
+ X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
#include "Options.inc"
#undef OPTION
};
diff --git a/COFF/InputFiles.cpp b/COFF/InputFiles.cpp
index 58e8dd329f1f..c26483e3e368 100644
--- a/COFF/InputFiles.cpp
+++ b/COFF/InputFiles.cpp
@@ -132,17 +132,17 @@ void ObjectFile::initializeChunks() {
if (!Config->Debug && Name.startswith(".debug"))
continue;
- // CodeView sections are stored to a different vector because they are
- // not linked in the regular manner.
- if (Name == ".debug" || Name.startswith(".debug$")) {
- DebugChunks.push_back(make<SectionChunk>(this, Sec));
- continue;
- }
-
if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
continue;
auto *C = make<SectionChunk>(this, Sec);
- Chunks.push_back(C);
+
+ // CodeView sections are stored to a different vector because they are not
+ // linked in the regular manner.
+ if (C->isCodeView())
+ DebugChunks.push_back(C);
+ else
+ Chunks.push_back(C);
+
SparseChunks[I] = C;
}
}
@@ -249,8 +249,12 @@ SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
if (auto *ParentSC = cast_or_null<SectionChunk>(
- SparseChunks[Aux->getNumber(Sym.isBigObj())]))
+ SparseChunks[Aux->getNumber(Sym.isBigObj())])) {
ParentSC->addAssociative(SC);
+ // If we already discarded the parent, discard the child.
+ if (ParentSC->isDiscarded())
+ SC->markDiscarded();
+ }
SC->Checksum = Aux->CheckSum;
}
diff --git a/COFF/Options.td b/COFF/Options.td
index 14a1aa04afd6..61523c4f2256 100644
--- a/COFF/Options.td
+++ b/COFF/Options.td
@@ -102,7 +102,6 @@ def nosymtab : F<"nosymtab">;
def msvclto : F<"msvclto">;
// Flags for debugging
-def dumppdb : Joined<["/", "-"], "dumppdb">;
def lldmap : F<"lldmap">;
def lldmap_file : Joined<["/", "-"], "lldmap:">;
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index 116766740e58..c9842cfd1b9a 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -15,10 +15,11 @@
#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/SymbolDumper.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.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"
@@ -46,8 +47,6 @@ using namespace lld;
using namespace lld::coff;
using namespace llvm;
using namespace llvm::codeview;
-using namespace llvm::support;
-using namespace llvm::support::endian;
using llvm::object::coff_section;
@@ -68,22 +67,24 @@ static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
return nullptr;
}
-static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
- SectionChunk *Sec = findByName(File->getDebugChunks(), SecName);
- if (!Sec)
- return {};
-
+static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
+ StringRef SecName) {
// First 4 bytes are section magic.
- ArrayRef<uint8_t> Data = Sec->getContents();
if (Data.size() < 4)
fatal(SecName + " too short");
- if (read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
+ if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
fatal(SecName + " has an invalid magic");
return Data.slice(4);
}
+static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
+ if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName))
+ return consumeDebugMagic(Sec->getContents(), SecName);
+ return {};
+}
+
static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
- codeview::TypeTableBuilder &TypeTable) {
+ TypeTableBuilder &TypeTable) {
// Start the TPI or IPI stream header.
TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
@@ -94,17 +95,148 @@ static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
});
}
+static void mergeDebugT(ObjectFile *File,
+ TypeTableBuilder &IDTable,
+ TypeTableBuilder &TypeTable,
+ SmallVectorImpl<TypeIndex> &TypeIndexMap,
+ pdb::PDBTypeServerHandler &Handler) {
+ ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
+ if (Data.empty())
+ return;
+
+ 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");
+ if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
+ TypeIndexMap, &Handler, Types))
+ fatal(Err, "codeview::mergeTypeStreams failed");
+}
+
+static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
+ if (TI.isSimple())
+ return true;
+ if (TI.toArrayIndex() >= TypeIndexMap.size())
+ return false;
+ TI = TypeIndexMap[TI.toArrayIndex()];
+ return true;
+}
+
+static bool remapTypesInSymbolRecord(ObjectFile *File,
+ MutableArrayRef<uint8_t> Contents,
+ ArrayRef<TypeIndex> TypeIndexMap,
+ ArrayRef<TiReference> TypeRefs) {
+ for (const TiReference &Ref : TypeRefs) {
+ unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
+ if (Contents.size() < Ref.Offset + ByteSize) {
+ log("ignoring short symbol record");
+ return false;
+ }
+ MutableArrayRef<TypeIndex> TIs(
+ reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
+ for (TypeIndex &TI : TIs)
+ if (!remapTypeIndex(TI, TypeIndexMap)) {
+ log("ignoring symbol record in " + File->getName() +
+ " with bad type index 0x" + utohexstr(TI.getIndex()));
+ return false;
+ }
+ }
+ return true;
+}
+
+/// MSVC translates S_PROC_ID_END to S_END.
+uint16_t canonicalizeSymbolKind(SymbolKind Kind) {
+ if (Kind == SymbolKind::S_PROC_ID_END)
+ return SymbolKind::S_END;
+ return Kind;
+}
+
+/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
+/// The object file may not be aligned.
+static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym,
+ BumpPtrAllocator &Alloc) {
+ size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
+ assert(Size >= 4 && "record too short");
+ assert(Size <= MaxRecordLength && "record too long");
+ void *Mem = Alloc.Allocate(Size, 4);
+
+ // Copy the symbol record and zero out any padding bytes.
+ MutableArrayRef<uint8_t> NewData(reinterpret_cast<uint8_t *>(Mem), Size);
+ memcpy(NewData.data(), Sym.data().data(), Sym.length());
+ memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
+
+ // Update the record prefix length. It should point to the beginning of the
+ // next record. MSVC does some canonicalization of the record kind, so we do
+ // that as well.
+ auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem);
+ Prefix->RecordKind = canonicalizeSymbolKind(Sym.kind());
+ Prefix->RecordLen = Size - 2;
+ return NewData;
+}
+
+static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
+ ArrayRef<TypeIndex> TypeIndexMap,
+ BinaryStreamRef SymData) {
+ // FIXME: Improve error recovery by warning and skipping records when
+ // possible.
+ CVSymbolArray Syms;
+ BinaryStreamReader Reader(SymData);
+ ExitOnErr(Reader.readArray(Syms, Reader.getLength()));
+ for (const CVSymbol &Sym : Syms) {
+ // Discover type index references in the record. Skip it if we don't know
+ // where they are.
+ SmallVector<TiReference, 32> TypeRefs;
+ if (!discoverTypeIndices(Sym, TypeRefs)) {
+ log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind()));
+ continue;
+ }
+
+ // Copy the symbol record so we can mutate it.
+ MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc);
+
+ // Re-map all the type index references.
+ MutableArrayRef<uint8_t> Contents =
+ NewData.drop_front(sizeof(RecordPrefix));
+ if (!remapTypesInSymbolRecord(File, Contents, TypeIndexMap, TypeRefs))
+ continue;
+
+ // FIXME: Fill in "Parent" and "End" fields by maintaining a stack of
+ // scopes.
+
+ // Add the symbol to the module.
+ File->ModuleDBI->addSymbol(CVSymbol(Sym.kind(), NewData));
+ }
+}
+
+// Allocate memory for a .debug$S section and relocate it.
+static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
+ SectionChunk *DebugChunk) {
+ uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
+ assert(DebugChunk->OutputSectionOff == 0 &&
+ "debug sections should not be in output sections");
+ DebugChunk->writeTo(Buffer);
+ return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
+ ".debug$S");
+}
+
// Add all object files to the PDB. Merge .debug$T sections into IpiData and
// TpiData.
-static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
- codeview::TypeTableBuilder &TypeTable,
- codeview::TypeTableBuilder &IDTable) {
+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
@@ -118,25 +250,74 @@ static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
File->ModuleDBI->setObjFileName(Path);
- // FIXME: Walk the .debug$S sections and add them. Do things like recording
- // source files.
-
- ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
- if (Data.empty())
- continue;
-
- BinaryByteStream Stream(Data, support::little);
- codeview::CVTypeArray Types;
- BinaryStreamReader Reader(Stream);
- SmallVector<TypeIndex, 128> SourceToDest;
- Handler.addSearchPath(llvm::sys::path::parent_path(File->getName()));
- if (auto EC = Reader.readArray(Types, Reader.getLength()))
- fatal(EC, "Reader::readArray failed");
- if (auto Err = codeview::mergeTypeAndIdRecords(
- IDTable, TypeTable, SourceToDest, &Handler, Types))
- fatal(Err, "codeview::mergeTypeStreams failed");
+ // 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;
+
+ 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;
+ }
+ }
+
+ 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));
+ }
+ }
}
+ Builder.getStringTableBuilder().setStrings(*PDBStrTab);
+
// Construct TPI stream contents.
addTypeInfo(Builder.getTpiBuilder(), TypeTable);
@@ -144,56 +325,10 @@ static void addObjectsToPDB(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder,
addTypeInfo(Builder.getIpiBuilder(), IDTable);
}
-static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) {
- ListScope LS(W, "DebugT");
- ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
- if (Data.empty())
- return;
-
- LazyRandomTypeCollection Types(Data, 100);
- TypeDumpVisitor TDV(Types, &W, false);
- // Use a default implementation that does not follow type servers and instead
- // just dumps the contents of the TypeServer2 record.
- if (auto EC = codeview::visitTypeStream(Types, TDV))
- fatal(EC, "CVTypeDumper::dump failed");
-}
-
-static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) {
- ListScope LS(W, "DebugS");
- ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$S");
- if (Data.empty())
- return;
-
- BinaryByteStream Stream(Data, llvm::support::little);
- CVSymbolArray Symbols;
- BinaryStreamReader Reader(Stream);
- if (auto EC = Reader.readArray(Symbols, Reader.getLength()))
- fatal(EC, "StreamReader.readArray<CVSymbolArray> failed");
-
- TypeDatabase TDB(0);
- CVSymbolDumper SymbolDumper(W, TDB, CodeViewContainer::ObjectFile, nullptr,
- false);
- if (auto EC = SymbolDumper.dump(Symbols))
- fatal(EC, "CVSymbolDumper::dump failed");
-}
-
-// Dump CodeView debug info. This is for debugging.
-static void dumpCodeView(SymbolTable *Symtab) {
- ScopedPrinter W(outs());
-
- for (ObjectFile *File : Symtab->ObjectFiles) {
- dumpDebugT(W, File);
- dumpDebugS(W, File);
- }
-}
-
// Creates a PDB file.
void coff::createPDB(StringRef Path, SymbolTable *Symtab,
ArrayRef<uint8_t> SectionTable,
const llvm::codeview::DebugInfo *DI) {
- if (Config->DumpPdb)
- dumpCodeView(Symtab);
-
BumpPtrAllocator Alloc;
pdb::PDBFileBuilder Builder(Alloc);
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
@@ -219,9 +354,9 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab,
pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setVersionHeader(pdb::PdbDbiV110);
- codeview::TypeTableBuilder TypeTable(BAlloc);
- codeview::TypeTableBuilder IDTable(BAlloc);
- addObjectsToPDB(Symtab, Builder, TypeTable, IDTable);
+ TypeTableBuilder TypeTable(BAlloc);
+ TypeTableBuilder IDTable(BAlloc);
+ addObjectsToPDB(Alloc, Symtab, Builder, TypeTable, IDTable);
// Add Section Contributions.
addSectionContribs(Symtab, DbiBuilder);
diff --git a/COFF/Strings.cpp b/COFF/Strings.cpp
index d0558413f673..84f9b9a55a32 100644
--- a/COFF/Strings.cpp
+++ b/COFF/Strings.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "Strings.h"
+#include <mutex>
#if defined(_MSC_VER)
#include <Windows.h>
@@ -21,6 +22,10 @@ using namespace llvm;
Optional<std::string> coff::demangle(StringRef S) {
#if defined(_MSC_VER)
+ // UnDecorateSymbolName is not thread-safe, so we need a mutex.
+ static std::mutex Mu;
+ std::lock_guard<std::mutex> Lock(Mu);
+
char Buf[4096];
if (S.startswith("?"))
if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
diff --git a/COFF/SymbolTable.cpp b/COFF/SymbolTable.cpp
index 310eab274526..c06e42bb114b 100644
--- a/COFF/SymbolTable.cpp
+++ b/COFF/SymbolTable.cpp
@@ -219,13 +219,13 @@ Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
return S;
}
-Symbol *SymbolTable::addRelative(StringRef N, uint64_t VA) {
+Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
Symbol *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
S->IsUsedInRegularObj = true;
if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
- replaceBody<DefinedRelative>(S, N, VA);
+ replaceBody<DefinedSynthetic>(S, N, C);
else if (!isa<DefinedCOFF>(S->body()))
reportDuplicate(S, nullptr);
return S;
@@ -244,6 +244,12 @@ Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
reportDuplicate(S, F);
} else if (SP == SP_NEW) {
replaceBody<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, C);
+ } else if (SP == SP_EXISTING && IsCOMDAT && C) {
+ C->markDiscarded();
+ // Discard associative chunks that we've parsed so far. No need to recurse
+ // because an associative section cannot have children.
+ for (SectionChunk *Child : C->children())
+ Child->markDiscarded();
}
return S;
}
diff --git a/COFF/SymbolTable.h b/COFF/SymbolTable.h
index 0aa8a4593b5c..ea74678c28d8 100644
--- a/COFF/SymbolTable.h
+++ b/COFF/SymbolTable.h
@@ -85,7 +85,7 @@ public:
// Creates an Undefined symbol for a given name.
SymbolBody *addUndefined(StringRef Name);
- Symbol *addRelative(StringRef N, uint64_t VA);
+ Symbol *addSynthetic(StringRef N, Chunk *C);
Symbol *addAbsolute(StringRef N, uint64_t VA);
Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
diff --git a/COFF/Symbols.cpp b/COFF/Symbols.cpp
index 5c185a511dd7..1cf2934a355b 100644
--- a/COFF/Symbols.cpp
+++ b/COFF/Symbols.cpp
@@ -61,6 +61,8 @@ COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
}
+uint16_t DefinedAbsolute::OutputSectionIndex = 0;
+
static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) {
if (Machine == AMD64)
return make<ImportThunkChunkX64>(S);
diff --git a/COFF/Symbols.h b/COFF/Symbols.h
index 801fc87f91d9..8c1390c45876 100644
--- a/COFF/Symbols.h
+++ b/COFF/Symbols.h
@@ -50,13 +50,13 @@ public:
DefinedImportThunkKind,
DefinedImportDataKind,
DefinedAbsoluteKind,
- DefinedRelativeKind,
+ DefinedSyntheticKind,
UndefinedKind,
LazyKind,
LastDefinedCOFFKind = DefinedCommonKind,
- LastDefinedKind = DefinedRelativeKind,
+ LastDefinedKind = DefinedSyntheticKind,
};
Kind kind() const { return static_cast<Kind>(SymbolKind); }
@@ -112,11 +112,11 @@ public:
// Returns the RVA relative to the beginning of the output section.
// Used to implement SECREL relocation type.
- uint64_t getSecrel();
+ uint32_t getSecrel();
// Returns the output section index.
// Used to implement SECTION relocation type.
- uint64_t getSectionIndex();
+ uint16_t getSectionIndex();
// Returns true if this symbol points to an executable (e.g. .text) section.
// Used to implement ARM relocations.
@@ -167,6 +167,7 @@ public:
bool isCOMDAT() { return IsCOMDAT; }
SectionChunk *getChunk() { return *Data; }
uint32_t getValue() { return Sym->Value; }
+ uint32_t getSecrel();
private:
SectionChunk **Data;
@@ -186,6 +187,8 @@ public:
}
uint64_t getRVA() { return Data->getRVA(); }
+ uint32_t getSecrel() { return Data->OutputSectionOff; }
+ uint16_t getSectionIndex();
private:
friend SymbolTable;
@@ -212,28 +215,34 @@ public:
uint64_t getRVA() { return VA - Config->ImageBase; }
void setVA(uint64_t V) { VA = V; }
+ // The sentinel absolute symbol section index. Section index relocations
+ // against absolute symbols resolve to this 16 bit number, and it is the
+ // largest valid section index plus one. This is written by the Writer.
+ static uint16_t OutputSectionIndex;
+
private:
uint64_t VA;
};
-// This is a kind of absolute symbol but relative to the image base.
-// Unlike absolute symbols, relocations referring this kind of symbols
-// are subject of the base relocation. This type is used rarely --
-// mainly for __ImageBase.
-class DefinedRelative : public Defined {
+// This symbol is used for linker-synthesized symbols like __ImageBase and
+// __safe_se_handler_table.
+class DefinedSynthetic : public Defined {
public:
- explicit DefinedRelative(StringRef Name, uint64_t V = 0)
- : Defined(DefinedRelativeKind, Name), RVA(V) {}
+ explicit DefinedSynthetic(StringRef Name, Chunk *C)
+ : Defined(DefinedSyntheticKind, Name), C(C) {}
static bool classof(const SymbolBody *S) {
- return S->kind() == DefinedRelativeKind;
+ return S->kind() == DefinedSyntheticKind;
}
- uint64_t getRVA() { return RVA; }
- void setRVA(uint64_t V) { RVA = V; }
+ // A null chunk indicates that this is __ImageBase. Otherwise, this is some
+ // other synthesized chunk, like SEHTableChunk.
+ uint32_t getRVA() const { return C ? C->getRVA() : 0; }
+ uint32_t getSecrel() const { return C ? C->OutputSectionOff : 0; }
+ Chunk *getChunk() const { return C; }
private:
- uint64_t RVA;
+ Chunk *C;
};
// This class represents a symbol defined in an archive file. It is
@@ -350,8 +359,8 @@ inline uint64_t Defined::getRVA() {
switch (kind()) {
case DefinedAbsoluteKind:
return cast<DefinedAbsolute>(this)->getRVA();
- case DefinedRelativeKind:
- return cast<DefinedRelative>(this)->getRVA();
+ case DefinedSyntheticKind:
+ return cast<DefinedSynthetic>(this)->getRVA();
case DefinedImportDataKind:
return cast<DefinedImportData>(this)->getRVA();
case DefinedImportThunkKind:
@@ -386,7 +395,7 @@ struct Symbol {
// AlignedCharArrayUnion gives us a struct with a char array field that is
// large and aligned enough to store any derived class of SymbolBody.
llvm::AlignedCharArrayUnion<
- DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedRelative, Lazy,
+ DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy,
Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport>
Body;
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index fb1f3cae5bb2..d32577b361fa 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -181,7 +181,7 @@ void OutputSection::addChunk(Chunk *C) {
uint64_t Off = Header.VirtualSize;
Off = alignTo(Off, C->getAlign());
C->setRVA(Off);
- C->setOutputSectionOff(Off);
+ C->OutputSectionOff = Off;
Off += C->getSize();
Header.VirtualSize = Off;
if (C->hasData())
@@ -210,16 +210,46 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
}
}
-uint64_t Defined::getSecrel() {
- if (auto *D = dyn_cast<DefinedRegular>(this))
- return getRVA() - D->getChunk()->getOutputSection()->getRVA();
- fatal("SECREL relocation points to a non-regular symbol");
+uint32_t Defined::getSecrel() {
+ assert(this);
+ switch (kind()) {
+ case DefinedRegularKind:
+ return cast<DefinedRegular>(this)->getSecrel();
+ case DefinedCommonKind:
+ return cast<DefinedCommon>(this)->getSecrel();
+ case DefinedSyntheticKind:
+ return cast<DefinedSynthetic>(this)->getSecrel();
+ default:
+ break;
+ }
+ fatal("SECREL relocation points to a non-regular symbol: " + toString(*this));
+}
+
+uint32_t DefinedRegular::getSecrel() {
+ assert(getChunk()->isLive() && "relocation against discarded section");
+ uint64_t Diff = getRVA() - getChunk()->getOutputSection()->getRVA();
+ assert(Diff < UINT32_MAX && "section offset too large");
+ return (uint32_t)Diff;
}
-uint64_t Defined::getSectionIndex() {
+uint16_t Defined::getSectionIndex() {
if (auto *D = dyn_cast<DefinedRegular>(this))
return D->getChunk()->getOutputSection()->SectionIndex;
- fatal("SECTION relocation points to a non-regular symbol");
+ if (isa<DefinedAbsolute>(this))
+ return DefinedAbsolute::OutputSectionIndex;
+ if (auto *D = dyn_cast<DefinedCommon>(this))
+ return D->getSectionIndex();
+ if (auto *D = dyn_cast<DefinedSynthetic>(this)) {
+ if (!D->getChunk())
+ return 0;
+ return D->getChunk()->getOutputSection()->SectionIndex;
+ }
+ fatal("SECTION relocation points to a non-regular symbol: " +
+ toString(*this));
+}
+
+uint16_t DefinedCommon::getSectionIndex() {
+ return Data->getOutputSection()->SectionIndex;
}
bool Defined::isExecutable() {
@@ -345,12 +375,19 @@ void Writer::createMiscChunks() {
for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) {
if (!File->SEHCompat)
return;
- for (SymbolBody *B : File->SEHandlers)
- Handlers.insert(cast<Defined>(B));
+ for (SymbolBody *B : File->SEHandlers) {
+ // Make sure the handler is still live. Assume all handlers are regular
+ // symbols.
+ auto *D = dyn_cast<DefinedRegular>(B);
+ if (D && D->getChunk()->isLive())
+ Handlers.insert(D);
+ }
}
- SEHTable = make<SEHTableChunk>(Handlers);
- RData->addChunk(SEHTable);
+ if (!Handlers.empty()) {
+ SEHTable = make<SEHTableChunk>(Handlers);
+ RData->addChunk(SEHTable);
+ }
}
// Create .idata section for the DLL-imported symbol table.
@@ -442,12 +479,15 @@ size_t Writer::addEntryToStringTable(StringRef Str) {
Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
// Relative symbols are unrepresentable in a COFF symbol table.
- if (isa<DefinedRelative>(Def))
+ if (isa<DefinedSynthetic>(Def))
return None;
- if (auto *D = dyn_cast<DefinedRegular>(Def))
- if (!D->getChunk()->isLive())
+ if (auto *D = dyn_cast<DefinedRegular>(Def)) {
+ // Don't write dead symbols or symbols in codeview sections to the symbol
+ // table.
+ if (!D->getChunk()->isLive() || D->getChunk()->isCodeView())
return None;
+ }
if (auto *Sym = dyn_cast<DefinedImportData>(Def))
if (!Sym->File->Live)
@@ -599,6 +639,15 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
Buf += sizeof(*PE);
PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
+
+ // If {Major,Minor}LinkerVersion is left at 0.0, then for some
+ // reason signing the resulting PE file with Authenticode produces a
+ // signature that fails to validate on Windows 7 (but is OK on 10).
+ // Set it to 14.0, which is what VS2015 outputs, and which avoids
+ // that problem.
+ PE->MajorLinkerVersion = 14;
+ PE->MinorLinkerVersion = 0;
+
PE->ImageBase = Config->ImageBase;
PE->SectionAlignment = PageSize;
PE->FileAlignment = SectorSize;
@@ -743,10 +792,13 @@ void Writer::openFile(StringRef Path) {
void Writer::fixSafeSEHSymbols() {
if (!SEHTable)
return;
- if (auto *T = dyn_cast<DefinedRelative>(Config->SEHTable->body()))
- T->setRVA(SEHTable->getRVA());
- if (auto *C = dyn_cast<DefinedAbsolute>(Config->SEHCount->body()))
- C->setVA(SEHTable->getSize() / 4);
+ // Replace the absolute table symbol with a synthetic symbol pointing to the
+ // SEHTable chunk so that we can emit base relocations for it and resolve
+ // section relative relocations.
+ Symbol *T = Symtab->find("___safe_se_handler_table");
+ Symbol *C = Symtab->find("___safe_se_handler_count");
+ replaceBody<DefinedSynthetic>(T, T->body()->getName(), SEHTable);
+ cast<DefinedAbsolute>(C->body())->setVA(SEHTable->getSize() / 4);
}
// Handles /section options to allow users to overwrite
@@ -762,6 +814,10 @@ void Writer::setSectionPermissions() {
// Write section contents to a mmap'ed file.
void Writer::writeSections() {
+ // Record the section index that should be used when resolving a section
+ // relocation against an absolute symbol.
+ DefinedAbsolute::OutputSectionIndex = OutputSections.size() + 1;
+
uint8_t *Buf = Buffer->getBufferStart();
for (OutputSection *Sec : OutputSections) {
uint8_t *SecBuf = Buf + Sec->getFileOff();
diff --git a/ELF/Arch/AArch64.cpp b/ELF/Arch/AArch64.cpp
index 113d0960d5f5..b26cf0815109 100644
--- a/ELF/Arch/AArch64.cpp
+++ b/ELF/Arch/AArch64.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "Error.h"
-#include "Memory.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -371,4 +370,7 @@ void AArch64::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
}
-TargetInfo *elf::createAArch64TargetInfo() { return make<AArch64>(); }
+TargetInfo *elf::getAArch64TargetInfo() {
+ static AArch64 Target;
+ return &Target;
+}
diff --git a/ELF/Arch/AMDGPU.cpp b/ELF/Arch/AMDGPU.cpp
index 68e516f9e6cf..de566c617ac0 100644
--- a/ELF/Arch/AMDGPU.cpp
+++ b/ELF/Arch/AMDGPU.cpp
@@ -9,7 +9,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "Symbols.h"
#include "Target.h"
#include "llvm/Object/ELF.h"
@@ -79,4 +78,7 @@ RelExpr AMDGPU::getRelExpr(uint32_t Type, const SymbolBody &S,
}
}
-TargetInfo *elf::createAMDGPUTargetInfo() { return make<AMDGPU>(); }
+TargetInfo *elf::getAMDGPUTargetInfo() {
+ static AMDGPU Target;
+ return &Target;
+}
diff --git a/ELF/Arch/ARM.cpp b/ELF/Arch/ARM.cpp
index b245cbd7005a..e4b06ade4487 100644
--- a/ELF/Arch/ARM.cpp
+++ b/ELF/Arch/ARM.cpp
@@ -9,7 +9,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -58,6 +57,7 @@ ARM::ARM() {
GotPltEntrySize = 4;
PltEntrySize = 16;
PltHeaderSize = 20;
+ TrapInstr = 0xd4d4d4d4;
// ARM uses Variant 1 TLS
TcbSize = 8;
NeedsThunks = true;
@@ -429,4 +429,7 @@ int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
}
}
-TargetInfo *elf::createARMTargetInfo() { return make<ARM>(); }
+TargetInfo *elf::getARMTargetInfo() {
+ static ARM Target;
+ return &Target;
+}
diff --git a/ELF/Arch/AVR.cpp b/ELF/Arch/AVR.cpp
index 86343a6faa16..3853248f8fbd 100644
--- a/ELF/Arch/AVR.cpp
+++ b/ELF/Arch/AVR.cpp
@@ -28,7 +28,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "Symbols.h"
#include "Target.h"
#include "llvm/Object/ELF.h"
@@ -75,4 +74,7 @@ void AVR::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
}
}
-TargetInfo *elf::createAVRTargetInfo() { return make<AVR>(); }
+TargetInfo *elf::getAVRTargetInfo() {
+ static AVR Target;
+ return &Target;
+}
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index 79642df8a885..b8d796f5897a 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -9,7 +9,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "OutputSections.h"
#include "Symbols.h"
#include "SyntheticSections.h"
@@ -55,6 +54,7 @@ template <class ELFT> MIPS<ELFT>::MIPS() {
CopyRel = R_MIPS_COPY;
PltRel = R_MIPS_JUMP_SLOT;
NeedsThunks = true;
+ TrapInstr = 0xefefefef;
if (ELFT::Is64Bits) {
RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
@@ -412,11 +412,12 @@ bool MIPS<ELFT>::usesOnlyLowPageBits(uint32_t Type) const {
return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST;
}
-template <class ELFT> TargetInfo *elf::createMipsTargetInfo() {
- return make<MIPS<ELFT>>();
+template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
+ static MIPS<ELFT> Target;
+ return &Target;
}
-template TargetInfo *elf::createMipsTargetInfo<ELF32LE>();
-template TargetInfo *elf::createMipsTargetInfo<ELF32BE>();
-template TargetInfo *elf::createMipsTargetInfo<ELF64LE>();
-template TargetInfo *elf::createMipsTargetInfo<ELF64BE>();
+template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
+template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
+template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
+template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
diff --git a/ELF/Mips.cpp b/ELF/Arch/MipsArchTree.cpp
index af92fb9d24fd..ed183e9a3061 100644
--- a/ELF/Mips.cpp
+++ b/ELF/Arch/MipsArchTree.cpp
@@ -1,4 +1,4 @@
-//===- Mips.cpp ----------------------------------------------------------===//
+//===- MipsArchTree.cpp --------------------------------------------------===//
//
// The LLVM Linker
//
diff --git a/ELF/Arch/PPC.cpp b/ELF/Arch/PPC.cpp
index b5f0d5b4c687..19e10729a00e 100644
--- a/ELF/Arch/PPC.cpp
+++ b/ELF/Arch/PPC.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "Error.h"
-#include "Memory.h"
#include "Symbols.h"
#include "Target.h"
#include "llvm/Support/Endian.h"
@@ -22,7 +21,7 @@ using namespace lld::elf;
namespace {
class PPC final : public TargetInfo {
public:
- PPC() {}
+ PPC() { GotBaseSymOff = 0x8000; }
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
const uint8_t *Loc) const override;
@@ -60,4 +59,7 @@ RelExpr PPC::getRelExpr(uint32_t Type, const SymbolBody &S,
}
}
-TargetInfo *elf::createPPCTargetInfo() { return make<PPC>(); }
+TargetInfo *elf::getPPCTargetInfo() {
+ static PPC Target;
+ return &Target;
+}
diff --git a/ELF/Arch/PPC64.cpp b/ELF/Arch/PPC64.cpp
index eb1e917d5790..bf414d75bec7 100644
--- a/ELF/Arch/PPC64.cpp
+++ b/ELF/Arch/PPC64.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "Error.h"
-#include "Memory.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -212,4 +211,7 @@ void PPC64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
}
}
-TargetInfo *elf::createPPC64TargetInfo() { return make<PPC64>(); }
+TargetInfo *elf::getPPC64TargetInfo() {
+ static PPC64 Target;
+ return &Target;
+}
diff --git a/ELF/Arch/X86.cpp b/ELF/Arch/X86.cpp
index bc0d2b81a613..a1e9bcaf1b12 100644
--- a/ELF/Arch/X86.cpp
+++ b/ELF/Arch/X86.cpp
@@ -9,7 +9,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -47,6 +46,7 @@ public:
} // namespace
X86::X86() {
+ GotBaseSymOff = -1;
CopyRel = R_386_COPY;
GotRel = R_386_GLOB_DAT;
PltRel = R_386_JUMP_SLOT;
@@ -60,9 +60,7 @@ X86::X86() {
PltEntrySize = 16;
PltHeaderSize = 16;
TlsGdRelaxSkip = 2;
-
- // 0xCC is the "int3" (call debug exception handler) instruction.
- TrapInstr = 0xcccccccc;
+ TrapInstr = 0xcccccccc; // 0xcc = INT3
}
RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S,
@@ -360,4 +358,7 @@ void X86::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
memcpy(Loc - 2, Inst, sizeof(Inst));
}
-TargetInfo *elf::createX86TargetInfo() { return make<X86>(); }
+TargetInfo *elf::getX86TargetInfo() {
+ static X86 Target;
+ return &Target;
+}
diff --git a/ELF/Arch/X86_64.cpp b/ELF/Arch/X86_64.cpp
index b790868c7125..10179f57ee93 100644
--- a/ELF/Arch/X86_64.cpp
+++ b/ELF/Arch/X86_64.cpp
@@ -9,7 +9,6 @@
#include "Error.h"
#include "InputFiles.h"
-#include "Memory.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -52,6 +51,7 @@ private:
} // namespace
template <class ELFT> X86_64<ELFT>::X86_64() {
+ GotBaseSymOff = -1;
CopyRel = R_X86_64_COPY;
GotRel = R_X86_64_GLOB_DAT;
PltRel = R_X86_64_JUMP_SLOT;
@@ -65,13 +65,11 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
PltEntrySize = 16;
PltHeaderSize = 16;
TlsGdRelaxSkip = 2;
+ TrapInstr = 0xcccccccc; // 0xcc = INT3
// Align to the large page size (known as a superpage or huge page).
// FreeBSD automatically promotes large, superpage-aligned allocations.
DefaultImageBase = 0x200000;
-
- // 0xCC is the "int3" (call debug exception handler) instruction.
- TrapInstr = 0xcccccccc;
}
template <class ELFT>
@@ -464,5 +462,12 @@ void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
write32le(Loc - 1, Val + 1);
}
-TargetInfo *elf::createX32TargetInfo() { return make<X86_64<ELF32LE>>(); }
-TargetInfo *elf::createX86_64TargetInfo() { return make<X86_64<ELF64LE>>(); }
+TargetInfo *elf::getX32TargetInfo() {
+ static X86_64<ELF32LE> Target;
+ return &Target;
+}
+
+TargetInfo *elf::getX86_64TargetInfo() {
+ static X86_64<ELF64LE> Target;
+ return &Target;
+}
diff --git a/ELF/CMakeLists.txt b/ELF/CMakeLists.txt
index 09a19fee14b2..b4bc215a77eb 100644
--- a/ELF/CMakeLists.txt
+++ b/ELF/CMakeLists.txt
@@ -12,6 +12,7 @@ add_lld_library(lldELF
Arch/ARM.cpp
Arch/AVR.cpp
Arch/Mips.cpp
+ Arch/MipsArchTree.cpp
Arch/PPC.cpp
Arch/PPC64.cpp
Arch/X86.cpp
@@ -29,7 +30,6 @@ add_lld_library(lldELF
LinkerScript.cpp
MapFile.cpp
MarkLive.cpp
- Mips.cpp
OutputSections.cpp
Relocations.cpp
ScriptLexer.cpp
diff --git a/ELF/Config.h b/ELF/Config.h
index 9c73b4c9c068..32e86b0ec7b6 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -70,7 +70,7 @@ struct VersionDefinition {
// Structure for mapping renamed symbols
struct RenamedSymbol {
Symbol *Target;
- uint8_t OrigBinding;
+ uint8_t OriginalBinding;
};
// This struct contains the global configuration for the linker.
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index f24c941fe773..5fb33caea46f 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -200,6 +200,7 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
error("attempted static link of dynamic object " + Path);
return;
}
+
// DSOs usually have DT_SONAME tags in their ELF headers, and the
// sonames are used to identify DSOs. But if they are missing,
// they are identified by filenames. We don't know whether the new
@@ -210,8 +211,8 @@ void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
// If a file was specified by -lfoo, the directory part is not
// significant, as a user did not specify it. This behavior is
// compatible with GNU.
- Files.push_back(createSharedFile(
- MBRef, WithLOption ? sys::path::filename(Path) : Path));
+ Files.push_back(
+ createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path));
return;
default:
if (InLib)
@@ -301,7 +302,7 @@ static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key,
for (auto *Arg : Args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
if (KV.first == Key) {
- uint64_t Result;
+ uint64_t Result = Default;
if (!to_integer(KV.second, Result))
error("invalid " + Key + ": " + KV.second);
return Result;
@@ -907,12 +908,47 @@ getDefsym(opt::InputArgList &Args) {
return Ret;
}
+// Parses `--exclude-libs=lib,lib,...`.
+// The library names may be delimited by commas or colons.
+static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
+ DenseSet<StringRef> Ret;
+ for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
+ StringRef S = Arg->getValue();
+ for (;;) {
+ size_t Pos = S.find_first_of(",:");
+ if (Pos == StringRef::npos)
+ break;
+ Ret.insert(S.substr(0, Pos));
+ S = S.substr(Pos + 1);
+ }
+ Ret.insert(S);
+ }
+ return Ret;
+}
+
+// Handles the -exclude-libs option. If a static library file is specified
+// by the -exclude-libs option, all public symbols from the archive become
+// private unless otherwise specified by version scripts or something.
+// A special library name "ALL" means all archive files.
+//
+// This is not a popular option, but some programs such as bionic libc use it.
+static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) {
+ DenseSet<StringRef> Libs = getExcludeLibs(Args);
+ bool All = Libs.count("ALL");
+
+ for (InputFile *File : Files)
+ if (auto *F = dyn_cast<ArchiveFile>(File))
+ if (All || Libs.count(path::filename(F->getName())))
+ for (Symbol *Sym : F->getSymbols())
+ Sym->VersionId = VER_NDX_LOCAL;
+}
+
// Do actual linking. Note that when this function is called,
// all linker scripts have already been parsed.
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
SymbolTable<ELFT> Symtab;
elf::Symtab<ELFT>::X = &Symtab;
- Target = createTarget();
+ Target = getTarget();
Config->MaxPageSize = getMaxPageSize(Args);
Config->ImageBase = getImageBase(Args);
@@ -958,8 +994,17 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
if (ErrorCount)
return;
+ // Handle the `--undefined <sym>` options.
Symtab.scanUndefinedFlags();
+
+ // Handle undefined symbols in DSOs.
Symtab.scanShlibUndefined();
+
+ // Handle the -exclude-libs option.
+ if (Args.hasArg(OPT_exclude_libs))
+ excludeLibs(Args, Files);
+
+ // Apply version scripts.
Symtab.scanVersionScript();
// Create wrapped symbols for -wrap option.
diff --git a/ELF/Driver.h b/ELF/Driver.h
index af88341632f4..076dda7730ac 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -58,7 +58,7 @@ public:
// Create enum with OPT_xxx values for each option in Options.td
enum {
OPT_INVALID = 0,
-#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
+#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};
diff --git a/ELF/DriverUtils.cpp b/ELF/DriverUtils.cpp
index f4eadeee9e43..5adb09176a3a 100644
--- a/ELF/DriverUtils.cpp
+++ b/ELF/DriverUtils.cpp
@@ -42,9 +42,9 @@ using namespace lld::elf;
// Create table mapping all options defined in Options.td
static const opt::OptTable::Info OptInfo[] = {
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
- {X1, X2, X9, X10, OPT_##ID, opt::Option::KIND##Class, \
- X8, X7, OPT_##GROUP, OPT_##ALIAS, X6},
+#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
+ {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
+ X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
#include "Options.inc"
#undef OPTION
};
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index 3d11239bf88f..1ff0b4224e70 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -632,8 +632,9 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
File(std::move(File)) {}
template <class ELFT> void ArchiveFile::parse() {
+ Symbols.reserve(File->getNumberOfSymbols());
for (const Archive::Symbol &Sym : File->symbols())
- Symtab<ELFT>::X->addLazyArchive(this, Sym);
+ Symbols.push_back(Symtab<ELFT>::X->addLazyArchive(this, Sym));
}
// Returns a buffer pointing to a member file containing a given symbol.
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 2eec78444837..544a0b009b39 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -251,6 +251,7 @@ public:
explicit ArchiveFile(std::unique_ptr<Archive> &&File);
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
template <class ELFT> void parse();
+ ArrayRef<Symbol *> getSymbols() { return Symbols; }
// Returns a memory buffer for a given symbol and the offset in the archive
// for the member. An empty memory buffer and an offset of zero
@@ -261,6 +262,7 @@ public:
private:
std::unique_ptr<Archive> File;
llvm::DenseSet<uint64_t> Seen;
+ std::vector<Symbol *> Symbols;
};
class BitcodeFile : public InputFile {
diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp
index 9aae82bc2992..b1d5e1349460 100644
--- a/ELF/InputSection.cpp
+++ b/ELF/InputSection.cpp
@@ -399,9 +399,16 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
}
}
+// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak
+// references specially. The general rule is that the value of the symbol in
+// this context is the address of the place P. A further special case is that
+// branch relocations to an undefined weak reference resolve to the next
+// instruction.
static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A,
uint32_t P) {
switch (Type) {
+ // Unresolved branch relocations to weak references resolve to next
+ // instruction, this will be either 2 or 4 bytes on from P.
case R_ARM_THM_JUMP11:
return P + 2 + A;
case R_ARM_CALL:
@@ -415,22 +422,38 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A,
case R_ARM_THM_CALL:
// We don't want an interworking BLX to ARM
return P + 5 + A;
- default:
+ // Unresolved non branch pc-relative relocations
+ // R_ARM_TARGET2 which can be resolved relatively is not present as it never
+ // targets a weak-reference.
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_REL32:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
return P + A;
}
+ llvm_unreachable("ARM pc-relative relocation expected\n");
}
+// The comment above getARMUndefinedRelativeWeakVA applies to this function.
static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
uint64_t P) {
switch (Type) {
+ // Unresolved branch relocations to weak references resolve to next
+ // instruction, this is 4 bytes on from P.
case R_AARCH64_CALL26:
case R_AARCH64_CONDBR19:
case R_AARCH64_JUMP26:
case R_AARCH64_TSTBR14:
return P + 4 + A;
- default:
+ // Unresolved non branch pc-relative relocations
+ case R_AARCH64_PREL16:
+ case R_AARCH64_PREL32:
+ case R_AARCH64_PREL64:
+ case R_AARCH64_ADR_PREL_LO21:
return P + A;
}
+ llvm_unreachable("AArch64 pc-relative relocation expected\n");
}
// ARM SBREL relocations are of the form S + A - B where B is the static base
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index f5a59f0c8c4d..d369a6f978a2 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -338,8 +338,9 @@ LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
for (InputSectionBase *S : V) {
S->Live = false;
- if (S == InX::ShStrTab)
- error("discarding .shstrtab section is not allowed");
+ if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
+ S == InX::DynStrTab)
+ error("discarding " + S->Name + " section is not allowed");
discard(S->DependentSections);
}
}
@@ -463,11 +464,6 @@ void LinkerScript::fabricateDefaultCommands() {
OSCmd->Sec = Sec;
SecToCommand[Sec] = OSCmd;
- // Prefer user supplied address over additional alignment constraint
- auto I = Config->SectionStartMap.find(Sec->Name);
- if (I != Config->SectionStartMap.end())
- OSCmd->AddrExpr = [=] { return I->second; };
-
Commands.push_back(OSCmd);
if (Sec->Sections.size()) {
auto *ISD = make<InputSectionDescription>("");
@@ -953,6 +949,8 @@ static bool compareByFilePosition(InputSection *A, InputSection *B) {
template <class ELFT>
static void finalizeShtGroup(OutputSection *OS,
ArrayRef<InputSection *> Sections) {
+ assert(Config->Relocatable && Sections.size() == 1);
+
// sh_link field for SHT_GROUP sections should contain the section index of
// the symbol table.
OS->Link = InX::SymTab->getParent()->SectionIndex;
@@ -960,7 +958,6 @@ static void finalizeShtGroup(OutputSection *OS,
// sh_info then contain index of an entry in symbol table section which
// provides signature of the section group.
elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
- assert(Config->Relocatable && Sections.size() == 1);
ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
}
@@ -1044,8 +1041,9 @@ template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
Sec->Loc = Buf;
- // We may have already rendered compressed content when using
- // -compress-debug-sections option. Write it together with header.
+ // If -compress-debug-section is specified and if this is a debug seciton,
+ // we've already compressed section contents. If that's the case,
+ // just write it down.
if (!Sec->CompressedData.empty()) {
memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
@@ -1109,18 +1107,27 @@ ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
+static const size_t NoPhdr = -1;
+
// Returns indices of ELF headers containing specific section. Each index is a
// zero based number of ELF header listed within PHDRS {} script block.
std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
if (OutputSectionCommand *Cmd = getCmd(Sec)) {
std::vector<size_t> Ret;
- for (StringRef PhdrName : Cmd->Phdrs)
- Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
+ for (StringRef PhdrName : Cmd->Phdrs) {
+ size_t Index = getPhdrIndex(Cmd->Location, PhdrName);
+ if (Index != NoPhdr)
+ Ret.push_back(Index);
+ }
return Ret;
}
return {};
}
+// Returns the index of the segment named PhdrName if found otherwise
+// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'
+// (which can be used to explicitly specify that a section isn't assigned to a
+// segment) then error.
size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
size_t I = 0;
for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
@@ -1128,8 +1135,9 @@ size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
return I;
++I;
}
- error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
- return 0;
+ if (PhdrName != "NONE")
+ error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
+ return NoPhdr;
}
template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
diff --git a/ELF/MarkLive.cpp b/ELF/MarkLive.cpp
index 0b4a78f8da6b..bde3eefc6d5f 100644
--- a/ELF/MarkLive.cpp
+++ b/ELF/MarkLive.cpp
@@ -78,7 +78,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
typename ELFT::uint Offset = D->Value;
if (D->isSection())
Offset += getAddend<ELFT>(Sec, Rel);
- Fn({cast<InputSectionBase>(D->Section)->Repl, Offset});
+ Fn({cast<InputSectionBase>(D->Section), Offset});
} else if (auto *U = dyn_cast<Undefined>(&B)) {
for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
Fn({Sec, 0});
diff --git a/ELF/Options.td b/ELF/Options.td
index 335c7ade6db2..29e14c530c6a 100644
--- a/ELF/Options.td
+++ b/ELF/Options.td
@@ -92,6 +92,9 @@ def error_limit: S<"error-limit">,
def error_unresolved_symbols: F<"error-unresolved-symbols">,
HelpText<"Report unresolved symbols as errors">;
+def exclude_libs: S<"exclude-libs">,
+ HelpText<"Exclude static libraries from automatic export">;
+
def export_dynamic: F<"export-dynamic">,
HelpText<"Put symbols in the dynamic symbol table">;
@@ -298,6 +301,7 @@ def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>;
def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
def alias_entry_entry: J<"entry=">, Alias<entry>;
def alias_error_limit: J<"error-limit=">, Alias<error_limit>;
+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>;
diff --git a/ELF/OutputSections.cpp b/ELF/OutputSections.cpp
index 6f04a04be8d0..c0bf6b32e6e2 100644
--- a/ELF/OutputSections.cpp
+++ b/ELF/OutputSections.cpp
@@ -273,7 +273,7 @@ void elf::reportDiscarded(InputSectionBase *IS) {
if (!Config->PrintGcSections)
return;
message("removing unused section from '" + IS->Name + "' in file '" +
- IS->File->getName());
+ IS->File->getName() + "'");
}
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
@@ -305,7 +305,7 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS,
SectionKey Key = createKey(IS, OutsecName);
OutputSection *&Sec = Map[Key];
- return addInputSec(IS, OutsecName, Sec);
+ addInputSec(IS, OutsecName, Sec);
}
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 1ac3bce769ee..fd823fe0ed42 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -361,7 +361,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
// These expressions always compute a constant
if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
- R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
+ R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD,
R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
return true;
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index a223aec98624..ab8802c86d8e 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -167,8 +167,8 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) {
// Tell LTO not to eliminate this symbol
Wrap->IsUsedInRegularObj = true;
- Config->RenamedSymbols[Real] = RenamedSymbol{Sym, Real->Binding};
- Config->RenamedSymbols[Sym] = RenamedSymbol{Wrap, Sym->Binding};
+ Config->RenamedSymbols[Real] = {Sym, Real->Binding};
+ Config->RenamedSymbols[Sym] = {Wrap, Sym->Binding};
}
// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
@@ -184,7 +184,7 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias,
// Tell LTO not to eliminate this symbol
Sym->IsUsedInRegularObj = true;
- Config->RenamedSymbols[AliasSym] = RenamedSymbol{Sym, AliasSym->Binding};
+ Config->RenamedSymbols[AliasSym] = {Sym, AliasSym->Binding};
}
// Apply symbol renames created by -wrap and -defsym. The renames are created
@@ -193,14 +193,16 @@ template <class ELFT> void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias,
// symbols are finalized, we can perform the replacement.
template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() {
for (auto &KV : Config->RenamedSymbols) {
- Symbol *Sym = KV.first;
- Symbol *Rename = KV.second.Target;
- Sym->Binding = KV.second.OrigBinding;
-
- // We rename symbols by replacing the old symbol's SymbolBody with the new
- // symbol's SymbolBody. This causes all SymbolBody pointers referring to the
- // old symbol to instead refer to the new symbol.
- memcpy(Sym->Body.buffer, Rename->Body.buffer, sizeof(Sym->Body));
+ Symbol *Dst = KV.first;
+ Symbol *Src = KV.second.Target;
+ Dst->Binding = KV.second.OriginalBinding;
+
+ // We rename symbols by replacing the old symbol's SymbolBody with
+ // the new symbol's SymbolBody. The only attribute we want to keep
+ // is the symbol name, so that two symbols don't have the same name.
+ StringRef S = Dst->body()->getName();
+ memcpy(Dst->Body.buffer, Src->Body.buffer, sizeof(Symbol::Body));
+ Dst->body()->setName(S);
}
}
@@ -518,18 +520,18 @@ SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) {
}
template <class ELFT>
-void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
- const object::Archive::Symbol Sym) {
+Symbol *SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
+ const object::Archive::Symbol Sym) {
Symbol *S;
bool WasInserted;
StringRef Name = Sym.getName();
std::tie(S, WasInserted) = insert(Name);
if (WasInserted) {
replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType);
- return;
+ return S;
}
if (!S->body()->isUndefined())
- return;
+ return S;
// Weak undefined symbols should not fetch members from archives. If we were
// to keep old symbol we would not know that an archive member was available
@@ -540,11 +542,12 @@ void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
// to preserve its type. FIXME: Move the Type field to Symbol.
if (S->isWeak()) {
replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type);
- return;
+ return S;
}
std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
if (!MBInfo.first.getBuffer().empty())
addFile(createObjectFile(MBInfo.first, F->getName(), MBInfo.second));
+ return S;
}
template <class ELFT>
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index f38d09760c7e..316d9c9bf373 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -66,7 +66,7 @@ public:
void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
const typename ELFT::Verdef *Verdef);
- void addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
+ Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
void addLazyObject(StringRef Name, LazyObjectFile &Obj);
Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File);
diff --git a/ELF/Symbols.cpp b/ELF/Symbols.cpp
index 8f9b20477b29..5dce71a32c9c 100644
--- a/ELF/Symbols.cpp
+++ b/ELF/Symbols.cpp
@@ -35,6 +35,7 @@ DefinedRegular *ElfSym::Edata1;
DefinedRegular *ElfSym::Edata2;
DefinedRegular *ElfSym::End1;
DefinedRegular *ElfSym::End2;
+DefinedRegular *ElfSym::GlobalOffsetTable;
DefinedRegular *ElfSym::MipsGp;
DefinedRegular *ElfSym::MipsGpDisp;
DefinedRegular *ElfSym::MipsLocalGp;
diff --git a/ELF/Symbols.h b/ELF/Symbols.h
index 030527f63744..406fd8e0f57b 100644
--- a/ELF/Symbols.h
+++ b/ELF/Symbols.h
@@ -69,6 +69,7 @@ public:
bool isLocal() const { return IsLocal; }
bool isPreemptible() const;
StringRef getName() const { return Name; }
+ void setName(StringRef S) { Name = S; }
uint8_t getVisibility() const { return StOther & 0x3; }
void parseSymbolVersion();
@@ -317,6 +318,11 @@ struct ElfSym {
static DefinedRegular *End1;
static DefinedRegular *End2;
+ // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+ // be at some offset from the base of the .got section, usually 0 or
+ // the end of the .got.
+ static DefinedRegular *GlobalOffsetTable;
+
// _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
static DefinedRegular *MipsGp;
static DefinedRegular *MipsGpDisp;
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index df3f4d6773f0..c1a85e165258 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -47,40 +47,40 @@ std::string lld::toString(uint32_t Type) {
return S;
}
-TargetInfo *elf::createTarget() {
+TargetInfo *elf::getTarget() {
switch (Config->EMachine) {
case EM_386:
case EM_IAMCU:
- return createX86TargetInfo();
+ return getX86TargetInfo();
case EM_AARCH64:
- return createAArch64TargetInfo();
+ return getAArch64TargetInfo();
case EM_AMDGPU:
- return createAMDGPUTargetInfo();
+ return getAMDGPUTargetInfo();
case EM_ARM:
- return createARMTargetInfo();
+ return getARMTargetInfo();
case EM_AVR:
- return createAVRTargetInfo();
+ return getAVRTargetInfo();
case EM_MIPS:
switch (Config->EKind) {
case ELF32LEKind:
- return createMipsTargetInfo<ELF32LE>();
+ return getMipsTargetInfo<ELF32LE>();
case ELF32BEKind:
- return createMipsTargetInfo<ELF32BE>();
+ return getMipsTargetInfo<ELF32BE>();
case ELF64LEKind:
- return createMipsTargetInfo<ELF64LE>();
+ return getMipsTargetInfo<ELF64LE>();
case ELF64BEKind:
- return createMipsTargetInfo<ELF64BE>();
+ return getMipsTargetInfo<ELF64BE>();
default:
fatal("unsupported MIPS target");
}
case EM_PPC:
- return createPPCTargetInfo();
+ return getPPCTargetInfo();
case EM_PPC64:
- return createPPC64TargetInfo();
+ return getPPC64TargetInfo();
case EM_X86_64:
if (Config->EKind == ELF32LEKind)
- return createX32TargetInfo();
- return createX86_64TargetInfo();
+ return getX32TargetInfo();
+ return getX86_64TargetInfo();
}
fatal("unknown target machine");
}
diff --git a/ELF/Target.h b/ELF/Target.h
index 79b03f876d0d..bf703fd0086a 100644
--- a/ELF/Target.h
+++ b/ELF/Target.h
@@ -66,6 +66,10 @@ public:
// Given that, the smallest value that can be used in here is 0x10000.
uint64_t DefaultImageBase = 0x10000;
+ // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
+ // end of .got
+ uint64_t GotBaseSymOff = 0;
+
uint32_t CopyRel;
uint32_t GotRel;
uint32_t PltRel;
@@ -102,16 +106,16 @@ public:
virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
};
-TargetInfo *createAArch64TargetInfo();
-TargetInfo *createAMDGPUTargetInfo();
-TargetInfo *createARMTargetInfo();
-TargetInfo *createAVRTargetInfo();
-TargetInfo *createPPC64TargetInfo();
-TargetInfo *createPPCTargetInfo();
-TargetInfo *createX32TargetInfo();
-TargetInfo *createX86TargetInfo();
-TargetInfo *createX86_64TargetInfo();
-template <class ELFT> TargetInfo *createMipsTargetInfo();
+TargetInfo *getAArch64TargetInfo();
+TargetInfo *getAMDGPUTargetInfo();
+TargetInfo *getARMTargetInfo();
+TargetInfo *getAVRTargetInfo();
+TargetInfo *getPPC64TargetInfo();
+TargetInfo *getPPCTargetInfo();
+TargetInfo *getX32TargetInfo();
+TargetInfo *getX86TargetInfo();
+TargetInfo *getX86_64TargetInfo();
+template <class ELFT> TargetInfo *getMipsTargetInfo();
std::string getErrorLocation(const uint8_t *Loc);
@@ -119,7 +123,7 @@ uint64_t getPPC64TocBase();
uint64_t getAArch64Page(uint64_t Expr);
extern TargetInfo *Target;
-TargetInfo *createTarget();
+TargetInfo *getTarget();
template <unsigned N>
static void checkInt(uint8_t *Loc, int64_t V, uint32_t Type) {
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 4ff06388ec78..4c12b18836bf 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -87,6 +87,8 @@ private:
uint64_t FileSize;
uint64_t SectionHeaderOff;
+
+ bool HasGotBaseSym = false;
};
} // anonymous namespace
@@ -815,19 +817,13 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
}
- // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
- // is magical and is used to produce a R_386_GOTPC relocation.
- // The R_386_GOTPC relocation value doesn't actually depend on the
- // symbol value, so it could use an index of STN_UNDEF which, according
- // to the spec, means the symbol value is 0.
- // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in
- // the object file.
- // The situation is even stranger on x86_64 where the assembly doesn't
- // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as
- // an undefined symbol in the .o files.
- // Given that the symbol is effectively unused, we just create a dummy
- // hidden one to avoid the undefined symbol error.
- Symtab<ELFT>::X->addIgnored("_GLOBAL_OFFSET_TABLE_");
+ // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+ // be at some offset from the base of the .got section, usually 0 or the end
+ // of the .got
+ InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
+ : cast<InputSection>(InX::Got);
+ ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
+ "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
// __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
// static linking the linker is required to optimize away any references to
@@ -1147,6 +1143,8 @@ static void removeUnusedSyntheticSections(std::vector<OutputSection *> &V) {
OutputSection *OS = SS->getParent();
if (!SS->empty() || !OS)
continue;
+ if ((SS == InX::Got || SS == InX::MipsGot) && ElfSym::GlobalOffsetTable)
+ continue;
OS->Sections.erase(std::find(OS->Sections.begin(), OS->Sections.end(), SS));
SS->Live = false;
// If there are no other sections in the output section, remove it from the
@@ -1231,6 +1229,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
OutputSectionCommands.push_back(Cmd);
+ // Prefer command line supplied address over other constraints.
+ for (OutputSectionCommand *Cmd : OutputSectionCommands) {
+ auto I = Config->SectionStartMap.find(Cmd->Name);
+ if (I != Config->SectionStartMap.end())
+ Cmd->AddrExpr = [=] { return I->second; };
+ }
+
// This is a bit of a hack. A value of 0 means undef, so we set it
// to 1 t make __ehdr_start defined. The section number is not
// particularly relevant.
diff --git a/README.md b/README.md
index dc05cdea0a12..38a6b48b1841 100644
--- a/README.md
+++ b/README.md
@@ -8,3 +8,4 @@ infrastructure project.
lld is open source software. You may freely distribute it under the terms of
the license agreement found in LICENSE.txt.
+
diff --git a/docs/windows_support.rst b/docs/windows_support.rst
index 72fcbccec149..56df45b32633 100644
--- a/docs/windows_support.rst
+++ b/docs/windows_support.rst
@@ -49,7 +49,7 @@ Creating DLL
Windows resource files support
:good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF
- file using ``cvtres.exe`` command and link it.
+ file using LLVM's Object library.
Safe Structured Exception Handler (SEH)
:good:`Done` for both x86 and x64.
diff --git a/lib/Driver/DarwinLdDriver.cpp b/lib/Driver/DarwinLdDriver.cpp
index c859c9802349..f564d8cb8d7e 100644
--- a/lib/Driver/DarwinLdDriver.cpp
+++ b/lib/Driver/DarwinLdDriver.cpp
@@ -61,9 +61,9 @@ namespace {
// Create enum with OPT_xxx values for each option in DarwinLdOptions.td
enum {
OPT_INVALID = 0,
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELP, META) \
- OPT_##ID,
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELP, META, VALUES) \
+ OPT_##ID,
#include "DarwinLdOptions.inc"
#undef OPTION
};
@@ -75,10 +75,12 @@ enum {
// Create table mapping all options defined in DarwinLdOptions.td
static const llvm::opt::OptTable::Info infoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ {PREFIX, NAME, HELPTEXT, \
+ METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
+ PARAM, FLAGS, OPT_##GROUP, \
+ OPT_##ALIAS, ALIASARGS, VALUES},
#include "DarwinLdOptions.inc"
#undef OPTION
};
diff --git a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
index 18fb71f16bcf..226a25d3c1ed 100644
--- a/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
+++ b/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
@@ -906,6 +906,7 @@ readCompUnit(const NormalizedFile &normalizedFile,
abbrevData.getU8(&abbrevOffset);
uint32_t name;
llvm::dwarf::Form form;
+ llvm::DWARFFormParams formParams = {version, addrSize, Format};
TranslationUnitSource tu;
while ((name = abbrevData.getULEB128(&abbrevOffset)) |
(form = static_cast<llvm::dwarf::Form>(
@@ -929,8 +930,7 @@ readCompUnit(const NormalizedFile &normalizedFile,
break;
}
default:
- llvm::DWARFFormValue::skipValue(form, infoData, &offset, version,
- addrSize, Format);
+ llvm::DWARFFormValue::skipValue(form, infoData, &offset, formParams);
}
}
return tu;
diff --git a/test/COFF/Inputs/associative-comdat-2.s b/test/COFF/Inputs/associative-comdat-2.s
new file mode 100644
index 000000000000..cd4ef46539f1
--- /dev/null
+++ b/test/COFF/Inputs/associative-comdat-2.s
@@ -0,0 +1,13 @@
+# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
+# associative with it. foo_assoc should be discarded iff foo is discarded,
+# either by linker GC or normal comdat merging.
+
+ .section .rdata,"dr",associative,foo
+ .p2align 3
+ .quad foo
+
+ .section .data,"dw",discard,foo
+ .globl foo # @foo
+ .p2align 2
+foo:
+ .long 42
diff --git a/test/COFF/Inputs/pdb1.yaml b/test/COFF/Inputs/pdb1.yaml
index 566f2da003c5..90905ae191ec 100644
--- a/test/COFF/Inputs/pdb1.yaml
+++ b/test/COFF/Inputs/pdb1.yaml
@@ -34,14 +34,10 @@ sections:
Records:
- Kind: S_GPROC32_ID
ProcSym:
- PtrParent: 0
- PtrEnd: 0
- PtrNext: 0
CodeSize: 14
DbgStart: 4
DbgEnd: 9
FunctionType: 4101
- Segment: 0
Flags: [ ]
DisplayName: main
- Kind: S_FRAMEPROC
diff --git a/test/COFF/Inputs/pdb_comdat_bar.yaml b/test/COFF/Inputs/pdb_comdat_bar.yaml
new file mode 100644
index 000000000000..71a9535c50b7
--- /dev/null
+++ b/test/COFF/Inputs/pdb_comdat_bar.yaml
@@ -0,0 +1,440 @@
+--- !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\pdb_comdat_bar.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:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 14
+ DbgStart: 4
+ DbgEnd: 9
+ FunctionType: 4102
+ Segment: 0
+ Flags: [ ]
+ DisplayName: bar
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 40
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 14
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
+ Lines:
+ - Offset: 0
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 4
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 9
+ LineStart: 5
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !Symbols
+ Records:
+ - Kind: S_GDATA32
+ DataSym:
+ Type: 116
+ DisplayName: global
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
+ Kind: MD5
+ Checksum: 365279DB4FCBEDD721BBFC3B14A953C2
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Kind: MD5
+ Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\pdb_comdat_bar.c'
+ - 'c:\src\llvm-project\build\foo.h'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4110
+ Relocations:
+ - VirtualAddress: 168
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 172
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 224
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 228
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 288
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 292
+ SymbolName: global
+ 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_ARGLIST
+ ArgList:
+ ArgIndices: [ 0 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 3
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_POINTER
+ Pointer:
+ ReferentType: 4097
+ Attrs: 65548
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: foo
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 3
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4100
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4101
+ Name: bar
+ - 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 -Z7 -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: [ 4105 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4106
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: pdb_comdat_bar.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\vc140.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
+ - Name: .bss
+ Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 4
+ SectionData: ''
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC28E8000000004883C428C3
+ Relocations:
+ - VirtualAddress: 5
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 8B0500000000FFC0890500000000C3
+ Relocations:
+ - VirtualAddress: 2
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_REL32
+ - VirtualAddress: 10
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 15
+ DbgStart: 0
+ DbgEnd: 14
+ FunctionType: 4099
+ Segment: 0
+ Flags: [ ]
+ DisplayName: foo
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 0
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 15
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 0
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 14
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ Relocations:
+ - VirtualAddress: 44
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 48
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 100
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 104
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '0104010004420000'
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '000000000E00000000000000'
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 4
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 8
+ SymbolName: '$unwind$bar'
+ 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: 460
+ NumberOfRelocations: 6
+ 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: 628
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: .bss
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 4
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: global
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 14
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1682752513
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 15
+ NumberOfRelocations: 2
+ NumberOfLinenumbers: 0
+ CheckSum: 1746394828
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 148
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 6
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: foo
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: bar
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: '$LN3'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_LABEL
+ - Name: .xdata
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 264583633
+ Number: 0
+ - Name: '$unwind$bar'
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 9
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 12
+ NumberOfRelocations: 3
+ NumberOfLinenumbers: 0
+ CheckSum: 361370162
+ Number: 0
+ - Name: '$pdata$bar'
+ Value: 0
+ SectionNumber: 9
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+...
diff --git a/test/COFF/Inputs/pdb_comdat_main.yaml b/test/COFF/Inputs/pdb_comdat_main.yaml
new file mode 100644
index 000000000000..d9019d633415
--- /dev/null
+++ b/test/COFF/Inputs/pdb_comdat_main.yaml
@@ -0,0 +1,446 @@
+--- !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\pdb_comdat_main.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:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 24
+ DbgStart: 4
+ DbgEnd: 19
+ FunctionType: 4102
+ Segment: 0
+ Flags: [ ]
+ DisplayName: main
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 40
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 24
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 4
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 9
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 14
+ LineStart: 5
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 19
+ LineStart: 6
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !Symbols
+ Records:
+ - Kind: S_GDATA32
+ DataSym:
+ Type: 116
+ DisplayName: global
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
+ Kind: MD5
+ Checksum: F969E51BBE373436D81492EB61387F36
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Kind: MD5
+ Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\pdb_comdat_main.c'
+ - 'c:\src\llvm-project\build\foo.h'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4111
+ Relocations:
+ - VirtualAddress: 168
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 172
+ 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
+ - VirtualAddress: 304
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 308
+ SymbolName: global
+ 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_ARGLIST
+ ArgList:
+ ArgIndices: [ 0 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 3
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_POINTER
+ Pointer:
+ ReferentType: 4097
+ Attrs: 65548
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: foo
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4100
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4101
+ Name: main
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: bar
+ - 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 -Z7 -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: [ 4106 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4107
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: pdb_comdat_main.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\vc140.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC28E800000000E800000000B82A0000004883C428C3
+ Relocations:
+ - VirtualAddress: 5
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_REL32
+ - VirtualAddress: 10
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 8B0500000000FFC0890500000000C3
+ Relocations:
+ - VirtualAddress: 2
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_REL32
+ - VirtualAddress: 10
+ SymbolName: global
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 15
+ DbgStart: 0
+ DbgEnd: 14
+ FunctionType: 4099
+ Segment: 0
+ Flags: [ ]
+ DisplayName: foo
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 0
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 15
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 0
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 14
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ Relocations:
+ - VirtualAddress: 44
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 48
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 100
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 104
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '0104010004420000'
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '000000001800000000000000'
+ 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: 480
+ NumberOfRelocations: 6
+ 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: 648
+ 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: 24
+ NumberOfRelocations: 2
+ NumberOfLinenumbers: 0
+ CheckSum: 492663294
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 15
+ NumberOfRelocations: 2
+ NumberOfLinenumbers: 0
+ CheckSum: 1746394828
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 148
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 5
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: foo
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: bar
+ 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: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 264583633
+ Number: 0
+ - Name: '$unwind$main'
+ Value: 0
+ SectionNumber: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 12
+ NumberOfRelocations: 3
+ NumberOfLinenumbers: 0
+ CheckSum: 2942184094
+ Number: 0
+ - Name: '$pdata$main'
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: global
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/Inputs/pdb_lines_1.yaml b/test/COFF/Inputs/pdb_lines_1.yaml
new file mode 100644
index 000000000000..3fbb2a94d45f
--- /dev/null
+++ b/test/COFF/Inputs/pdb_lines_1.yaml
@@ -0,0 +1,480 @@
+--- !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\pdb_lines_1.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:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 19
+ DbgStart: 4
+ DbgEnd: 14
+ FunctionType: 4102
+ Segment: 0
+ Flags: [ ]
+ DisplayName: main
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 40
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 19
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 4
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 9
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 14
+ LineStart: 5
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
+ Kind: MD5
+ Checksum: 4EB19DCD86C3BA2238A255C718572E7B
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Kind: MD5
+ Checksum: 061EB73ABB642532857A4F1D9CBAC323
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\pdb_lines_1.c'
+ - 'c:\src\llvm-project\build\foo.h'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4111
+ Relocations:
+ - VirtualAddress: 164
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 168
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 220
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 224
+ 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_ARGLIST
+ ArgList:
+ ArgIndices: [ ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 3
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_POINTER
+ Pointer:
+ ReferentType: 4097
+ Attrs: 65548
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: foo
+ - Kind: LF_ARGLIST
+ ArgList:
+ ArgIndices: [ 0 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4100
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4101
+ Name: main
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: bar
+ - 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 -Z7 -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: [ 4106 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4107
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: pdb_lines_1.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\vc140.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC28E800000000B82A0000004883C428C3
+ Relocations:
+ - VirtualAddress: 5
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 4883EC28E8000000004883C428C3
+ Relocations:
+ - VirtualAddress: 5
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_REL32
+ - Name: '.debug$S'
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+ Alignment: 1
+ Subsections:
+ - !Symbols
+ Records:
+ - Kind: S_GPROC32_ID
+ ProcSym:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 14
+ DbgStart: 4
+ DbgEnd: 9
+ FunctionType: 4099
+ Segment: 0
+ Flags: [ ]
+ DisplayName: foo
+ - Kind: S_FRAMEPROC
+ FrameProcSym:
+ TotalFrameBytes: 40
+ PaddingFrameBytes: 0
+ OffsetToPadding: 0
+ BytesOfCalleeSavedRegisters: 0
+ OffsetOfExceptionHandler: 0
+ SectionIdOfExceptionHandler: 0
+ Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
+ - Kind: S_PROC_ID_END
+ ScopeEndSym:
+ - !Lines
+ CodeSize: 14
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\foo.h'
+ Lines:
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 4
+ LineStart: 3
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 9
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ Relocations:
+ - VirtualAddress: 44
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 48
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 100
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 104
+ SymbolName: foo
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '0104010004420000'
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '000000000E00000000000000'
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 4
+ SymbolName: '$LN3'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 8
+ SymbolName: '$unwind$foo'
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '0104010004420000'
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: '000000001300000000000000'
+ 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: 432
+ 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: 644
+ 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: 19
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 791570821
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 14
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1682752513
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ - Name: '.debug$S'
+ Value: 0
+ SectionNumber: 6
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 148
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 5
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: bar
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: foo
+ Value: 0
+ SectionNumber: 5
+ 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: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_LABEL
+ - 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: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 264583633
+ Number: 5
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '$unwind$foo'
+ Value: 0
+ SectionNumber: 7
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 12
+ NumberOfRelocations: 3
+ NumberOfLinenumbers: 0
+ CheckSum: 361370162
+ Number: 5
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
+ - Name: '$pdata$foo'
+ Value: 0
+ SectionNumber: 8
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .xdata
+ Value: 0
+ SectionNumber: 9
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 264583633
+ Number: 0
+ - Name: '$unwind$main'
+ Value: 0
+ SectionNumber: 9
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 10
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 12
+ NumberOfRelocations: 3
+ NumberOfLinenumbers: 0
+ CheckSum: 4063508168
+ Number: 0
+ - Name: '$pdata$main'
+ Value: 0
+ SectionNumber: 10
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+...
diff --git a/test/COFF/Inputs/pdb_lines_2.yaml b/test/COFF/Inputs/pdb_lines_2.yaml
new file mode 100644
index 000000000000..8ad8d062db58
--- /dev/null
+++ b/test/COFF/Inputs/pdb_lines_2.yaml
@@ -0,0 +1,209 @@
+--- !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\pdb_lines_2.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:
+ PtrParent: 0
+ PtrEnd: 0
+ PtrNext: 0
+ CodeSize: 1
+ DbgStart: 0
+ DbgEnd: 0
+ FunctionType: 4098
+ Segment: 0
+ Flags: [ ]
+ DisplayName: bar
+ - 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: 1
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
+ Lines:
+ - Offset: 0
+ LineStart: 1
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 0
+ LineStart: 2
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
+ Kind: MD5
+ Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\pdb_lines_2.c'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4106
+ Relocations:
+ - VirtualAddress: 164
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 168
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 220
+ SymbolName: bar
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 224
+ SymbolName: bar
+ 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_ARGLIST
+ ArgList:
+ ArgIndices: [ ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 3
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: bar
+ - 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 -Z7 -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: [ 4101 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4102
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: pdb_lines_2.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\vc140.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ]
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: C3
+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: 568
+ 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: 1
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 40735498
+ Number: 0
+ - Name: bar
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/associative-comdat.s b/test/COFF/associative-comdat.s
new file mode 100644
index 000000000000..dd5419533c16
--- /dev/null
+++ b/test/COFF/associative-comdat.s
@@ -0,0 +1,46 @@
+# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t1.obj
+# RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj
+
+# RUN: lld-link -entry:main %t1.obj %t2.obj -out:%t.gc.exe
+# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s
+
+# RUN: lld-link -entry:main %t1.obj %t2.obj -opt:noref -out:%t.nogc.exe
+# RUN: llvm-readobj -sections %t.nogc.exe | FileCheck %s
+
+# CHECK: Sections [
+# CHECK: Section {
+# CHECK: Number: 1
+# CHECK-LABEL: Name: .data (2E 64 61 74 61 00 00 00)
+# CHECK-NEXT: VirtualSize: 0x4
+# CHECK: Section {
+# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)
+# This is the critical check to show that only *one* definition of
+# foo_assoc was retained. This *must* be 8, not 16.
+# CHECK-NEXT: VirtualSize: 0x8
+
+ .text
+ .def main;
+ .scl 2;
+ .type 32;
+ .endef
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+main: # @main
+# BB#0:
+ movl foo(%rip), %eax
+ retq
+ # -- End function
+
+# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
+# associative with it. foo_assoc should be discarded iff foo is discarded,
+# either by linker GC or normal comdat merging.
+
+ .section .rdata,"dr",associative,foo
+ .p2align 3
+ .quad foo
+
+ .section .data,"dw",discard,foo
+ .globl foo # @foo
+ .p2align 2
+foo:
+ .long 42
diff --git a/test/COFF/def-name.test b/test/COFF/def-name.test
index c48424a1bff0..b971007eda37 100644
--- a/test/COFF/def-name.test
+++ b/test/COFF/def-name.test
@@ -1,5 +1,3 @@
-# REQUIRES: winres
-
# RUN: rm -rf %t
# RUN: mkdir -p %t
# RUN: cd %t
diff --git a/test/COFF/dll.test b/test/COFF/dll.test
index db4b4056552c..abd39f4eeb24 100644
--- a/test/COFF/dll.test
+++ b/test/COFF/dll.test
@@ -1,5 +1,3 @@
-# REQUIRES: winres
-
# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
# RUN: /export:mangled
diff --git a/test/COFF/dllimport-gc.test b/test/COFF/dllimport-gc.test
index 54ae773e793f..d8523fbc7dae 100644
--- a/test/COFF/dllimport-gc.test
+++ b/test/COFF/dllimport-gc.test
@@ -1,5 +1,3 @@
-# REQUIRES: winres
-
# RUN: yaml2obj < %p/Inputs/export.yaml > %t-lib.obj
# RUN: lld-link /out:%t.dll /dll %t-lib.obj /implib:%t.lib /export:exportfn1
diff --git a/test/COFF/guardcf.test b/test/COFF/guardcf.test
new file mode 100644
index 000000000000..4f99d705301c
--- /dev/null
+++ b/test/COFF/guardcf.test
@@ -0,0 +1,74 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld-link /entry:main /out:%t.exe %t.obj
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 000000000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_fids_count
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_fids_table
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_flags
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_iat_count
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_iat_table
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_longjmp_count
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_longjmp_table
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/hello32.test b/test/COFF/hello32.test
index 66b52378aaa3..9464a3c114eb 100644
--- a/test/COFF/hello32.test
+++ b/test/COFF/hello32.test
@@ -21,7 +21,7 @@ HEADER-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
HEADER-NEXT: ]
HEADER-NEXT: }
HEADER-NEXT: ImageOptionalHeader {
-HEADER-NEXT: MajorLinkerVersion: 0
+HEADER-NEXT: MajorLinkerVersion: 14
HEADER-NEXT: MinorLinkerVersion: 0
HEADER-NEXT: SizeOfCode: 512
HEADER-NEXT: SizeOfInitializedData: 1536
diff --git a/test/COFF/icf-associative.test b/test/COFF/icf-associative.test
index 1c63b05d8f22..bfaeabb4d41a 100644
--- a/test/COFF/icf-associative.test
+++ b/test/COFF/icf-associative.test
@@ -16,7 +16,7 @@ sections:
Alignment: 16
SectionData: 4883EC28E8000000004883C428C3
- - Name: '.debug$S'
+ - Name: '.debug_blah'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
SectionData: 0000000000000000000000000000
@@ -26,7 +26,7 @@ sections:
Alignment: 16
SectionData: 4883EC28E8000000004883C428C3
- - Name: '.debug$S'
+ - Name: '.debug_blah'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
SectionData: FFFFFFFFFFFFFFFFFFFFFFFFFFFF
@@ -46,7 +46,7 @@ symbols:
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
- - Name: '.debug$S'
+ - Name: '.debug_blah'
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
@@ -74,7 +74,7 @@ symbols:
Number: 0
Selection: IMAGE_COMDAT_SELECT_ANY
- - Name: '.debug$S'
+ - Name: '.debug_blah'
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
diff --git a/test/COFF/manifestinput.test b/test/COFF/manifestinput.test
index 376d404d604c..4eb1730bb0e4 100644
--- a/test/COFF/manifestinput.test
+++ b/test/COFF/manifestinput.test
@@ -1,4 +1,4 @@
-# REQUIRES: winres
+# REQUIRES: win_mt
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
# RUN: lld-link /out:%t.exe /entry:main \
@@ -8,3 +8,28 @@
CHECK: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
CHECK: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency><trustInfo><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo></assembly>
+
+# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
+# RUN: lld-link /out:%t.exe /entry:main \
+# RUN: /manifest:embed \
+# RUN: /manifestuac:"level='requireAdministrator'" \
+# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
+# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
+# RUN: -check-prefix TEST_EMBED
+
+TEST_EMBED: ResourceTableRVA: 0x1000
+TEST_EMBED-NEXT: ResourceTableSize: 0x298
+TEST_EMBED-DAG: Resources [
+TEST_EMBED-NEXT: Total Number of Resources: 1
+TEST_EMBED-DAG: Number of String Entries: 0
+TEST_EMBED-NEXT: Number of ID Entries: 1
+TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
+TEST_EMBED-NEXT: Table Offset: 0x18
+TEST_EMBED-NEXT: Number of String Entries: 0
+TEST_EMBED-NEXT: Number of ID Entries: 1
+TEST_EMBED-NEXT: Name: (ID 1) [
+TEST_EMBED-NEXT: Table Offset: 0x30
+TEST_EMBED-NEXT: Number of String Entries: 0
+TEST_EMBED-NEXT: Number of ID Entries: 1
+TEST_EMBED-NEXT: Language: (ID 1033) [
+TEST_EMBED-NEXT: Entry Offset: 0x48
diff --git a/test/COFF/noentry.test b/test/COFF/noentry.test
index 5e241e46e897..cc02c85e7010 100644
--- a/test/COFF/noentry.test
+++ b/test/COFF/noentry.test
@@ -1,5 +1,3 @@
-# REQUIRES: winres
-
# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
# RUN: lld-link /out:%t.dll /dll %t.obj
# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s
diff --git a/test/COFF/out.test b/test/COFF/out.test
index 67b2ef01b711..a7b56145996f 100644
--- a/test/COFF/out.test
+++ b/test/COFF/out.test
@@ -1,4 +1,3 @@
-# REQUIRES: winres
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
# RUN: mkdir -p %T/out/tmp
diff --git a/test/COFF/pdb-comdat.test b/test/COFF/pdb-comdat.test
new file mode 100644
index 000000000000..769b630d0e8d
--- /dev/null
+++ b/test/COFF/pdb-comdat.test
@@ -0,0 +1,100 @@
+Consider this example program with an inline function "foo":
+
+==> foo.h <==
+extern int global;
+__inline void foo() {
+ ++global;
+}
+void bar();
+==> pdb_comdat_main.c <==
+#include "foo.h"
+int main(void) {
+ foo();
+ bar();
+ return 42;
+}
+==> pdb_comdat_bar.c <==
+#include "foo.h"
+void bar(void) {
+ foo();
+}
+
+Both object files will contain debug info for foo, but only the debug info from
+pdb_comdat_main.obj should be included in the PDB.
+
+RUN: rm -rf %t && mkdir -p %t && cd %t
+RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj
+RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj
+RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
+RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s
+
+CHECK: Lines
+CHECK: ============================================================
+CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
+CHECK: c:\src\llvm-project\build\pdb_comdat_main.c (MD5: F969E51BBE373436D81492EB61387F36)
+CHECK: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
+CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
+CHECK: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
+CHECK-NOT: c:\src\llvm-project\build\foo.h
+CHECK-LABEL: Mod 0002 | `* Linker *`:
+
+CHECK: Symbols
+CHECK: ============================================================
+CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
+CHECK: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_main.obj`
+CHECK: - 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: - S_GPROC32_ID [size = 44] `main`
+ FIXME: We need to fill in "end".
+CHECK: parent = 0, addr = 0002:0000, code size = 24, end = 0
+CHECK: debug start = 4, debug end = 19, flags = none
+CHECK: - S_FRAMEPROC [size = 32]
+CHECK: size = 40, 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: - S_END [size = 4]
+CHECK: - S_GDATA32 [size = 24] `global`
+CHECK: type = 0x0074 (int), addr = 0000:0000
+CHECK: - S_BUILDINFO [size = 8] BuildId = `4106`
+CHECK: - S_GPROC32_ID [size = 44] `foo`
+CHECK: parent = 0, addr = 0002:0032, code size = 15, end = 0
+CHECK: debug start = 0, debug end = 14, flags = none
+CHECK: - 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 = marked inline | has async eh | opt speed
+CHECK: - S_END [size = 4]
+CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
+CHECK: - S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj`
+CHECK: - 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: - S_GPROC32_ID [size = 44] `bar`
+CHECK: parent = 0, addr = 0002:0048, code size = 14, end = 0
+CHECK: debug start = 4, debug end = 9, flags = none
+CHECK: - S_FRAMEPROC [size = 32]
+CHECK: size = 40, 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: - S_END [size = 4]
+CHECK: - S_GDATA32 [size = 24] `global`
+CHECK: type = 0x0074 (int), addr = 0000:0000
+CHECK: - S_BUILDINFO [size = 8] BuildId = `4109`
+CHECK-NOT: - S_GPROC32_ID {{.*}} `foo`
+CHECK-LABEL: Mod 0002 | `* Linker *`:
+
+Reorder the object files and verify that the other table is selected.
+
+RUN: lld-link pdb_comdat_bar.obj pdb_comdat_main.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
+RUN: llvm-pdbutil dump -l t.pdb | FileCheck %s --check-prefix=REORDER
+
+REORDER-LABEL: Mod 0000 | `{{.*}}pdb_comdat_bar.obj`:
+REORDER: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
+REORDER: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
+REORDER-LABEL: Mod 0001 | `{{.*}}pdb_comdat_main.obj`:
+REORDER: c:\src\llvm-project\build\pdb_comdat_main.c
+REORDER-NOT: c:\src\llvm-project\build\foo.h
+REORDER-LABEL: Mod 0002 | `* Linker *`:
diff --git a/test/COFF/pdb-lib.s b/test/COFF/pdb-lib.s
index 073c6f08abf8..47375cc26ff2 100644
--- a/test/COFF/pdb-lib.s
+++ b/test/COFF/pdb-lib.s
@@ -3,7 +3,7 @@
# RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj
# RUN: llvm-lib bar.obj -out:bar.lib
# RUN: lld-link -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main
-# RUN: llvm-pdbutil raw -modules %t/foo.pdb | FileCheck %s
+# RUN: llvm-pdbutil dump -modules %t/foo.pdb | FileCheck %s
# Make sure that the PDB has module descriptors. foo.obj and bar.lib should be
# absolute paths, and bar.obj should be the relative path passed to llvm-lib.
diff --git a/test/COFF/pdb-safeseh.yaml b/test/COFF/pdb-safeseh.yaml
new file mode 100644
index 000000000000..9faa5042924d
--- /dev/null
+++ b/test/COFF/pdb-safeseh.yaml
@@ -0,0 +1,85 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
+# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
+
+# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
+# it in this debug info. This is similar to the relocations in the loadcfg.obj
+# file in the MSVC CRT. We need to make sure that our relocation logic matches
+# MSVC's for these absolute, linker-provided symbols.
+
+# CHECK: Mod 0000 |
+# CHECK-NEXT: - S_GDATA32 [size = 40] `___safe_se_handler_table`
+# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
+# CHECK-NEXT: Mod 0001 | `* Linker *`:
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_I386
+ 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_GDATA32
+ DataSym:
+ Type: 34
+ DisplayName: ___safe_se_handler_table
+ - !StringTable
+ Strings:
+ Relocations:
+ - VirtualAddress: 20
+ SymbolName: ___safe_se_handler_table
+ Type: IMAGE_REL_I386_SECREL
+ - VirtualAddress: 24
+ SymbolName: ___safe_se_handler_table
+ Type: IMAGE_REL_I386_SECTION
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 488D0500000000C3
+ Relocations:
+ - VirtualAddress: 3
+ SymbolName: ___safe_se_handler_table
+ Type: IMAGE_REL_I386_REL32
+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: 372
+ NumberOfRelocations: 6
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1092178131
+ Number: 0
+ - Name: _main
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: ___safe_se_handler_table
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
+
diff --git a/test/COFF/pdb-secrel-absolute.yaml b/test/COFF/pdb-secrel-absolute.yaml
new file mode 100644
index 000000000000..d74f07e32b98
--- /dev/null
+++ b/test/COFF/pdb-secrel-absolute.yaml
@@ -0,0 +1,84 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
+# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
+
+# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
+# it in this debug info. This is similar to the relocations in the loadcfg.obj
+# file in the MSVC CRT. We need to make sure that our relocation logic matches
+# MSVC's for these absolute, linker-provided symbols.
+
+# CHECK: Mod 0000 |
+# CHECK-NEXT: - S_GDATA32 [size = 36] `__guard_fids_table`
+# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
+# CHECK-NEXT: Mod 0001 | `* Linker *`:
+
+--- !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_GDATA32
+ DataSym:
+ Type: 34
+ DisplayName: __guard_fids_table
+ - !StringTable
+ Strings:
+ Relocations:
+ - VirtualAddress: 20
+ SymbolName: __guard_fids_table
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 24
+ SymbolName: __guard_fids_table
+ Type: IMAGE_REL_AMD64_SECTION
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 488D0500000000C3
+ Relocations:
+ - VirtualAddress: 3
+ SymbolName: __guard_fids_table
+ Type: IMAGE_REL_AMD64_REL32
+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: 372
+ NumberOfRelocations: 6
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 1092178131
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __guard_fids_table
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb-source-lines.test b/test/COFF/pdb-source-lines.test
new file mode 100644
index 000000000000..a630ecb22d62
--- /dev/null
+++ b/test/COFF/pdb-source-lines.test
@@ -0,0 +1,124 @@
+Test the linker line tables on roughly the following example:
+
+==> foo.h <==
+void bar(void);
+inline void foo(void) {
+ bar();
+}
+==> pdb_lines_1.c <==
+#include "foo.h"
+int main(void) {
+ foo();
+ return 42;
+}
+==> pdb_lines_2.c <==
+void bar(void) {
+}
+
+$ cl -c -Z7 pdb_lines*.c
+
+RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj
+RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj
+RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj
+RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
+
+CHECK-LABEL: DbiStream:
+CHECK-NEXT: VerHeader: V110
+CHECK-NEXT: Age: 1
+CHECK-NEXT: BuildNumber: 0
+CHECK-NEXT: PdbDllVersion: 0
+CHECK-NEXT: PdbDllRbld: 0
+CHECK-NEXT: Flags: 0
+CHECK-NEXT: MachineType: x86
+CHECK-NEXT: Modules:
+
+CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj
+CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1.obj
+CHECK-NEXT: SourceFiles:
+CHECK-NEXT: - '{{.*}}pdb_lines_1.c'
+CHECK-NEXT: - '{{.*}}foo.h'
+CHECK-NEXT: Subsections:
+CHECK-NEXT: - !Lines
+CHECK-NEXT: CodeSize: 19
+CHECK-NEXT: Flags: [ ]
+CHECK-NEXT: RelocOffset: 0
+CHECK-NEXT: RelocSegment: 2
+CHECK-NEXT: Blocks:
+CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
+CHECK-NEXT: Lines:
+CHECK-NEXT: - Offset: 0
+CHECK-NEXT: LineStart: 2
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 4
+CHECK-NEXT: LineStart: 3
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 9
+CHECK-NEXT: LineStart: 4
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 14
+CHECK-NEXT: LineStart: 5
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: Columns:
+CHECK-NEXT: - !FileChecksums
+CHECK-NEXT: Checksums:
+CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
+CHECK-NEXT: Kind: MD5
+CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B
+CHECK-NEXT: - FileName: '{{.*}}foo.h'
+CHECK-NEXT: Kind: MD5
+CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323
+CHECK-NEXT: - !Lines
+CHECK-NEXT: CodeSize: 14
+CHECK-NEXT: Flags: [ ]
+CHECK-NEXT: RelocOffset: 32
+CHECK-NEXT: RelocSegment: 2
+CHECK-NEXT: Blocks:
+CHECK-NEXT: - FileName: '{{.*}}foo.h'
+CHECK-NEXT: Lines:
+CHECK-NEXT: - Offset: 0
+CHECK-NEXT: LineStart: 2
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 4
+CHECK-NEXT: LineStart: 3
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 9
+CHECK-NEXT: LineStart: 4
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: Columns:
+
+CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj
+CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj
+CHECK-NEXT: SourceFiles:
+CHECK-NEXT: - '{{.*}}pdb_lines_2.c'
+CHECK-NEXT: Subsections:
+CHECK-NEXT: - !Lines
+CHECK-NEXT: CodeSize: 1
+CHECK-NEXT: Flags: [ ]
+CHECK-NEXT: RelocOffset: 48
+CHECK-NEXT: RelocSegment: 2
+CHECK-NEXT: Blocks:
+CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
+CHECK-NEXT: Lines:
+CHECK-NEXT: - Offset: 0
+CHECK-NEXT: LineStart: 1
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: - Offset: 0
+CHECK-NEXT: LineStart: 2
+CHECK-NEXT: IsStatement: true
+CHECK-NEXT: EndDelta: 0
+CHECK-NEXT: Columns:
+CHECK-NEXT: - !FileChecksums
+CHECK-NEXT: Checksums:
+CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
+CHECK-NEXT: Kind: MD5
+CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
+CHECK-NEXT: - Module: '* Linker *'
+CHECK-NEXT: ObjFile: ''
diff --git a/test/COFF/pdb-symbol-types.yaml b/test/COFF/pdb-symbol-types.yaml
new file mode 100644
index 000000000000..4951aa8be379
--- /dev/null
+++ b/test/COFF/pdb-symbol-types.yaml
@@ -0,0 +1,344 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb
+# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
+
+# To regenerate the object file:
+# $ cat symbol-types.c
+# struct Foo { int x; };
+# typedef struct Foo UDT_Foo;
+# UDT_Foo global_foo = {42};
+# int main() { return global_foo.x; }
+# $ cl -c -Z7 symbol-types.c
+
+# Note that the type of 'global' goes from 0x1005 in the object file to 0x1004
+# in the PDB because the LF_FUNC_ID is moved to the id stream.
+
+# CHECK: Symbols
+# CHECK: ============================================================
+# CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`:
+# CHECK: - S_OBJNAME [size = 52] sig=0, `C:\src\llvm-project\build\symbol-types.obj`
+# CHECK: - 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: - S_GPROC32_ID [size = 44] `main`
+# CHECK: parent = 0, addr = 0002:0000, code size = 7, end = 0
+# CHECK: debug start = 0, debug end = 6, flags = none
+# CHECK: - 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: - S_END [size = 4]
+# CHECK: - S_GDATA32 [size = 28] `global_foo`
+# CHECK: type = 0x1004 (Foo), addr = 0001:0000
+# CHECK: - S_UDT [size = 16] `UDT_Foo`
+# CHECK: original type = 0x1004
+# CHECK: - S_UDT [size = 12] `Foo`
+# CHECK: original type = 0x1004
+# CHECK: - S_BUILDINFO [size = 8] BuildId = `4106`
+# CHECK-LABEL: Mod 0001 | `* Linker *`:
+
+--- !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\symbol-types.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: 7
+ DbgStart: 0
+ DbgEnd: 6
+ FunctionType: 4098
+ 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: 7
+ Flags: [ ]
+ RelocOffset: 0
+ RelocSegment: 0
+ Blocks:
+ - FileName: 'c:\src\llvm-project\build\symbol-types.c'
+ Lines:
+ - Offset: 0
+ LineStart: 4
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 0
+ LineStart: 5
+ IsStatement: true
+ EndDelta: 0
+ - Offset: 6
+ LineStart: 6
+ IsStatement: true
+ EndDelta: 0
+ Columns:
+ - !Symbols
+ Records:
+ - Kind: S_GDATA32
+ DataSym:
+ Type: 4101
+ DisplayName: global_foo
+ - Kind: S_UDT
+ UDTSym:
+ Type: 4101
+ UDTName: UDT_Foo
+ - Kind: S_UDT
+ UDTSym:
+ Type: 4101
+ UDTName: Foo
+ - !FileChecksums
+ Checksums:
+ - FileName: 'c:\src\llvm-project\build\symbol-types.c'
+ Kind: MD5
+ Checksum: F833E1A4909FF6FEC5689A664F3BE725
+ - !StringTable
+ Strings:
+ - 'c:\src\llvm-project\build\symbol-types.c'
+ - !Symbols
+ Records:
+ - Kind: S_BUILDINFO
+ BuildInfoSym:
+ BuildId: 4111
+ Relocations:
+ - VirtualAddress: 164
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 168
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 220
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 224
+ SymbolName: main
+ Type: IMAGE_REL_AMD64_SECTION
+ - VirtualAddress: 284
+ SymbolName: global_foo
+ Type: IMAGE_REL_AMD64_SECREL
+ - VirtualAddress: 288
+ SymbolName: global_foo
+ 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_ARGLIST
+ ArgList:
+ ArgIndices: [ 0 ]
+ - Kind: LF_PROCEDURE
+ Procedure:
+ ReturnType: 116
+ CallConv: NearC
+ Options: [ None ]
+ ParameterCount: 0
+ ArgumentList: 4096
+ - Kind: LF_FUNC_ID
+ FuncId:
+ ParentScope: 0
+ FunctionType: 4097
+ Name: main
+ - Kind: LF_STRUCTURE
+ Class:
+ MemberCount: 0
+ Options: [ None, ForwardReference, HasUniqueName ]
+ FieldList: 0
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 0
+ - 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: 4100
+ Name: Foo
+ UniqueName: '.?AUFoo@@'
+ DerivationList: 0
+ VTableShape: 0
+ Size: 4
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'c:\src\llvm-project\build\symbol-types.c'
+ - Kind: LF_UDT_SRC_LINE
+ UdtSourceLine:
+ UDT: 4101
+ SourceFile: 4102
+ LineNumber: 1
+ - 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 -Z7 -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: [ 4106 ]
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 4107
+ String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: symbol-types.c
+ - Kind: LF_STRING_ID
+ StringId:
+ Id: 0
+ String: 'C:\src\llvm-project\build\vc140.pdb'
+ - Kind: LF_BUILDINFO
+ BuildInfo:
+ ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
+ - Name: .data
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 4
+ SectionData: 2A000000
+ - Name: '.text$mn'
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 8B0500000000C3
+ Relocations:
+ - VirtualAddress: 2
+ SymbolName: global_foo
+ Type: IMAGE_REL_AMD64_REL32
+symbols:
+ - Name: '@comp.id'
+ Value: 17063575
+ SectionNumber: -1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - Name: '@feat.00'
+ Value: 2147484048
+ SectionNumber: -1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ - 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: 432
+ NumberOfRelocations: 6
+ 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: 732
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: .data
+ Value: 0
+ SectionNumber: 4
+ 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: 0
+ - Name: global_foo
+ Value: 0
+ SectionNumber: 4
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: '.text$mn'
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 7
+ NumberOfRelocations: 1
+ NumberOfLinenumbers: 0
+ CheckSum: 3635526833
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 5
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/test/COFF/pdb.test b/test/COFF/pdb.test
index c2881669d358..3acb7188df49 100644
--- a/test/COFF/pdb.test
+++ b/test/COFF/pdb.test
@@ -6,7 +6,7 @@
# RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \
# RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s
-# RUN: llvm-pdbutil raw -modules -section-map -section-contribs \
+# RUN: llvm-pdbutil dump -modules -section-map -section-contribs \
# RUN: -types -ids %t.pdb | FileCheck -check-prefix RAW %s
# CHECK: MSF:
@@ -22,7 +22,7 @@
# CHECK-NEXT: NumStreams:
# CHECK-NEXT: FileSize:
# CHECK-NEXT: StreamSizes:
-# CHECK-NEXT: StreamMap:
+# CHECK: StreamMap:
# CHECK: PdbStream:
# CHECK-NEXT: Age: 1
# CHECK-NEXT: Guid:
@@ -119,10 +119,10 @@ RAW: Modules
RAW-NEXT: ============================================================
RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`:
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
-RAW-NEXT: debug stream: 9, # files: 0, has ec info: false
+RAW-NEXT: debug stream: 9, # files: 1, has ec info: false
RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`:
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
-RAW-NEXT: debug stream: 10, # files: 0, has ec info: false
+RAW-NEXT: debug stream: 10, # files: 1, has ec info: false
RAW-NEXT: Mod 0002 | Name: `* Linker *`:
RAW-NEXT: Obj: ``:
RAW-NEXT: debug stream: 11, # files: 0, has ec info: false
diff --git a/test/COFF/resource.test b/test/COFF/resource.test
index 7b6090d89f65..a73a20258201 100644
--- a/test/COFF/resource.test
+++ b/test/COFF/resource.test
@@ -1,5 +1,3 @@
-# REQUIRES: winres
-
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res
diff --git a/test/COFF/safeseh.test b/test/COFF/safeseh-diag-feat.test
index ed928a51350a..ed928a51350a 100644
--- a/test/COFF/safeseh.test
+++ b/test/COFF/safeseh-diag-feat.test
diff --git a/test/COFF/safeseh.s b/test/COFF/safeseh.s
new file mode 100644
index 000000000000..83c15afbf938
--- /dev/null
+++ b/test/COFF/safeseh.s
@@ -0,0 +1,60 @@
+# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main
+# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
+# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main
+# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
+
+# CHECK-NOGC: LoadConfig [
+# CHECK-NOGC: Size: 0x48
+# CHECK-NOGC: SEHandlerTable: 0x401048
+# CHECK-NOGC: SEHandlerCount: 1
+# CHECK-NOGC: ]
+# CHECK-NOGC: SEHTable [
+# CHECK-NOGC-NEXT: 0x402006
+# CHECK-NOGC-NEXT: ]
+
+# CHECK-GC: LoadConfig [
+# CHECK-GC: Size: 0x48
+# CHECK-GC: SEHandlerTable: 0x0
+# CHECK-GC: SEHandlerCount: 0
+# CHECK-GC: ]
+# CHECK-GC-NOT: SEHTable
+
+
+ .def @feat.00;
+ .scl 3;
+ .type 0;
+ .endef
+ .globl @feat.00
+@feat.00 = 1
+
+ .def _main;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,_main
+ .globl _main
+_main:
+ movl $42, %eax
+ ret
+
+# This handler can be GCd, which will make the safeseh table empty, so it should
+# appear null.
+ .def _my_handler;
+ .scl 3;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,_my_handler
+_my_handler:
+ ret
+
+.safeseh _my_handler
+
+
+ .section .rdata,"dr"
+.globl __load_config_used
+__load_config_used:
+ .long 72
+ .fill 60, 1, 0
+ .long ___safe_se_handler_table
+ .long ___safe_se_handler_count
diff --git a/test/COFF/secidx-absolute.s b/test/COFF/secidx-absolute.s
new file mode 100644
index 000000000000..bfe7136b31d2
--- /dev/null
+++ b/test/COFF/secidx-absolute.s
@@ -0,0 +1,33 @@
+# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
+# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
+# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
+
+# Section relocations against absolute symbols resolve to the last real ouput
+# section index plus one.
+
+.text
+.global main
+main:
+ret
+
+.section .rdata,"dr"
+.secidx __guard_fids_table
+
+# CHECK: Sections [
+# CHECK: Section {
+# CHECK: Number: 1
+# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
+# CHECK: SectionData (
+# CHECK: 0000: 0300 |..|
+# CHECK: )
+# CHECK: }
+# CHECK: Section {
+# CHECK: Number: 2
+# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
+# CHECK: VirtualSize: 0x1
+# CHECK: SectionData (
+# CHECK: 0000: C3 |.|
+# CHECK: )
+# CHECK: }
+# CHECK-NOT: Section
+# CHECK: ]
diff --git a/test/COFF/secrel-absolute.s b/test/COFF/secrel-absolute.s
new file mode 100644
index 000000000000..69b5ab92991b
--- /dev/null
+++ b/test/COFF/secrel-absolute.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
+# RUN: not lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe 2>&1 | FileCheck %s
+
+# secrel relocations against absolute symbols are errors.
+
+# CHECK: SECREL relocation points to a non-regular symbol: __guard_fids_table
+
+.text
+.global main
+main:
+ret
+
+.section .rdata,"dr"
+.secrel32 __guard_fids_table
diff --git a/test/COFF/secrel-common.s b/test/COFF/secrel-common.s
new file mode 100644
index 000000000000..0188f6cb9674
--- /dev/null
+++ b/test/COFF/secrel-common.s
@@ -0,0 +1,41 @@
+# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
+# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
+# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
+
+# Section relocations against common symbols resolve to .bss.
+
+# CHECK: Sections [
+# CHECK: Section {
+# CHECK: Number: 1
+# CHECK: Name: .bss (2E 62 73 73 00 00 00 00)
+# CHECK: VirtualSize: 0x4
+# CHECK: }
+# CHECK: Section {
+# CHECK: Number: 2
+# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
+# CHECK: SectionData (
+# CHECK: 0000: 00000000 01000000 |........|
+# CHECK: )
+# CHECK: }
+# CHECK: Section {
+# CHECK: Number: 3
+# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
+# CHECK: VirtualSize: 0x1
+# CHECK: SectionData (
+# CHECK: 0000: C3 |.|
+# CHECK: )
+# CHECK: }
+# CHECK-NOT: Section
+# CHECK: ]
+
+.text
+.global main
+main:
+ret
+
+.comm common_global,4,2
+
+.section .rdata,"dr"
+.secrel32 common_global
+.secidx common_global
+.short 0
diff --git a/test/ELF/Inputs/exclude-libs.s b/test/ELF/Inputs/exclude-libs.s
new file mode 100644
index 000000000000..6d05c5e3aa91
--- /dev/null
+++ b/test/ELF/Inputs/exclude-libs.s
@@ -0,0 +1,3 @@
+.globl fn
+fn:
+ nop
diff --git a/test/ELF/arm-gnu-ifunc-plt.s b/test/ELF/arm-gnu-ifunc-plt.s
index 2561a4d34bed..efcaee1e9889 100644
--- a/test/ELF/arm-gnu-ifunc-plt.s
+++ b/test/ELF/arm-gnu-ifunc-plt.s
@@ -61,9 +61,9 @@
// DISASM: $d:
// DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0
// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless
-// DISASM-NEXT: 11054: 00 00 00 00 .word 0x00000000
-// DISASM-NEXT: 11058: 00 00 00 00 .word 0x00000000
-// DISASM-NEXT: 1105c: 00 00 00 00 .word 0x00000000
+// DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4
+// DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4
+// DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4
// DISASM: $a:
// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4]
// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc
diff --git a/test/ELF/arm-got-relative.s b/test/ELF/arm-got-relative.s
index db76711fe68e..46a3ca97d080 100644
--- a/test/ELF/arm-got-relative.s
+++ b/test/ELF/arm-got-relative.s
@@ -16,9 +16,9 @@ _start:
bx lr
.align 2
.LGOT:
- // gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
- // llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32
- .word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8)
+ // gas implicitly uses (R_ARM_BASE_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
+ // llvm-mc generates R_ARM_REL32, this will need updating when MC changes
+ .word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8)
.word function(GOT)
.globl function
@@ -28,17 +28,17 @@ function:
bx lr
// CHECK: Dynamic Relocations {
-// CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0
+// CHECK-NEXT: 0x2048 R_ARM_GLOB_DAT function 0x0
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Value: 0x2048
// CHECK-NEXT: Size:
// CHECK-NEXT: Binding: Local
// CHECK-NEXT: Type: None
// CHECK-NEXT: Other [
// CHECK-NEXT: STV_HIDDEN
// CHECK-NEXT: ]
-// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: Section: .got
// CODE: Disassembly of section .text:
// CODE-NEXT: _start:
@@ -49,5 +49,5 @@ function:
// CODE:$d.1:
// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
// CODE-NEXT: 1010: 38 10 00 00
-// (Got(function) - GotBase = 0x4
-// CODE-NEXT: 1014: 04 00 00 00
+// (Got(function) - GotBase = 0x0
+// CODE-NEXT: 1014: 00 00 00 00
diff --git a/test/ELF/arm-thumb-branch.s b/test/ELF/arm-thumb-branch.s
index 4dc0280b22f6..81bf7a3c68a9 100644
--- a/test/ELF/arm-thumb-branch.s
+++ b/test/ELF/arm-thumb-branch.s
@@ -54,7 +54,7 @@ callee_high:
// CHECK-NEXT: 1001c: ff f3 fd 97 b.w #16777210
// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574
// CHECK-NEXT: 10024: 70 47 bx lr
-// CHECK-NEXT: 10026: 00 00 movs r0, r0
+// CHECK-NEXT: 10026:
// CHECK-NEXT: Disassembly of section .callee2:
// CHECK-NEXT: callee_high:
// CHECK-NEXT: 10028: 70 47 bx lr
diff --git a/test/ELF/arm-thumb-plt-reloc.s b/test/ELF/arm-thumb-plt-reloc.s
index 95a6e9e7af79..f9afbb9c0ce1 100644
--- a/test/ELF/arm-thumb-plt-reloc.s
+++ b/test/ELF/arm-thumb-plt-reloc.s
@@ -30,7 +30,7 @@ _start:
// CHECK-NEXT: 11002: 70 47 bx lr
// CHECK: func3:
// CHECK-NEXT: 11004: 70 47 bx lr
-// CHECK-NEXT: 11006: 00 00 movs r0, r0
+// CHECK-NEXT: 11006: d4 d4
// CHECK: _start:
// 11008 + 4 -12 = 0x11000 = func1
// CHECK-NEXT: 11008: ff f7 fa ff bl #-12
@@ -49,7 +49,7 @@ _start:
// DSOTHUMB-NEXT: 1002: 70 47 bx lr
// DSOTHUMB: func3:
// DSOTHUMB-NEXT: 1004: 70 47 bx lr
-// DSOTHUMB-NEXT: 1006: 00 00 movs r0, r0
+// DSOTHUMB-NEXT: 1006: d4 d4
// DSOTHUMB: _start:
// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1
// DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40
diff --git a/test/ELF/defsym.s b/test/ELF/defsym.s
index 778180dc9324..253d5d8f408d 100644
--- a/test/ELF/defsym.s
+++ b/test/ELF/defsym.s
@@ -9,8 +9,6 @@
# RUN: llvm-readobj -t -s %t2 | FileCheck %s
# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE
-## In compare with GNU linkers, symbol defined with --defsym does
-## not get aliased name in symbol table:
# CHECK: Symbol {
# CHECK: Name: foo1
# CHECK-NEXT: Value: 0x123
@@ -21,7 +19,7 @@
# CHECK-NEXT: Section: Absolute
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
-# CHECK-NEXT: Name: foo1
+# CHECK-NEXT: Name: foo2
# CHECK-NEXT: Value: 0x123
# CHECK-NEXT: Size:
# CHECK-NEXT: Binding: Global
diff --git a/test/ELF/exclude-libs.s b/test/ELF/exclude-libs.s
new file mode 100644
index 000000000000..c36081f40e54
--- /dev/null
+++ b/test/ELF/exclude-libs.s
@@ -0,0 +1,30 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+// RUN: %p/Inputs/exclude-libs.s -o %t2.o
+// RUN: mkdir -p %t.dir
+// RUN: rm -f %t.dir/exc.a
+// RUN: llvm-ar rcs %t.dir/exc.a %t2.o
+
+// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe
+// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
+
+// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=foo,bar
+// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
+
+// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a
+// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
+
+// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo:bar:exc.a
+// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
+
+// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
+// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
+
+// DEFAULT: Name: fn
+// EXCLUDE-NOT: Name: fn
+
+.globl fn
+foo:
+ call fn@PLT
diff --git a/test/ELF/global-offset-table-position-aarch64.s b/test/ELF/global-offset-table-position-aarch64.s
new file mode 100644
index 000000000000..624e9b516fed
--- /dev/null
+++ b/test/ELF/global-offset-table-position-aarch64.s
@@ -0,0 +1,30 @@
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: aarch64
+.globl a
+.type a,@object
+.comm a,4,4
+
+.globl f
+.type f,@function
+f:
+ adrp x0, :got:a
+ ldr x0, [x0, #:got_lo12:a]
+
+.global _start
+.type _start,@function
+_start:
+ bl f
+.data
+.long _GLOBAL_OFFSET_TABLE_ - .
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
+// CHECK-NEXT: Value: 0x30090
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got
diff --git a/test/ELF/global-offset-table-position-arm.s b/test/ELF/global-offset-table-position-arm.s
new file mode 100644
index 000000000000..781d8ce5222f
--- /dev/null
+++ b/test/ELF/global-offset-table-position-arm.s
@@ -0,0 +1,35 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: arm
+
+// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
+.globl a
+.type a,%object
+.comm a,4,4
+
+.globl f
+.type f,%function
+f:
+ ldr r2, .L1
+.L0:
+ add r2, pc
+.L1:
+.word _GLOBAL_OFFSET_TABLE_ - (.L0+4)
+.word a(GOT)
+
+.global _start
+.type _start,%function
+_start:
+ bl f
+.data
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_
+// CHECK-NEXT: Value: 0x3068
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got
diff --git a/test/ELF/global-offset-table-position-i386.s b/test/ELF/global-offset-table-position-i386.s
new file mode 100644
index 000000000000..907105edcff0
--- /dev/null
+++ b/test/ELF/global-offset-table-position-i386.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: x86
+
+// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
+.globl a
+.type a,@object
+.comm a,4,4
+
+.globl f
+.type f,@function
+f:
+addl $_GLOBAL_OFFSET_TABLE_, %eax
+movl a@GOT(%eax), %eax
+
+.global _start
+.type _start,@function
+_start:
+addl $_GLOBAL_OFFSET_TABLE_, %eax
+calll f@PLT
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
+// CHECK-NEXT: Value: 0x306C
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got (0xA)
diff --git a/test/ELF/global-offset-table-position-mips.s b/test/ELF/global-offset-table-position-mips.s
new file mode 100644
index 000000000000..92daed1c7914
--- /dev/null
+++ b/test/ELF/global-offset-table-position-mips.s
@@ -0,0 +1,33 @@
+// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+
+// REQUIRES: mips
+
+// The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
+
+.globl a
+.hidden a
+.type a,@object
+.comm a,4,4
+
+.globl f
+.type f,@function
+f:
+ ld $v0,%got_page(a)($gp)
+ daddiu $v0,$v0,%got_ofst(a)
+
+.global _start
+.type _start,@function
+_start:
+ lw $t0,%call16(f)($gp)
+ .word _GLOBAL_OFFSET_TABLE_ - .
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
+// CHECK-NEXT: Value: 0x20000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local (0x0)
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got (0x9)
diff --git a/test/ELF/global-offset-table-position.s b/test/ELF/global-offset-table-position.s
new file mode 100644
index 000000000000..b3317c7edd8b
--- /dev/null
+++ b/test/ELF/global-offset-table-position.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: ld.lld -shared %t -o %t2
+// RUN: llvm-readobj -t %t2 | FileCheck %s
+// REQUIRES: x86
+
+// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
+.globl a
+.type a,@object
+.comm a,4,4
+
+.globl f
+.type f,@function
+f:
+movq a@GOTPCREL(%rip), %rax
+
+.global _start
+.type _start,@function
+_start:
+callq f@PLT
+.data
+.long _GLOBAL_OFFSET_TABLE_ - .
+
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_
+// CHECK-NEXT: Value: 0x30D8
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None (0x0)
+// CHECK-NEXT: Other [
+// CHECK-NEXT: STV_HIDDEN
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got
diff --git a/test/ELF/global_offset_table_shared.s b/test/ELF/global_offset_table_shared.s
index 7935925ae2b3..1ebc0110d4d7 100644
--- a/test/ELF/global_offset_table_shared.s
+++ b/test/ELF/global_offset_table_shared.s
@@ -1,9 +1,14 @@
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
// RUN: ld.lld -shared %t -o %t2
// RUN: llvm-readobj -t %t2 | FileCheck %s
-.long _GLOBAL_OFFSET_TABLE_
+.long _GLOBAL_OFFSET_TABLE_ - .
// CHECK: Name: _GLOBAL_OFFSET_TABLE_
-// CHECK-NEXT: Value:
+// CHECK-NEXT: Value: 0x2060
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other [ (0x2)
+// CHECK-NEXT: STV_HIDDEN (0x2)
+// CHECK-NEXT: ]
+// CHECK-NEXT: Section: .got
diff --git a/test/ELF/invalid-z.s b/test/ELF/invalid-z.s
new file mode 100644
index 000000000000..a5343c93e677
--- /dev/null
+++ b/test/ELF/invalid-z.s
@@ -0,0 +1,9 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: not ld.lld %t.o -o %t -z max-page-size 2>&1 | FileCheck %s
+# CHECK: invalid max-page-size
+# CHECK-NOT: error
+
+.global _start
+_start:
+ nop
diff --git a/test/ELF/linkerscript/discard-section-err.s b/test/ELF/linkerscript/discard-section-err.s
new file mode 100644
index 000000000000..5d9955545d92
--- /dev/null
+++ b/test/ELF/linkerscript/discard-section-err.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script
+# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | \
+# RUN: FileCheck -check-prefix=SHSTRTAB %s
+# SHSTRTAB: discarding .shstrtab section is not allowed
+
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script
+# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
+# RUN: FileCheck -check-prefix=DYNAMIC %s
+# DYNAMIC: discarding .dynamic section is not allowed
+
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script
+# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
+# RUN: FileCheck -check-prefix=DYNSYM %s
+# DYNSYM: discarding .dynsym section is not allowed
+
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script
+# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
+# RUN: FileCheck -check-prefix=DYNSTR %s
+# DYNSTR: discarding .dynstr section is not allowed
diff --git a/test/ELF/linkerscript/sections.s b/test/ELF/linkerscript/sections.s
index d5645c303754..dd4b12f42b89 100644
--- a/test/ELF/linkerscript/sections.s
+++ b/test/ELF/linkerscript/sections.s
@@ -67,12 +67,6 @@
# SEC-SWAP-NAMES: 7 .shstrtab 0000003b {{[0-9a-f]*}}
# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}}
-# Attemp to discard .shstrtab section.
-# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script
-# RUN: not ld.lld -o %t5 --script %t.script %t 2>&1 | \
-# RUN: FileCheck -check-prefix=SEC-DISCARD %s
-# SEC-DISCARD: discarding .shstrtab section is not allowed
-
# Multiple SECTIONS command specifying additional input section descriptions
# for the same output section description - input sections are merged into
# one output section.
diff --git a/test/ELF/linkerscript/segment-none.s b/test/ELF/linkerscript/segment-none.s
new file mode 100644
index 000000000000..d54e835a0c22
--- /dev/null
+++ b/test/ELF/linkerscript/segment-none.s
@@ -0,0 +1,39 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+## Test that section .foo is not placed in any segment when assigned to segment
+## NONE in the linker script and segment NONE is not defined.
+# RUN: echo "PHDRS {text PT_LOAD;} \
+# RUN: SECTIONS { \
+# RUN: .text : {*(.text .text*)} :text \
+# RUN: .foo : {*(.foo)} :NONE \
+# RUN: }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s
+
+## Test that section .foo is placed in segment NONE when assigned to segment
+## NONE in the linker script and segment NONE is defined.
+# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \
+# RUN: SECTIONS { \
+# RUN: .text : {*(.text .text*)} :text \
+# RUN: .foo : {*(.foo)} :NONE \
+# RUN: }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s
+
+# CHECK: Section to Segment mapping:
+# CHECK-NEXT: Segment Sections...
+# CHECK-NOT: .foo
+
+# DEFINED: Section to Segment mapping:
+# DEFINED-NEXT: Segment Sections...
+# DEFINED-NEXT: 00 .text
+# DEFINED-NEXT: 01 .foo
+
+.global _start
+_start:
+ nop
+
+.section .foo,"a"
+foo:
+ .long 0
diff --git a/test/ELF/linkerscript/ttext-script.s b/test/ELF/linkerscript/ttext-script.s
new file mode 100644
index 000000000000..9dcde9bb13c5
--- /dev/null
+++ b/test/ELF/linkerscript/ttext-script.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { .text 0x200000 : { *(.text) } }" > %t.script
+# RUN: ld.lld -T %t.script -Ttext 0x100000 %t.o -o %t
+# RUN: llvm-readobj --elf-output-style=GNU -s %t | FileCheck %s
+
+# CHECK: .text PROGBITS 0000000000100000
+
+.global _start
+_start:
+nop
diff --git a/test/ELF/lto/cache.ll b/test/ELF/lto/cache.ll
index 55e3a3d6f6cd..6731f522606f 100644
--- a/test/ELF/lto/cache.ll
+++ b/test/ELF/lto/cache.ll
@@ -12,6 +12,17 @@
; Two cached objects, plus a timestamp file and "foo", minus the file we removed.
; RUN: ls %t.cache | count 4
+; Create a file of size 64KB.
+; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo
+
+; This should leave the file in place.
+; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k -o %t3 %t2.o %t.o
+; RUN: ls %t.cache | count 5
+
+; This should remove it.
+; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k -o %t3 %t2.o %t.o
+; RUN: ls %t.cache | count 4
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/ELF/lto/wrap-2.ll b/test/ELF/lto/wrap-2.ll
index b2e33f83138e..b318b7f65f2d 100644
--- a/test/ELF/lto/wrap-2.ll
+++ b/test/ELF/lto/wrap-2.ll
@@ -10,8 +10,8 @@
; CHECK: foo:
; CHECK-NEXT: pushq %rax
-; CHECK-NEXT: callq{{.*}}<__wrap_bar>
; CHECK-NEXT: callq{{.*}}<bar>
+; CHECK-NEXT: callq{{.*}}<__real_bar>
; Check that bar and __wrap_bar retain their original binding.
; BIND: Name: bar
diff --git a/test/ELF/mips-got16-relocatable.s b/test/ELF/mips-got16-relocatable.s
index 963efeb4686e..bbacfdbaa682 100644
--- a/test/ELF/mips-got16-relocatable.s
+++ b/test/ELF/mips-got16-relocatable.s
@@ -15,8 +15,8 @@
# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 0
# OBJ-NEXT: 00000004: R_MIPS_LO16 .data
-# OBJ-NEXT: 8: 00 00 00 00 nop
-# OBJ-NEXT: c: 00 00 00 00 nop
+# OBJ-NEXT: 8: ef ef ef ef <unknown>
+# OBJ-NEXT: c: ef ef ef ef <unknown>
# OBJ-NEXT: 10: 8f 99 00 00 lw $25, 0($gp)
# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data
# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 16
@@ -26,8 +26,8 @@
# SO-NEXT: .text:
# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
-# SO-NEXT: 10008: 00 00 00 00 nop
-# SO-NEXT: 1000c: 00 00 00 00 nop
+# SO-NEXT: 10008: ef ef ef ef <unknown>
+# SO-NEXT: 1000c: ef ef ef ef <unknown>
# SO-NEXT: 10010: 8f 99 80 18 lw $25, -32744($gp)
# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 16
diff --git a/test/ELF/mips-npic-call-pic-os.s b/test/ELF/mips-npic-call-pic-os.s
index 131289e596e8..aea0fa1221dc 100644
--- a/test/ELF/mips-npic-call-pic-os.s
+++ b/test/ELF/mips-npic-call-pic-os.s
@@ -33,8 +33,8 @@
# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
# CHECK-NEXT: 20034: 00 00 00 00 nop
-# CHECK-NEXT: 20038: 00 00 00 00 nop
-# CHECK-NEXT: 2003c: 00 00 00 00 nop
+# CHECK-NEXT: 20038: ef ef ef ef <unknown>
+# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
# CHECK: foo2:
# CHECK-NEXT: 20040: 00 00 00 00 nop
# CHECK: __LA25Thunk_fpic:
@@ -42,14 +42,14 @@
# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>
# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 96
# CHECK-NEXT: 20050: 00 00 00 00 nop
-# CHECK-NEXT: 20054: 00 00 00 00 nop
-# CHECK-NEXT: 20058: 00 00 00 00 nop
-# CHECK-NEXT: 2005c: 00 00 00 00 nop
+# CHECK-NEXT: 20054: ef ef ef ef <unknown>
+# CHECK-NEXT: 20058: ef ef ef ef <unknown>
+# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
# CHECK: fpic:
# CHECK-NEXT: 20060: 00 00 00 00 nop
-# CHECK-NEXT: 20064: 00 00 00 00 nop
-# CHECK-NEXT: 20068: 00 00 00 00 nop
-# CHECK-NEXT: 2006c: 00 00 00 00 nop
+# CHECK-NEXT: 20064: ef ef ef ef <unknown>
+# CHECK-NEXT: 20068: ef ef ef ef <unknown>
+# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
# CHECK: fnpic:
# CHECK-NEXT: 20070: 00 00 00 00 nop
# CHECK-NEXT: Disassembly of section differentos:
@@ -93,13 +93,13 @@
# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
# REVERSE-NEXT: 20034: 00 00 00 00 nop
-# REVERSE-NEXT: 20038: 00 00 00 00 nop
-# REVERSE-NEXT: 2003c: 00 00 00 00 nop
+# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
# REVERSE: foo2:
# REVERSE-NEXT: 20040: 00 00 00 00 nop
-# REVERSE-NEXT: 20044: 00 00 00 00 nop
-# REVERSE-NEXT: 20048: 00 00 00 00 nop
-# REVERSE-NEXT: 2004c: 00 00 00 00 nop
+# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
+# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
# REVERSE: __LA25Thunk_fpic:
# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2
# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>
@@ -107,9 +107,9 @@
# REVERSE-NEXT: 2005c: 00 00 00 00 nop
# REVERSE: fpic:
# REVERSE-NEXT: 20060: 00 00 00 00 nop
-# REVERSE-NEXT: 20064: 00 00 00 00 nop
-# REVERSE-NEXT: 20068: 00 00 00 00 nop
-# REVERSE-NEXT: 2006c: 00 00 00 00 nop
+# REVERSE-NEXT: 20064: ef ef ef ef <unknown>
+# REVERSE-NEXT: 20068: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2006c: ef ef ef ef <unknown>
# REVERSE: fnpic:
# REVERSE-NEXT: 20070: 00 00 00 00 nop
# REVERSE-NEXT: Disassembly of section differentos:
diff --git a/test/ELF/mips-npic-call-pic-script.s b/test/ELF/mips-npic-call-pic-script.s
index 6028989ee4cb..230704459463 100644
--- a/test/ELF/mips-npic-call-pic-script.s
+++ b/test/ELF/mips-npic-call-pic-script.s
@@ -33,77 +33,77 @@
# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
# CHECK-NEXT: 20034: 00 00 00 00 nop
-# CHECK-NEXT: 20038: 00 00 00 00 nop
-# CHECK-NEXT: 2003c: 00 00 00 00 nop
+# CHECK-NEXT: 20038: ef ef ef ef <unknown>
+# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
# CHECK: foo2:
# CHECK-NEXT: 20040: 00 00 00 00 nop
-# CHECK-NEXT: 20044: 00 00 00 00 nop
-# CHECK-NEXT: 20048: 00 00 00 00 nop
-# CHECK-NEXT: 2004c: 00 00 00 00 nop
-# CHECK-NEXT: 20050: 00 00 00 00 nop
-# CHECK-NEXT: 20054: 00 00 00 00 nop
-# CHECK-NEXT: 20058: 00 00 00 00 nop
-# CHECK-NEXT: 2005c: 00 00 00 00 nop
-# CHECK-NEXT: 20060: 00 00 00 00 nop
-# CHECK-NEXT: 20064: 00 00 00 00 nop
-# CHECK-NEXT: 20068: 00 00 00 00 nop
-# CHECK-NEXT: 2006c: 00 00 00 00 nop
-# CHECK-NEXT: 20070: 00 00 00 00 nop
-# CHECK-NEXT: 20074: 00 00 00 00 nop
-# CHECK-NEXT: 20078: 00 00 00 00 nop
-# CHECK-NEXT: 2007c: 00 00 00 00 nop
-# CHECK-NEXT: 20080: 00 00 00 00 nop
-# CHECK-NEXT: 20084: 00 00 00 00 nop
-# CHECK-NEXT: 20088: 00 00 00 00 nop
-# CHECK-NEXT: 2008c: 00 00 00 00 nop
-# CHECK-NEXT: 20090: 00 00 00 00 nop
-# CHECK-NEXT: 20094: 00 00 00 00 nop
-# CHECK-NEXT: 20098: 00 00 00 00 nop
-# CHECK-NEXT: 2009c: 00 00 00 00 nop
-# CHECK-NEXT: 200a0: 00 00 00 00 nop
-# CHECK-NEXT: 200a4: 00 00 00 00 nop
-# CHECK-NEXT: 200a8: 00 00 00 00 nop
-# CHECK-NEXT: 200ac: 00 00 00 00 nop
-# CHECK-NEXT: 200b0: 00 00 00 00 nop
-# CHECK-NEXT: 200b4: 00 00 00 00 nop
-# CHECK-NEXT: 200b8: 00 00 00 00 nop
-# CHECK-NEXT: 200bc: 00 00 00 00 nop
-# CHECK-NEXT: 200c0: 00 00 00 00 nop
-# CHECK-NEXT: 200c4: 00 00 00 00 nop
-# CHECK-NEXT: 200c8: 00 00 00 00 nop
-# CHECK-NEXT: 200cc: 00 00 00 00 nop
-# CHECK-NEXT: 200d0: 00 00 00 00 nop
-# CHECK-NEXT: 200d4: 00 00 00 00 nop
-# CHECK-NEXT: 200d8: 00 00 00 00 nop
-# CHECK-NEXT: 200dc: 00 00 00 00 nop
-# CHECK-NEXT: 200e0: 00 00 00 00 nop
-# CHECK-NEXT: 200e4: 00 00 00 00 nop
-# CHECK-NEXT: 200e8: 00 00 00 00 nop
-# CHECK-NEXT: 200ec: 00 00 00 00 nop
-# CHECK-NEXT: 200f0: 00 00 00 00 nop
-# CHECK-NEXT: 200f4: 00 00 00 00 nop
-# CHECK-NEXT: 200f8: 00 00 00 00 nop
-# CHECK-NEXT: 200fc: 00 00 00 00 nop
-# CHECK-NEXT: 20100: 00 00 00 00 nop
-# CHECK-NEXT: 20104: 00 00 00 00 nop
-# CHECK-NEXT: 20108: 00 00 00 00 nop
-# CHECK-NEXT: 2010c: 00 00 00 00 nop
-# CHECK-NEXT: 20110: 00 00 00 00 nop
-# CHECK-NEXT: 20114: 00 00 00 00 nop
-# CHECK-NEXT: 20118: 00 00 00 00 nop
-# CHECK-NEXT: 2011c: 00 00 00 00 nop
-# CHECK-NEXT: 20120: 00 00 00 00 nop
-# CHECK-NEXT: 20124: 00 00 00 00 nop
-# CHECK-NEXT: 20128: 00 00 00 00 nop
-# CHECK-NEXT: 2012c: 00 00 00 00 nop
-# CHECK-NEXT: 20130: 00 00 00 00 nop
-# CHECK-NEXT: 20134: 00 00 00 00 nop
-# CHECK-NEXT: 20138: 00 00 00 00 nop
-# CHECK-NEXT: 2013c: 00 00 00 00 nop
-# CHECK-NEXT: 20140: 00 00 00 00 nop
-# CHECK-NEXT: 20144: 00 00 00 00 nop
-# CHECK-NEXT: 20148: 00 00 00 00 nop
-# CHECK-NEXT: 2014c: 00 00 00 00 nop
+# CHECK-NEXT: 20044: ef ef ef ef <unknown>
+# CHECK-NEXT: 20048: ef ef ef ef <unknown>
+# CHECK-NEXT: 2004c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20050: ef ef ef ef <unknown>
+# CHECK-NEXT: 20054: ef ef ef ef <unknown>
+# CHECK-NEXT: 20058: ef ef ef ef <unknown>
+# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20060: ef ef ef ef <unknown>
+# CHECK-NEXT: 20064: ef ef ef ef <unknown>
+# CHECK-NEXT: 20068: ef ef ef ef <unknown>
+# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20070: ef ef ef ef <unknown>
+# CHECK-NEXT: 20074: ef ef ef ef <unknown>
+# CHECK-NEXT: 20078: ef ef ef ef <unknown>
+# CHECK-NEXT: 2007c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20080: ef ef ef ef <unknown>
+# CHECK-NEXT: 20084: ef ef ef ef <unknown>
+# CHECK-NEXT: 20088: ef ef ef ef <unknown>
+# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20090: ef ef ef ef <unknown>
+# CHECK-NEXT: 20094: ef ef ef ef <unknown>
+# CHECK-NEXT: 20098: ef ef ef ef <unknown>
+# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
+# CHECK-NEXT: 200a0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200a4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200a8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200ac: ef ef ef ef <unknown>
+# CHECK-NEXT: 200b0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200b4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200b8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200bc: ef ef ef ef <unknown>
+# CHECK-NEXT: 200c0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200c4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200c8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200cc: ef ef ef ef <unknown>
+# CHECK-NEXT: 200d0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200d4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200d8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200dc: ef ef ef ef <unknown>
+# CHECK-NEXT: 200e0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200e4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200e8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200ec: ef ef ef ef <unknown>
+# CHECK-NEXT: 200f0: ef ef ef ef <unknown>
+# CHECK-NEXT: 200f4: ef ef ef ef <unknown>
+# CHECK-NEXT: 200f8: ef ef ef ef <unknown>
+# CHECK-NEXT: 200fc: ef ef ef ef <unknown>
+# CHECK-NEXT: 20100: ef ef ef ef <unknown>
+# CHECK-NEXT: 20104: ef ef ef ef <unknown>
+# CHECK-NEXT: 20108: ef ef ef ef <unknown>
+# CHECK-NEXT: 2010c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20110: ef ef ef ef <unknown>
+# CHECK-NEXT: 20114: ef ef ef ef <unknown>
+# CHECK-NEXT: 20118: ef ef ef ef <unknown>
+# CHECK-NEXT: 2011c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20120: ef ef ef ef <unknown>
+# CHECK-NEXT: 20124: ef ef ef ef <unknown>
+# CHECK-NEXT: 20128: ef ef ef ef <unknown>
+# CHECK-NEXT: 2012c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20130: ef ef ef ef <unknown>
+# CHECK-NEXT: 20134: ef ef ef ef <unknown>
+# CHECK-NEXT: 20138: ef ef ef ef <unknown>
+# CHECK-NEXT: 2013c: ef ef ef ef <unknown>
+# CHECK-NEXT: 20140: ef ef ef ef <unknown>
+# CHECK-NEXT: 20144: ef ef ef ef <unknown>
+# CHECK-NEXT: 20148: ef ef ef ef <unknown>
+# CHECK-NEXT: 2014c: ef ef ef ef <unknown>
# CHECK: __start:
# CHECK-NEXT: 20150: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
# CHECK-NEXT: 20154: 00 00 00 00 nop
@@ -124,9 +124,9 @@
# CHECK-NEXT: 2018c: 00 00 00 00 nop
# CHECK: fpic:
# CHECK-NEXT: 20190: 00 00 00 00 nop
-# CHECK-NEXT: 20194: 00 00 00 00 nop
-# CHECK-NEXT: 20198: 00 00 00 00 nop
-# CHECK-NEXT: 2019c: 00 00 00 00 nop
+# CHECK-NEXT: 20194: ef ef ef ef <unknown>
+# CHECK-NEXT: 20198: ef ef ef ef <unknown>
+# CHECK-NEXT: 2019c: ef ef ef ef <unknown>
# CHECK: fnpic:
# CHECK-NEXT: 201a0: 00 00 00 00 nop
@@ -166,9 +166,9 @@ __start:
# ORPH1-NEXT: 2003c: 00 00 00 00 nop
# ORPH1: fpic:
# ORPH1-NEXT: 20040: 00 00 00 00 nop
-# ORPH1-NEXT: 20044: 00 00 00 00 nop
-# ORPH1-NEXT: 20048: 00 00 00 00 nop
-# ORPH1-NEXT: 2004c: 00 00 00 00 nop
+# ORPH1-NEXT: 20044: ef ef ef ef <unknown>
+# ORPH1-NEXT: 20048: ef ef ef ef <unknown>
+# ORPH1-NEXT: 2004c: ef ef ef ef <unknown>
# ORPH1: fnpic:
# ORPH1-NEXT: 20050: 00 00 00 00 nop
# ORPH1: __LA25Thunk_foo1a:
@@ -181,9 +181,9 @@ __start:
# ORPH1-NEXT: 20068: 08 00 80 21 j 131204 <foo1b>
# ORPH1-NEXT: 2006c: 27 39 00 84 addiu $25, $25, 132
# ORPH1-NEXT: 20070: 00 00 00 00 nop
-# ORPH1-NEXT: 20074: 00 00 00 00 nop
-# ORPH1-NEXT: 20078: 00 00 00 00 nop
-# ORPH1-NEXT: 2007c: 00 00 00 00 nop
+# ORPH1-NEXT: 20074: ef ef ef ef <unknown>
+# ORPH1-NEXT: 20078: ef ef ef ef <unknown>
+# ORPH1-NEXT: 2007c: ef ef ef ef <unknown>
# ORPH1: foo1a:
# ORPH1-NEXT: 20080: 00 00 00 00 nop
# ORPH1: foo1b:
@@ -193,8 +193,8 @@ __start:
# ORPH1-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
# ORPH1-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
# ORPH1-NEXT: 20094: 00 00 00 00 nop
-# ORPH1-NEXT: 20098: 00 00 00 00 nop
-# ORPH1-NEXT: 2009c: 00 00 00 00 nop
+# ORPH1-NEXT: 20098: ef ef ef ef <unknown>
+# ORPH1-NEXT: 2009c: ef ef ef ef <unknown>
# ORPH1: foo2:
# ORPH1-NEXT: 200a0: 00 00 00 00 nop
@@ -224,9 +224,9 @@ __start:
# ORPH2-NEXT: 2003c: 00 00 00 00 nop
# ORPH2: fpic:
# ORPH2-NEXT: 20040: 00 00 00 00 nop
-# ORPH2-NEXT: 20044: 00 00 00 00 nop
-# ORPH2-NEXT: 20048: 00 00 00 00 nop
-# ORPH2-NEXT: 2004c: 00 00 00 00 nop
+# ORPH2-NEXT: 20044: ef ef ef ef <unknown>
+# ORPH2-NEXT: 20048: ef ef ef ef <unknown>
+# ORPH2-NEXT: 2004c: ef ef ef ef <unknown>
# ORPH2: fnpic:
# ORPH2-NEXT: 20050: 00 00 00 00 nop
# ORPH2-NEXT: Disassembly of section .text:
@@ -249,7 +249,7 @@ __start:
# ORPH2-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
# ORPH2-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
# ORPH2-NEXT: 20094: 00 00 00 00 nop
-# ORPH2-NEXT: 20098: 00 00 00 00 nop
-# ORPH2-NEXT: 2009c: 00 00 00 00 nop
+# ORPH2-NEXT: 20098: ef ef ef ef <unknown>
+# ORPH2-NEXT: 2009c: ef ef ef ef <unknown>
# ORPH2: foo2:
# ORPH2-NEXT: 200a0: 00 00 00 00 nop
diff --git a/test/ELF/mips-npic-call-pic.s b/test/ELF/mips-npic-call-pic.s
index a5a99d719983..c3c94d783410 100644
--- a/test/ELF/mips-npic-call-pic.s
+++ b/test/ELF/mips-npic-call-pic.s
@@ -51,8 +51,8 @@
# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>
# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112
# CHECK-NEXT: 20064: 00 00 00 00 nop
-# CHECK-NEXT: 20068: 00 00 00 00 nop
-# CHECK-NEXT: 2006c: 00 00 00 00 nop
+# CHECK-NEXT: 20068: ef ef ef ef <unknown>
+# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
# CHECK: foo2:
# CHECK-NEXT: 20070: 00 00 00 00 nop
@@ -62,15 +62,15 @@
# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>
# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144
# CHECK-NEXT: 20080: 00 00 00 00 nop
-# CHECK-NEXT: 20084: 00 00 00 00 nop
-# CHECK-NEXT: 20088: 00 00 00 00 nop
-# CHECK-NEXT: 2008c: 00 00 00 00 nop
+# CHECK-NEXT: 20084: ef ef ef ef <unknown>
+# CHECK-NEXT: 20088: ef ef ef ef <unknown>
+# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
# CHECK: fpic:
# CHECK-NEXT: 20090: 00 00 00 00 nop
-# CHECK-NEXT: 20094: 00 00 00 00 nop
-# CHECK-NEXT: 20098: 00 00 00 00 nop
-# CHECK-NEXT: 2009c: 00 00 00 00 nop
+# CHECK-NEXT: 20094: ef ef ef ef <unknown>
+# CHECK-NEXT: 20098: ef ef ef ef <unknown>
+# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
# CHECK: fnpic:
# CHECK-NEXT: 200a0: 00 00 00 00 nop
@@ -101,13 +101,13 @@
# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
# REVERSE-NEXT: 20034: 00 00 00 00 nop
-# REVERSE-NEXT: 20038: 00 00 00 00 nop
-# REVERSE-NEXT: 2003c: 00 00 00 00 nop
+# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
# REVERSE: foo2:
# REVERSE-NEXT: 20040: 00 00 00 00 nop
-# REVERSE-NEXT: 20044: 00 00 00 00 nop
-# REVERSE-NEXT: 20048: 00 00 00 00 nop
-# REVERSE-NEXT: 2004c: 00 00 00 00 nop
+# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
+# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
# REVERSE: __start:
# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
# REVERSE-NEXT: 20054: 00 00 00 00 nop
@@ -128,9 +128,9 @@
# REVERSE-NEXT: 2008c: 00 00 00 00 nop
# REVERSE: fpic:
# REVERSE-NEXT: 20090: 00 00 00 00 nop
-# REVERSE-NEXT: 20094: 00 00 00 00 nop
-# REVERSE-NEXT: 20098: 00 00 00 00 nop
-# REVERSE-NEXT: 2009c: 00 00 00 00 nop
+# REVERSE-NEXT: 20094: ef ef ef ef <unknown>
+# REVERSE-NEXT: 20098: ef ef ef ef <unknown>
+# REVERSE-NEXT: 2009c: ef ef ef ef <unknown>
# REVERSE: fnpic:
# REVERSE-NEXT: 200a0: 00 00 00 00 nop
diff --git a/test/ELF/mips-plt-r6.s b/test/ELF/mips-plt-r6.s
index ccf233cc73cd..4bab21c32eb9 100644
--- a/test/ELF/mips-plt-r6.s
+++ b/test/ELF/mips-plt-r6.s
@@ -18,7 +18,7 @@
#
# CHECK-NEXT: Disassembly of section .plt:
# CHECK-NEXT: .plt:
-# CHECK-NEXT: 20010: 3c 1c 00 03 aui $zero, $gp, 3
+# CHECK-NEXT: 20010: 3c 1c 00 03 aui $gp, $zero, 3
# CHECK-NEXT: 20014: 8f 99 00 04 lw $25, 4($gp)
# CHECK-NEXT: 20018: 27 9c 00 04 addiu $gp, $gp, 4
# CHECK-NEXT: 2001c: 03 1c c0 23 subu $24, $24, $gp
@@ -27,7 +27,7 @@
# CHECK-NEXT: 20028: 03 20 f8 09 jalr $25
# CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2
-# CHECK-NEXT: 20030: 3c 0f 00 03 aui $zero, $15, 3
+# CHECK-NEXT: 20030: 3c 0f 00 03 aui $15, $zero, 3
# CHECK-NEXT: 20034: 8d f9 00 0c lw $25, 12($15)
# CHECK-NEXT: 20038: 03 20 00 09 jr $25
# CHECK-NEXT: 2003c: 25 f8 00 0c addiu $24, $15, 12
diff --git a/test/ELF/wrap.s b/test/ELF/wrap.s
index 17aac2db6e18..d8d802bb8ca4 100644
--- a/test/ELF/wrap.s
+++ b/test/ELF/wrap.s
@@ -12,6 +12,14 @@
// CHECK-NEXT: movl $0x11010, %edx
// CHECK-NEXT: movl $0x11000, %edx
+// RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s
+// SYM: Name: __real_foo
+// SYM-NEXT: Value: 0x11000
+// SYM: Name: __wrap_foo
+// SYM-NEXT: Value: 0x11010
+// SYM: Name: foo
+// SYM-NEXT: Value: 0x11010
+
.global _start
_start:
movl $foo, %edx
diff --git a/test/lit.cfg b/test/lit.cfg
index c8471e1280aa..0cb62d4cab97 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -45,7 +45,7 @@ else:
config.test_format = lit.formats.ShTest(execute_external)
# suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.ll', '.s', '.objtxt', '.test']
+config.suffixes = ['.ll', '.s', '.test', '.yaml', '.objtxt']
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
@@ -262,8 +262,7 @@ llvm_config_cmd.wait()
# Set a fake constant version so that we get consitent output.
config.environment['LLD_VERSION'] = 'LLD 1.0'
-# Check if Windows resource file compiler exists.
-cvtres = lit.util.which('cvtres', config.environment['PATH'])
-rc = lit.util.which('rc', config.environment['PATH'])
-if cvtres and rc:
- config.available_features.add('winres')
+# Indirectly check if the mt.exe Microsoft utility exists by searching for
+# cvtres, which always accompanies it.
+if lit.util.which('cvtres', config.environment['PATH']):
+ config.available_features.add('win_mt')
diff --git a/test/mach-o/executable-exports.yaml b/test/mach-o/executable-exports.yaml
index 0b8717eb724e..f16cbd5ce935 100644
--- a/test/mach-o/executable-exports.yaml
+++ b/test/mach-o/executable-exports.yaml
@@ -42,5 +42,5 @@ global-symbols:
...
# CHECK-NOT: _myHidden
-# CHECK: 0x00000FFD _myRegular
-# CHECK: 0x00000FFE _myWeak [weak_def]
+# CHECK: 0x100000FFD _myRegular
+# CHECK: 0x100000FFE _myWeak [weak_def]