aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
Diffstat (limited to 'lld')
-rw-r--r--lld/COFF/DLL.cpp58
-rw-r--r--lld/COFF/Driver.cpp23
-rw-r--r--lld/COFF/InputFiles.cpp5
-rw-r--r--lld/COFF/Options.td6
-rw-r--r--lld/COFF/PDB.cpp9
-rw-r--r--lld/COFF/SymbolTable.cpp37
-rw-r--r--lld/COFF/SymbolTable.h3
-rw-r--r--lld/ELF/Arch/LoongArch.cpp9
-rw-r--r--lld/ELF/Arch/Mips.cpp4
-rw-r--r--lld/ELF/Config.h2
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/InputSection.cpp5
-rw-r--r--lld/ELF/Relocations.cpp29
-rw-r--r--lld/ELF/Relocations.h1
-rw-r--r--lld/ELF/SyntheticSections.cpp56
-rw-r--r--lld/ELF/SyntheticSections.h71
-rw-r--r--lld/ELF/Target.cpp3
-rw-r--r--lld/ELF/Target.h35
-rw-r--r--lld/ELF/Writer.cpp5
-rw-r--r--lld/test/COFF/alternatename-alias.s15
-rw-r--r--lld/test/COFF/alternatename-antidep.s16
-rw-r--r--lld/test/COFF/alternatename-lib.s43
-rw-r--r--lld/test/COFF/arm64ec-altnames.s39
-rw-r--r--lld/test/COFF/arm64ec-delayimport.test48
-rw-r--r--lld/test/COFF/arm64x-delayimport.test98
-rw-r--r--lld/test/COFF/delayimports.test14
-rw-r--r--lld/test/COFF/delayimporttables.yaml8
-rw-r--r--lld/test/COFF/embed-bitcode.test30
-rw-r--r--lld/test/COFF/giats.s4
-rw-r--r--lld/test/COFF/nodefaultlib.test19
-rw-r--r--lld/test/COFF/pdb-empty-sec.s19
-rw-r--r--lld/test/COFF/pdb-options.test12
-rw-r--r--lld/test/COFF/pdb-type-server-invalid-signature.yaml7
-rw-r--r--lld/test/COFF/wrap-lto-2.ll14
-rw-r--r--lld/test/COFF/wrap-with-archive.s3
-rw-r--r--lld/test/ELF/aarch64-build-attributes-malformed.s2
-rw-r--r--lld/test/ELF/loongarch-relax-pc-hi20-lo12.s59
-rw-r--r--lld/test/wasm/lto/save-temps.ll3
38 files changed, 508 insertions, 307 deletions
diff --git a/lld/COFF/DLL.cpp b/lld/COFF/DLL.cpp
index c327da2..3ce8853 100644
--- a/lld/COFF/DLL.cpp
+++ b/lld/COFF/DLL.cpp
@@ -244,40 +244,36 @@ static const uint8_t thunkX64[] = {
};
static const uint8_t tailMergeX64[] = {
- 0x51, // push rcx
- 0x52, // push rdx
- 0x41, 0x50, // push r8
- 0x41, 0x51, // push r9
- 0x48, 0x83, 0xEC, 0x48, // sub rsp, 48h
- 0x66, 0x0F, 0x7F, 0x04, 0x24, // movdqa xmmword ptr [rsp], xmm0
- 0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa xmmword ptr [rsp+10h], xmm1
- 0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa xmmword ptr [rsp+20h], xmm2
- 0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa xmmword ptr [rsp+30h], xmm3
- 0x48, 0x8B, 0xD0, // mov rdx, rax
- 0x48, 0x8D, 0x0D, 0, 0, 0, 0, // lea rcx, [___DELAY_IMPORT_...]
- 0xE8, 0, 0, 0, 0, // call __delayLoadHelper2
- 0x66, 0x0F, 0x6F, 0x04, 0x24, // movdqa xmm0, xmmword ptr [rsp]
- 0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x10, // movdqa xmm1, xmmword ptr [rsp+10h]
- 0x66, 0x0F, 0x6F, 0x54, 0x24, 0x20, // movdqa xmm2, xmmword ptr [rsp+20h]
- 0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x30, // movdqa xmm3, xmmword ptr [rsp+30h]
- 0x48, 0x83, 0xC4, 0x48, // add rsp, 48h
- 0x41, 0x59, // pop r9
- 0x41, 0x58, // pop r8
- 0x5A, // pop rdx
- 0x59, // pop rcx
- 0xFF, 0xE0, // jmp rax
+ 0x48, 0x89, 0x4C, 0x24, 0x08, // mov qword ptr [rsp+8], rcx
+ 0x48, 0x89, 0x54, 0x24, 0x10, // mov qword ptr [rsp+10h], rdx
+ 0x4C, 0x89, 0x44, 0x24, 0x18, // mov qword ptr [rsp+18h], r8
+ 0x4C, 0x89, 0x4C, 0x24, 0x20, // mov qword ptr [rsp+20h], r9
+ 0x48, 0x83, 0xEC, 0x68, // sub rsp, 68h
+ 0x66, 0x0F, 0x7F, 0x44, 0x24, 0x20, // movdqa xmmword ptr [rsp+20h], xmm0
+ 0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x30, // movdqa xmmword ptr [rsp+30h], xmm1
+ 0x66, 0x0F, 0x7F, 0x54, 0x24, 0x40, // movdqa xmmword ptr [rsp+40h], xmm2
+ 0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x50, // movdqa xmmword ptr [rsp+50h], xmm3
+ 0x48, 0x8B, 0xD0, // mov rdx, rax
+ 0x48, 0x8D, 0x0D, 0, 0, 0, 0, // lea rcx, [___DELAY_IMPORT_...]
+ 0xE8, 0, 0, 0, 0, // call __delayLoadHelper2
+ 0x66, 0x0F, 0x6F, 0x44, 0x24, 0x20, // movdqa xmm0, xmmword ptr [rsp+20h]
+ 0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x30, // movdqa xmm1, xmmword ptr [rsp+30h]
+ 0x66, 0x0F, 0x6F, 0x54, 0x24, 0x40, // movdqa xmm2, xmmword ptr [rsp+40h]
+ 0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x50, // movdqa xmm3, xmmword ptr [rsp+50h]
+ 0x48, 0x8B, 0x4C, 0x24, 0x70, // mov rcx, qword ptr [rsp+70h]
+ 0x48, 0x8B, 0x54, 0x24, 0x78, // mov rdx, qword ptr [rsp+78h]
+ 0x4C, 0x8B, 0x84, 0x24, 0x80, 0, 0, 0, // mov r8, qword ptr [rsp+80h]
+ 0x4C, 0x8B, 0x8C, 0x24, 0x88, 0, 0, 0, // mov r9, qword ptr [rsp+88h]
+ 0x48, 0x83, 0xC4, 0x68, // add rsp, 68h
+ 0xFF, 0xE0, // jmp rax
};
static const uint8_t tailMergeUnwindInfoX64[] = {
0x01, // Version=1, Flags=UNW_FLAG_NHANDLER
- 0x0a, // Size of prolog
- 0x05, // Count of unwind codes
+ 0x18, // Size of prolog
+ 0x01, // Count of unwind codes
0x00, // No frame register
- 0x0a, 0x82, // Offset 0xa: UWOP_ALLOC_SMALL(0x48)
- 0x06, 0x02, // Offset 6: UWOP_ALLOC_SMALL(8)
- 0x04, 0x02, // Offset 4: UWOP_ALLOC_SMALL(8)
- 0x02, 0x02, // Offset 2: UWOP_ALLOC_SMALL(8)
- 0x01, 0x02, // Offset 1: UWOP_ALLOC_SMALL(8)
+ 0x18, 0xC2, // Offset 0x18: UWOP_ALLOC_SMALL(0x68)
0x00, 0x00 // Padding to align on 32-bits
};
@@ -378,8 +374,8 @@ public:
void writeTo(uint8_t *buf) const override {
memcpy(buf, tailMergeX64, sizeof(tailMergeX64));
- write32le(buf + 39, desc->getRVA() - rva - 43);
- write32le(buf + 44, helper->getRVA() - rva - 48);
+ write32le(buf + 54, desc->getRVA() - rva - 58);
+ write32le(buf + 59, helper->getRVA() - rva - 63);
}
Chunk *desc = nullptr;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 83040b5..570b8f9 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2554,28 +2554,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
e.symbolName = symtab.mangleMaybe(e.sym);
}
- // Add weak aliases. Weak aliases is a mechanism to give remaining
- // undefined symbols final chance to be resolved successfully.
- for (auto pair : symtab.alternateNames) {
- StringRef from = pair.first;
- StringRef to = pair.second;
- Symbol *sym = symtab.find(from);
- if (!sym)
- continue;
- if (auto *u = dyn_cast<Undefined>(sym)) {
- if (u->weakAlias) {
- // On ARM64EC, anti-dependency aliases are treated as undefined
- // symbols unless a demangled symbol aliases a defined one, which
- // is part of the implementation.
- if (!symtab.isEC() || !u->isAntiDep)
- continue;
- if (!isa<Undefined>(u->weakAlias) &&
- !isArm64ECMangledFunctionName(u->getName()))
- continue;
- }
- u->setWeakAlias(symtab.addUndefined(to));
- }
- }
+ symtab.resolveAlternateNames();
});
ctx.forEachActiveSymtab([&](SymbolTable &symtab) {
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 2a6b63c..c08099b 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -403,6 +403,11 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
return nullptr;
}
+ // Those sections are generated by -fembed-bitcode and do not need to be kept
+ // in executable files.
+ if (name == ".llvmbc" || name == ".llvmcmd")
+ return nullptr;
+
// Object files may have DWARF debug info or MS CodeView debug info
// (or both).
//
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 2a82fb5..0d66b49 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -353,7 +353,13 @@ def fastfail : F<"fastfail">;
def kernel : F<"kernel">;
def pdbcompress : F<"pdbcompress">;
def emitpogophaseinfo : F<"emitpogophaseinfo">;
+defm emittoolversioninfo: B<
+ "emittoolversioninfo",
+ "Emit a tool version info after DOS header (so-called Rich header, default)",
+ "Do not emit a tool version info after DOS header (so-called Rich header)">;
+def nocoffgrpinfo: F<"nocoffgrpinfo">;
def noexp : F<"noexp">;
+def novcfeature: F<"novcfeature">;
def delay : P_priv<"delay">;
def errorreport : P_priv<"errorreport">;
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index a54ea40..94eeae2 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1135,9 +1135,12 @@ static pdb::BulkPublic createPublic(COFFLinkerContext &ctx, Defined *def) {
pub.setFlags(flags);
OutputSection *os = ctx.getOutputSection(def->getChunk());
- assert(os && "all publics should be in final image");
- pub.Offset = def->getRVA() - os->getRVA();
- pub.Segment = os->sectionIndex;
+ assert((os || !def->getChunk()->getSize()) &&
+ "all publics should be in final image");
+ if (os) {
+ pub.Offset = def->getRVA() - os->getRVA();
+ pub.Segment = os->sectionIndex;
+ }
return pub;
}
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 0062df5..189e75d 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -1344,6 +1344,43 @@ void SymbolTable::parseAlternateName(StringRef s) {
alternateNames.insert(it, std::make_pair(from, to));
}
+void SymbolTable::resolveAlternateNames() {
+ // Add weak aliases. Weak aliases is a mechanism to give remaining
+ // undefined symbols final chance to be resolved successfully.
+ for (auto pair : alternateNames) {
+ StringRef from = pair.first;
+ StringRef to = pair.second;
+ Symbol *sym = find(from);
+ if (!sym)
+ continue;
+ if (auto *u = dyn_cast<Undefined>(sym)) {
+ if (u->weakAlias) {
+ // On ARM64EC, anti-dependency aliases are treated as undefined
+ // symbols unless a demangled symbol aliases a defined one, which
+ // is part of the implementation.
+ if (!isEC() || !u->isAntiDep)
+ continue;
+ if (!isa<Undefined>(u->weakAlias) &&
+ !isArm64ECMangledFunctionName(u->getName()))
+ continue;
+ }
+
+ // Check if the destination symbol is defined. If not, skip it.
+ // It may still be resolved later if more input files are added.
+ // Also skip anti-dependency targets, as they can't be chained anyway.
+ Symbol *toSym = find(to);
+ if (!toSym)
+ continue;
+ auto toUndef = dyn_cast<Undefined>(toSym);
+ if (toUndef && (!toUndef->weakAlias || toUndef->isAntiDep))
+ continue;
+ if (toSym->isLazy())
+ forceLazy(toSym);
+ u->setWeakAlias(toSym);
+ }
+ }
+}
+
// Parses /aligncomm option argument.
void SymbolTable::parseAligncomm(StringRef s) {
auto [name, align] = s.split(',');
diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index 15e2644..7eb0676 100644
--- a/lld/COFF/SymbolTable.h
+++ b/lld/COFF/SymbolTable.h
@@ -69,6 +69,9 @@ public:
// symbols and warn about imported local symbols.
void resolveRemainingUndefines();
+ // Try to resolve undefined symbols with alternate names.
+ void resolveAlternateNames();
+
// Load lazy objects that are needed for MinGW automatic import and for
// doing stdcall fixups.
void loadMinGWSymbols();
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 15dcddb..a145530 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -809,10 +809,13 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
// address.
// Meanwhile skip undefined, preemptible and STT_GNU_IFUNC symbols, because
// these symbols may be resolve in runtime.
+ // Moreover, relaxation can only occur if the addends of both relocations are
+ // zero for GOT references.
if (rHi20.type == R_LARCH_GOT_PC_HI20 &&
- (!rHi20.sym->isDefined() || rHi20.sym->isPreemptible ||
- rHi20.sym->isGnuIFunc() ||
- (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section)))
+ (!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||
+ rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc() ||
+ (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section) ||
+ rHi20.addend != 0 || rLo12.addend != 0))
return;
uint64_t dest = 0;
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 91c7f15..f88b021c 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -40,6 +40,10 @@ public:
};
} // namespace
+uint64_t elf::getMipsPageAddr(uint64_t addr) {
+ return (addr + 0x8000) & ~0xffff;
+}
+
template <class ELFT> MIPS<ELFT>::MIPS(Ctx &ctx) : TargetInfo(ctx) {
gotPltHeaderEntriesNum = 2;
defaultMaxPageSize = 65536;
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index e7622dd..a83a4c1 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -702,6 +702,8 @@ struct Ctx : CommonLinkerContext {
std::unique_ptr<llvm::TarWriter> tar;
// InputFile for linker created symbols with no source location.
InputFile *internalFile = nullptr;
+ // Dummy Undefined for relocations without a symbol.
+ Undefined *dummySym = nullptr;
// True if symbols can be exported (isExported) or preemptible.
bool hasDynsym = false;
// True if SHT_LLVM_SYMPART is used.
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 91e11bc..6c2f318 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -3140,6 +3140,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.symtab->insert(arg->getValue())->traced = true;
ctx.internalFile = createInternalFile(ctx, "<internal>");
+ ctx.dummySym = make<Undefined>(ctx.internalFile, "", STB_LOCAL, 0, 0);
// Handle -u/--undefined before input files. If both a.a and b.so define foo,
// -u foo a.a b.so will extract a.a.
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 68e3feb..784ff7c 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -861,6 +861,11 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
return ctx.in.mipsGot->getVA() +
ctx.in.mipsGot->getPageEntryOffset(file, *r.sym, a) -
ctx.in.mipsGot->getGp(file);
+ case RE_MIPS_OSEC_LOCAL_PAGE:
+ // This is used by the MIPS multi-GOT implementation. It relocates
+ // addresses of 64kb pages that lie inside the output section that sym is
+ // a representative for.
+ return getMipsPageAddr(r.sym->getOutputSection()->addr) + a;
case RE_MIPS_GOT_OFF:
case RE_MIPS_GOT_OFF32:
// In case of MIPS if a GOT relocation has non-zero addend this addend
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index bd22fe2..32ac28d6 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -885,10 +885,12 @@ static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
RelocationBaseSection &rel, RelType type, Symbol &sym) {
plt.addEntry(sym);
gotPlt.addEntry(sym);
- rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
- sym.isPreemptible ? DynamicReloc::AgainstSymbol
- : DynamicReloc::AddendOnlyWithTargetVA,
- sym, 0, R_ABS});
+ if (sym.isPreemptible)
+ rel.addReloc(
+ {type, &gotPlt, sym.getGotPltOffset(ctx), true, sym, 0, R_ADDEND});
+ else
+ rel.addReloc(
+ {type, &gotPlt, sym.getGotPltOffset(ctx), false, sym, 0, R_ABS});
}
void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
@@ -897,9 +899,8 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
// If preemptible, emit a GLOB_DAT relocation.
if (sym.isPreemptible) {
- ctx.mainPart->relaDyn->addReloc({ctx.target->gotRel, ctx.in.got.get(), off,
- DynamicReloc::AgainstSymbol, sym, 0,
- R_ABS});
+ ctx.mainPart->relaDyn->addReloc(
+ {ctx.target->gotRel, ctx.in.got.get(), off, true, sym, 0, R_ADDEND});
return;
}
@@ -920,15 +921,13 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {
// If preemptible, emit a GLOB_DAT relocation.
if (sym.isPreemptible) {
ctx.mainPart->relaDyn->addReloc({R_AARCH64_AUTH_GLOB_DAT, ctx.in.got.get(),
- off, DynamicReloc::AgainstSymbol, sym, 0,
- R_ABS});
+ off, true, sym, 0, R_ADDEND});
return;
}
// Signed GOT requires dynamic relocation.
ctx.in.got->getPartition(ctx).relaDyn->addReloc(
- {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off,
- DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS});
+ {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, false, sym, 0, R_ABS});
}
static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) {
@@ -1159,9 +1158,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
sec->addReloc({expr, type, offset, addend, &sym});
part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1});
} else {
- part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
- DynamicReloc::AddendOnlyWithTargetVA, sym,
- addend, R_ABS});
+ part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, false,
+ sym, addend, R_ABS});
}
return;
}
@@ -1948,13 +1946,12 @@ void elf::postScanRelocations(Ctx &ctx) {
GotSection *got = ctx.in.got.get();
if (ctx.needsTlsLd.load(std::memory_order_relaxed) && got->addTlsIndex()) {
- static Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
if (ctx.arg.shared)
ctx.mainPart->relaDyn->addReloc(
{ctx.target->tlsModuleIndexRel, got, got->getTlsIndexOff()});
else
got->addConstant({R_ADDEND, ctx.target->symbolicRel,
- got->getTlsIndexOff(), 1, &dummy});
+ got->getTlsIndexOff(), 1, ctx.dummySym});
}
assert(ctx.symAux.size() == 1);
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index 02ddf70..c1c4860 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -110,6 +110,7 @@ enum RelExpr {
RE_MIPS_GOT_LOCAL_PAGE,
RE_MIPS_GOT_OFF,
RE_MIPS_GOT_OFF32,
+ RE_MIPS_OSEC_LOCAL_PAGE,
RE_MIPS_TLSGD,
RE_MIPS_TLSLD,
RE_PPC32_PLTREL,
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index efec41a..0d87f9a 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -769,10 +769,6 @@ void GotSection::writeTo(uint8_t *buf) {
}
}
-static uint64_t getMipsPageAddr(uint64_t addr) {
- return (addr + 0x8000) & ~0xffff;
-}
-
static uint64_t getMipsPageCount(uint64_t size) {
return (size + 0xfffe) / 0xffff + 1;
}
@@ -786,7 +782,7 @@ void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
FileGot &g = getGot(file);
if (expr == RE_MIPS_GOT_LOCAL_PAGE) {
if (const OutputSection *os = sym.getOutputSection())
- g.pagesMap.insert({os, {}});
+ g.pagesMap.insert({os, {&sym}});
else
g.local16.insert({{nullptr, getMipsPageAddr(sym.getVA(ctx, addend))}, 0});
} else if (sym.isTls())
@@ -1066,8 +1062,7 @@ void MipsGotSection::build() {
// be allocated before us in the static TLS block.
if (s->isPreemptible || ctx.arg.shared)
ctx.mainPart->relaDyn->addReloc(
- {ctx.target->tlsGotRel, this, offset,
- DynamicReloc::AgainstSymbolWithTargetVA, *s, 0, R_ABS});
+ {ctx.target->tlsGotRel, this, offset, true, *s, 0, R_ABS});
}
for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
Symbol *s = p.first;
@@ -1115,15 +1110,16 @@ void MipsGotSection::build() {
size_t pageCount = l.second.count;
for (size_t pi = 0; pi < pageCount; ++pi) {
uint64_t offset = (l.second.firstIndex + pi) * ctx.arg.wordsize;
- ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
- l.first, int64_t(pi * 0x10000)});
+ ctx.mainPart->relaDyn->addReloc(
+ {ctx.target->relativeRel, this, offset, false, *l.second.repSym,
+ int64_t(pi * 0x10000), RE_MIPS_OSEC_LOCAL_PAGE});
}
}
for (const std::pair<GotEntry, size_t> &p : got.local16) {
uint64_t offset = p.second * ctx.arg.wordsize;
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
- DynamicReloc::AddendOnlyWithTargetVA,
- *p.first.first, p.first.second, R_ABS});
+ false, *p.first.first, p.first.second,
+ R_ABS});
}
}
}
@@ -1646,24 +1642,10 @@ uint64_t DynamicReloc::getOffset() const {
}
int64_t DynamicReloc::computeAddend(Ctx &ctx) const {
- switch (kind) {
- case AddendOnly:
- assert(sym == nullptr);
- return addend;
- case AgainstSymbol:
- assert(sym != nullptr);
- return addend;
- case AddendOnlyWithTargetVA:
- case AgainstSymbolWithTargetVA: {
- uint64_t ca = inputSec->getRelocTargetVA(
- ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
- return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
- }
- case MipsMultiGotPage:
- assert(sym == nullptr);
- return getMipsPageAddr(outputSec->addr) + addend;
- }
- llvm_unreachable("Unknown DynamicReloc::Kind enum");
+ assert(!isFinal && "addend already computed");
+ uint64_t ca = inputSec->getRelocTargetVA(
+ ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
+ return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
}
uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
@@ -1691,8 +1673,8 @@ RelocationBaseSection::RelocationBaseSection(Ctx &ctx, StringRef name,
void RelocationBaseSection::addSymbolReloc(
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
int64_t addend, std::optional<RelType> addendRelType) {
- addReloc(DynamicReloc::AgainstSymbol, dynType, isec, offsetInSec, sym, addend,
- R_ADDEND, addendRelType ? *addendRelType : ctx.target->noneRel);
+ addReloc(true, dynType, isec, offsetInSec, sym, addend, R_ADDEND,
+ addendRelType ? *addendRelType : ctx.target->noneRel);
}
void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
@@ -1700,11 +1682,9 @@ void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
RelType addendRelType) {
// No need to write an addend to the section for preemptible symbols.
if (sym.isPreemptible)
- addReloc({dynType, &isec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
- R_ABS});
+ addReloc({dynType, &isec, offsetInSec, true, sym, 0, R_ADDEND});
else
- addReloc(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec, offsetInSec,
- sym, 0, R_ABS, addendRelType);
+ addReloc(false, dynType, isec, offsetInSec, sym, 0, R_ABS, addendRelType);
}
void RelocationBaseSection::mergeRels() {
@@ -1744,17 +1724,17 @@ void RelocationBaseSection::finalizeContents() {
}
}
-void DynamicReloc::computeRaw(Ctx &ctx, SymbolTableBaseSection *symt) {
+void DynamicReloc::finalize(Ctx &ctx, SymbolTableBaseSection *symt) {
r_offset = getOffset();
r_sym = getSymIndex(symt);
addend = computeAddend(ctx);
- kind = AddendOnly; // Catch errors
+ isFinal = true; // Catch errors
}
void RelocationBaseSection::computeRels() {
SymbolTableBaseSection *symTab = getPartition(ctx).dynSymTab.get();
parallelForEach(relocs, [&ctx = ctx, symTab](DynamicReloc &rel) {
- rel.computeRaw(ctx, symTab);
+ rel.finalize(ctx, symTab);
});
auto irelative = std::stable_partition(
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 5f01513..223dfe3 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -327,9 +327,11 @@ private:
size_t startIndex = 0;
struct PageBlock {
+ Symbol *repSym; // Representative symbol for the OutputSection
size_t firstIndex;
size_t count;
- PageBlock() : firstIndex(0), count(0) {}
+ PageBlock(Symbol *repSym = nullptr)
+ : repSym(repSym), firstIndex(0), count(0) {}
};
// Map output sections referenced by MIPS GOT relocations
@@ -418,61 +420,31 @@ private:
class DynamicReloc {
public:
- enum Kind {
- /// The resulting dynamic relocation does not reference a symbol (#sym must
- /// be nullptr) and uses #addend as the result of computeAddend(ctx).
- AddendOnly,
- /// The resulting dynamic relocation will not reference a symbol: #sym is
- /// only used to compute the addend with InputSection::getRelocTargetVA().
- /// Useful for various relative and TLS relocations (e.g. R_X86_64_TPOFF64).
- AddendOnlyWithTargetVA,
- /// The resulting dynamic relocation references symbol #sym from the dynamic
- /// symbol table and uses #addend as the value of computeAddend(ctx).
- AgainstSymbol,
- /// The resulting dynamic relocation references symbol #sym from the dynamic
- /// symbol table and uses InputSection::getRelocTargetVA() + #addend for the
- /// final addend. It can be used for relocations that write the symbol VA as
- // the addend (e.g. R_MIPS_TLS_TPREL64) but still reference the symbol.
- AgainstSymbolWithTargetVA,
- /// This is used by the MIPS multi-GOT implementation. It relocates
- /// addresses of 64kb pages that lie inside the output section.
- MipsMultiGotPage,
- };
- /// This constructor records a relocation against a symbol.
+ /// This constructor records a normal relocation.
DynamicReloc(RelType type, const InputSectionBase *inputSec,
- uint64_t offsetInSec, Kind kind, Symbol &sym, int64_t addend,
- RelExpr expr)
+ uint64_t offsetInSec, bool isAgainstSymbol, Symbol &sym,
+ int64_t addend, RelExpr expr)
: sym(&sym), inputSec(inputSec), offsetInSec(offsetInSec), type(type),
- addend(addend), kind(kind), expr(expr) {}
+ addend(addend), isAgainstSymbol(isAgainstSymbol), isFinal(false),
+ expr(expr) {}
/// This constructor records a relative relocation with no symbol.
DynamicReloc(RelType type, const InputSectionBase *inputSec,
uint64_t offsetInSec, int64_t addend = 0)
- : sym(nullptr), inputSec(inputSec), offsetInSec(offsetInSec), type(type),
- addend(addend), kind(AddendOnly), expr(R_ADDEND) {}
- /// This constructor records dynamic relocation settings used by the MIPS
- /// multi-GOT implementation.
- DynamicReloc(RelType type, const InputSectionBase *inputSec,
- uint64_t offsetInSec, const OutputSection *outputSec,
- int64_t addend)
- : sym(nullptr), outputSec(outputSec), inputSec(inputSec),
- offsetInSec(offsetInSec), type(type), addend(addend),
- kind(MipsMultiGotPage), expr(R_ADDEND) {}
+ : DynamicReloc(type, inputSec, offsetInSec, false,
+ *inputSec->getCtx().dummySym, addend, R_ADDEND) {}
uint64_t getOffset() const;
uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
- bool needsDynSymIndex() const {
- return kind == AgainstSymbol || kind == AgainstSymbolWithTargetVA;
- }
+ bool needsDynSymIndex() const { return isAgainstSymbol; }
/// Computes the addend of the dynamic relocation. Note that this is not the
/// same as the #addend member variable as it may also include the symbol
/// address/the address of the corresponding GOT entry/etc.
int64_t computeAddend(Ctx &) const;
- void computeRaw(Ctx &, SymbolTableBaseSection *symt);
+ void finalize(Ctx &, SymbolTableBaseSection *symt);
Symbol *sym;
- const OutputSection *outputSec = nullptr;
const InputSectionBase *inputSec;
uint64_t offsetInSec;
uint64_t r_offset;
@@ -483,7 +455,15 @@ public:
int64_t addend;
private:
- Kind kind;
+ /// Whether this was constructed with a Kind of AgainstSymbol.
+ LLVM_PREFERRED_TYPE(bool)
+ uint8_t isAgainstSymbol : 1;
+
+ /// The resulting dynamic relocation has already had its addend computed.
+ /// Calling computeAddend() is an error.
+ LLVM_PREFERRED_TYPE(bool)
+ uint8_t isFinal : 1;
+
// The kind of expression used to calculate the added (required e.g. for
// relative GOT relocations).
RelExpr expr;
@@ -528,8 +508,8 @@ public:
uint64_t offsetInSec, Symbol &sym, int64_t addend,
RelType addendRelType, RelExpr expr) {
assert(expr != R_ADDEND && "expected non-addend relocation expression");
- addReloc<shard>(DynamicReloc::AddendOnlyWithTargetVA, dynType, isec,
- offsetInSec, sym, addend, expr, addendRelType);
+ addReloc<shard>(false, dynType, isec, offsetInSec, sym, addend, expr,
+ addendRelType);
}
/// Add a dynamic relocation using the target address of \p sym as the addend
/// if \p sym is non-preemptible. Otherwise add a relocation against \p sym.
@@ -538,14 +518,15 @@ public:
uint64_t offsetInSec, Symbol &sym,
RelType addendRelType);
template <bool shard = false>
- void addReloc(DynamicReloc::Kind kind, RelType dynType, InputSectionBase &sec,
+ void addReloc(bool isAgainstSymbol, RelType dynType, InputSectionBase &sec,
uint64_t offsetInSec, Symbol &sym, int64_t addend, RelExpr expr,
RelType addendRelType) {
// Write the addends to the relocated address if required. We skip
// it if the written value would be zero.
if (ctx.arg.writeAddends && (expr != R_ADDEND || addend != 0))
sec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});
- addReloc<shard>({dynType, &sec, offsetInSec, kind, sym, addend, expr});
+ addReloc<shard>(
+ {dynType, &sec, offsetInSec, isAgainstSymbol, sym, addend, expr});
}
bool isNeeded() const override {
return !relocs.empty() ||
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index ad7d57d..4946484 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -105,10 +105,9 @@ ErrorPlace elf::getErrorPlace(Ctx &ctx, const uint8_t *loc) {
if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
std::string objLoc = isec->getLocation(loc - isecLoc);
// Return object file location and source file location.
- Undefined dummy(ctx.internalFile, "", STB_LOCAL, 0, 0);
ELFSyncStream msg(ctx, DiagLevel::None);
if (isec->file)
- msg << isec->getSrcMsg(dummy, loc - isecLoc);
+ msg << isec->getSrcMsg(*ctx.dummySym, loc - isecLoc);
return {isec, objLoc + ": ", std::string(msg.str())};
}
}
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 93f1592..fdc0c20 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -214,6 +214,7 @@ void processArmCmseSymbols(Ctx &);
template <class ELFT> uint32_t calcMipsEFlags(Ctx &);
uint8_t getMipsFpAbiFlag(Ctx &, InputFile *file, uint8_t oldFlag,
uint8_t newFlag);
+uint64_t getMipsPageAddr(uint64_t addr);
bool isMipsN32Abi(Ctx &, const InputFile &f);
bool isMicroMips(Ctx &);
bool isMipsR6(Ctx &);
@@ -338,21 +339,23 @@ inline uint64_t overwriteULEB128(uint8_t *bufLoc, uint64_t val) {
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#endif
#define invokeELFT(f, ...) \
- switch (ctx.arg.ekind) { \
- case lld::elf::ELF32LEKind: \
- f<llvm::object::ELF32LE>(__VA_ARGS__); \
- break; \
- case lld::elf::ELF32BEKind: \
- f<llvm::object::ELF32BE>(__VA_ARGS__); \
- break; \
- case lld::elf::ELF64LEKind: \
- f<llvm::object::ELF64LE>(__VA_ARGS__); \
- break; \
- case lld::elf::ELF64BEKind: \
- f<llvm::object::ELF64BE>(__VA_ARGS__); \
- break; \
- default: \
- llvm_unreachable("unknown ctx.arg.ekind"); \
- }
+ do { \
+ switch (ctx.arg.ekind) { \
+ case lld::elf::ELF32LEKind: \
+ f<llvm::object::ELF32LE>(__VA_ARGS__); \
+ break; \
+ case lld::elf::ELF32BEKind: \
+ f<llvm::object::ELF32BE>(__VA_ARGS__); \
+ break; \
+ case lld::elf::ELF64LEKind: \
+ f<llvm::object::ELF64LE>(__VA_ARGS__); \
+ break; \
+ case lld::elf::ELF64BEKind: \
+ f<llvm::object::ELF64BE>(__VA_ARGS__); \
+ break; \
+ default: \
+ llvm_unreachable("unknown ctx.arg.ekind"); \
+ } \
+ } while (0)
#endif
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c3c0578..2b0e097 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1586,9 +1586,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
if (isInt<32>(reloc.sym->getVA(ctx, reloc.addend)))
return false;
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, elem.inputSec,
- reloc.offset,
- DynamicReloc::AddendOnlyWithTargetVA,
- *reloc.sym, reloc.addend, R_ABS});
+ reloc.offset, false, *reloc.sym,
+ reloc.addend, R_ABS});
return true;
});
changed |= (it != part.relrAuthDyn->relocs.end());
diff --git a/lld/test/COFF/alternatename-alias.s b/lld/test/COFF/alternatename-alias.s
new file mode 100644
index 0000000..bd0a861
--- /dev/null
+++ b/lld/test/COFF/alternatename-alias.s
@@ -0,0 +1,15 @@
+// REQUIRES: x86
+
+// Check that a weak alias can be used as an alternate name target.
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: lld-link -dll -noentry %t.obj -alternatename:sym=altsym
+
+ .data
+ .rva sym
+
+ .weak altsym
+ .set altsym,a
+
+ .globl a
+a:
+ .word 1
diff --git a/lld/test/COFF/alternatename-antidep.s b/lld/test/COFF/alternatename-antidep.s
new file mode 100644
index 0000000..1188a9b
--- /dev/null
+++ b/lld/test/COFF/alternatename-antidep.s
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+
+// Check that an anti-dependency alias can't be used as an alternate name target.
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: not lld-link -dll -noentry %t.obj -alternatename:sym=altsym 2>&1 | FileCheck %s
+// CHECK: error: undefined symbol: sym
+
+ .data
+ .rva sym
+
+ .weak_anti_dep altsym
+ .set altsym,a
+
+ .globl a
+a:
+ .word 1
diff --git a/lld/test/COFF/alternatename-lib.s b/lld/test/COFF/alternatename-lib.s
new file mode 100644
index 0000000..206fe6b
--- /dev/null
+++ b/lld/test/COFF/alternatename-lib.s
@@ -0,0 +1,43 @@
+// REQUIRES: x86
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows refab.s -o refab.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows aa.s -o aa.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows b.s -o b.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows antidep.s -o antidep.obj
+// RUN: llvm-lib -out:aa.lib aa.obj
+// RUN: llvm-lib -out:b.lib b.obj
+
+// Check that -alternatename with an undefined target does not prevent the symbol from being resolved to a library,
+// once another alternate name is resolved and pulls in the source symbol.
+// RUN: lld-link -out:out.dll -dll -noentry -machine:amd64 refab.obj aa.lib -alternatename:a=aa -alternatename:b=undef
+
+// Check that -alternatename with an anti-dependency target does not prevent the symbol from being resolved to a library,
+// after another alternate name is resolved and pulls in the source symbol.
+// RUN: lld-link -out:out2.dll -dll -noentry -machine:amd64 antidep.obj refab.obj aa.lib -alternatename:a=aa -alternatename:b=u
+
+#--- refab.s
+ .data
+ .rva a
+ .rva b
+
+#--- aa.s
+ .globl aa
+aa:
+ .word 1
+
+ .section .drectve, "yn"
+ .ascii "/defaultlib:b.lib"
+
+#--- b.s
+ .globl b
+b:
+ .word 2
+
+#--- antidep.s
+ .weak_anti_dep u
+ .set u,d
+
+ .globl d
+d:
+ .word 3
diff --git a/lld/test/COFF/arm64ec-altnames.s b/lld/test/COFF/arm64ec-altnames.s
index b2abb24..cca778a 100644
--- a/lld/test/COFF/arm64ec-altnames.s
+++ b/lld/test/COFF/arm64ec-altnames.s
@@ -2,6 +2,7 @@ REQUIRES: aarch64
RUN: split-file %s %t.dir && cd %t.dir
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext.s -o ext.obj
+RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ext-mangled.s -o ext-mangled.obj
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl.s -o impl.obj
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows impl-cpp.s -o impl-cpp.obj
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig.obj
@@ -49,6 +50,20 @@ RUN: lld-link -machine:arm64ec -dll -noentry -out:out4.dll impl-cpp.obj loadconf
RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s
RUN: llvm-readobj --hex-dump=.test out4.dll | FileCheck --check-prefix=TESTSEC %s
+# Check that when both mangled and demangled alternate names are used,
+# only the one whose target is defined is used (the mangled one in this case).
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out5.dll ext-mangled.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
+RUN: llvm-objdump -d out5.dll | FileCheck --check-prefix=DISASM %s
+RUN: llvm-readobj --hex-dump=.test out5.dll | FileCheck --check-prefix=TESTSEC %s
+
+# Check that when both mangled and demangled alternate names are used,
+# only the one whose target is defined is used (the demangled one in this case).
+
+RUN: lld-link -machine:arm64ec -dll -noentry -out:out6.dll ext.obj loadconfig.obj "-alternatename:#func=#altsym" -alternatename:func=altsym
+RUN: llvm-objdump -d out6.dll | FileCheck --check-prefix=DISASM2 %s
+RUN: llvm-readobj --hex-dump=.test out6.dll | FileCheck --check-prefix=TESTSEC2 %s
+
#--- ext.s
.weak_anti_dep func
.set func, "#func"
@@ -70,6 +85,30 @@ altsym:
mov w0, #1
ret
+#--- ext-mangled.s
+ .weak_anti_dep func
+.set func, "#func"
+ .weak_anti_dep "#func"
+.set "#func", thunksym
+
+ .section .test, "r"
+ .rva func
+ .rva "#func"
+
+ .section .thnk,"xr",discard,thunksym
+thunksym:
+ mov w0, #2
+ ret
+
+ .section .text,"xr",discard,"#altsym"
+ .globl "#altsym"
+"#altsym":
+ mov w0, #1
+ ret
+
+ .weak_anti_dep altsym
+ .set altsym,"#altsym"
+
#--- impl.s
.weak_anti_dep func
.set func, "#func"
diff --git a/lld/test/COFF/arm64ec-delayimport.test b/lld/test/COFF/arm64ec-delayimport.test
index 1e0bd89..01d4ab8 100644
--- a/lld/test/COFF/arm64ec-delayimport.test
+++ b/lld/test/COFF/arm64ec-delayimport.test
@@ -51,28 +51,28 @@ DISASM-NEXT: 180002016: 48 8d 05 6b 50 00 00 leaq 0x506b(%rip), %rax
DISASM-NEXT: 18000201d: e9 0c 00 00 00 jmp 0x18000202e <.text+0x102e>
DISASM-NEXT: 180002022: 48 8d 05 67 50 00 00 leaq 0x5067(%rip), %rax # 0x180007090
DISASM-NEXT: 180002029: e9 00 00 00 00 jmp 0x18000202e <.text+0x102e>
-DISASM-NEXT: 18000202e: 51 pushq %rcx
-DISASM-NEXT: 18000202f: 52 pushq %rdx
-DISASM-NEXT: 180002030: 41 50 pushq %r8
-DISASM-NEXT: 180002032: 41 51 pushq %r9
-DISASM-NEXT: 180002034: 48 83 ec 48 subq $0x48, %rsp
-DISASM-NEXT: 180002038: 66 0f 7f 04 24 movdqa %xmm0, (%rsp)
-DISASM-NEXT: 18000203d: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
-DISASM-NEXT: 180002043: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
-DISASM-NEXT: 180002049: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
-DISASM-NEXT: 18000204f: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180002052: 48 8d 0d a7 21 00 00 leaq 0x21a7(%rip), %rcx # 0x180004200
-DISASM-NEXT: 180002059: e8 aa ef ff ff callq 0x180001008 <.text+0x8>
-DISASM-NEXT: 18000205e: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
-DISASM-NEXT: 180002063: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
-DISASM-NEXT: 180002069: 66 0f 6f 54 24 20 movdqa 0x20(%rsp), %xmm2
-DISASM-NEXT: 18000206f: 66 0f 6f 5c 24 30 movdqa 0x30(%rsp), %xmm3
-DISASM-NEXT: 180002075: 48 83 c4 48 addq $0x48, %rsp
-DISASM-NEXT: 180002079: 41 59 popq %r9
-DISASM-NEXT: 18000207b: 41 58 popq %r8
-DISASM-NEXT: 18000207d: 5a popq %rdx
-DISASM-NEXT: 18000207e: 59 popq %rcx
-DISASM-NEXT: 18000207f: ff e0 jmpq *%rax
+DISASM-NEXT: 18000202e: 48 89 4c 24 08 movq %rcx, 0x8(%rsp)
+DISASM-NEXT: 180002033: 48 89 54 24 10 movq %rdx, 0x10(%rsp)
+DISASM-NEXT: 180002038: 4c 89 44 24 18 movq %r8, 0x18(%rsp)
+DISASM-NEXT: 18000203d: 4c 89 4c 24 20 movq %r9, 0x20(%rsp)
+DISASM-NEXT: 180002042: 48 83 ec 68 subq $0x68, %rsp
+DISASM-NEXT: 180002046: 66 0f 7f 44 24 20 movdqa %xmm0, 0x20(%rsp)
+DISASM-NEXT: 18000204c: 66 0f 7f 4c 24 30 movdqa %xmm1, 0x30(%rsp)
+DISASM-NEXT: 180002052: 66 0f 7f 54 24 40 movdqa %xmm2, 0x40(%rsp)
+DISASM-NEXT: 180002058: 66 0f 7f 5c 24 50 movdqa %xmm3, 0x50(%rsp)
+DISASM-NEXT: 18000205e: 48 8b d0 movq %rax, %rdx
+DISASM-NEXT: 180002061: 48 8d 0d 90 21 00 00 leaq 0x2190(%rip), %rcx # 0x1800041f8
+DISASM-NEXT: 180002068: e8 9b ef ff ff callq 0x180001008 <.text+0x8>
+DISASM-NEXT: 18000206d: 66 0f 6f 44 24 20 movdqa 0x20(%rsp), %xmm0
+DISASM-NEXT: 180002073: 66 0f 6f 4c 24 30 movdqa 0x30(%rsp), %xmm1
+DISASM-NEXT: 180002079: 66 0f 6f 54 24 40 movdqa 0x40(%rsp), %xmm2
+DISASM-NEXT: 18000207f: 66 0f 6f 5c 24 50 movdqa 0x50(%rsp), %xmm3
+DISASM-NEXT: 180002085: 48 8b 4c 24 70 movq 0x70(%rsp), %rcx
+DISASM-NEXT: 18000208a: 48 8b 54 24 78 movq 0x78(%rsp), %rdx
+DISASM-NEXT: 18000208f: 4c 8b 84 24 80 00 00 00 movq 0x80(%rsp), %r8
+DISASM-NEXT: 180002097: 4c 8b 8c 24 88 00 00 00 movq 0x88(%rsp), %r9
+DISASM-NEXT: 18000209f: 48 83 c4 68 addq $0x68, %rsp
+DISASM-NEXT: 1800020a3: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: CHPEMetadata [
@@ -85,7 +85,7 @@ IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x7080
IMPORTS-NEXT: ImportAddressTable: 0x7088
-IMPORTS-NEXT: ImportNameTable: 0x4240
+IMPORTS-NEXT: ImportNameTable: 0x4238
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -141,7 +141,7 @@ RELOC-NEXT: Address: 0x6008
RELOC-NEXT: }
RUN: llvm-readobj --hex-dump=.pdata out.dll | FileCheck --check-prefix=PDATA %s
-PDATA: 0x180008000 2e200000 81200000 18400000
+PDATA: 0x180008000 2e200000 a5200000 18400000
Verify that a demangled version of __delayLoadHelper2 can be used.
diff --git a/lld/test/COFF/arm64x-delayimport.test b/lld/test/COFF/arm64x-delayimport.test
index 56923ef..2a68bce 100644
--- a/lld/test/COFF/arm64x-delayimport.test
+++ b/lld/test/COFF/arm64x-delayimport.test
@@ -21,7 +21,7 @@ IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
IMPORTS-NEXT: ImportAddressTable: 0x6088
-IMPORTS-NEXT: ImportNameTable: 0x4390
+IMPORTS-NEXT: ImportNameTable: 0x4388
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -35,7 +35,7 @@ IMPORTS-NEXT: Name: test.dll
IMPORTS-NEXT: Attributes: 0x1
IMPORTS-NEXT: ModuleHandle: 0x6080
IMPORTS-NEXT: ImportAddressTable: 0x6098
-IMPORTS-NEXT: ImportNameTable: 0x43A0
+IMPORTS-NEXT: ImportNameTable: 0x4398
IMPORTS-NEXT: BoundDelayImportTable: 0x0
IMPORTS-NEXT: UnloadDelayImportTable: 0x0
IMPORTS-NEXT: Import {
@@ -73,7 +73,7 @@ DISASM-NEXT: 180001040: ad0497e4 stp q4, q5, [sp, #0x90]
DISASM-NEXT: 180001044: ad059fe6 stp q6, q7, [sp, #0xb0]
DISASM-NEXT: 180001048: aa1103e1 mov x1, x17
DISASM-NEXT: 18000104c: f0000000 adrp x0, 0x180004000
-DISASM-NEXT: 180001050: 910d4000 add x0, x0, #0x350
+DISASM-NEXT: 180001050: 910d2000 add x0, x0, #0x348
DISASM-NEXT: 180001054: 97ffffeb bl 0x180001000 <.text>
DISASM-NEXT: 180001058: aa0003f0 mov x16, x0
DISASM-NEXT: 18000105c: ad459fe6 ldp q6, q7, [sp, #0xb0]
@@ -105,28 +105,28 @@ DISASM-NEXT: ...
DISASM-NEXT: 180003000: ff 25 92 30 00 00 jmpq *0x3092(%rip) # 0x180006098
DISASM-NEXT: 180003006: 48 8d 05 8b 30 00 00 leaq 0x308b(%rip), %rax # 0x180006098
DISASM-NEXT: 18000300d: e9 00 00 00 00 jmp 0x180003012 <.text+0x2012>
-DISASM-NEXT: 180003012: 51 pushq %rcx
-DISASM-NEXT: 180003013: 52 pushq %rdx
-DISASM-NEXT: 180003014: 41 50 pushq %r8
-DISASM-NEXT: 180003016: 41 51 pushq %r9
-DISASM-NEXT: 180003018: 48 83 ec 48 subq $0x48, %rsp
-DISASM-NEXT: 18000301c: 66 0f 7f 04 24 movdqa %xmm0, (%rsp)
-DISASM-NEXT: 180003021: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
-DISASM-NEXT: 180003027: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
-DISASM-NEXT: 18000302d: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
-DISASM-NEXT: 180003033: 48 8b d0 movq %rax, %rdx
-DISASM-NEXT: 180003036: 48 8d 0d 13 13 00 00 leaq 0x1313(%rip), %rcx # 0x180004350
-DISASM-NEXT: 18000303d: e8 c6 ef ff ff callq 0x180002008 <.text+0x1008>
-DISASM-NEXT: 180003042: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
-DISASM-NEXT: 180003047: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
-DISASM-NEXT: 18000304d: 66 0f 6f 54 24 20 movdqa 0x20(%rsp), %xmm2
-DISASM-NEXT: 180003053: 66 0f 6f 5c 24 30 movdqa 0x30(%rsp), %xmm3
-DISASM-NEXT: 180003059: 48 83 c4 48 addq $0x48, %rsp
-DISASM-NEXT: 18000305d: 41 59 popq %r9
-DISASM-NEXT: 18000305f: 41 58 popq %r8
-DISASM-NEXT: 180003061: 5a popq %rdx
-DISASM-NEXT: 180003062: 59 popq %rcx
-DISASM-NEXT: 180003063: ff e0 jmpq *%rax
+DISASM-NEXT: 180003012: 48 89 4c 24 08 movq %rcx, 0x8(%rsp)
+DISASM-NEXT: 180003017: 48 89 54 24 10 movq %rdx, 0x10(%rsp)
+DISASM-NEXT: 18000301c: 4c 89 44 24 18 movq %r8, 0x18(%rsp)
+DISASM-NEXT: 180003021: 4c 89 4c 24 20 movq %r9, 0x20(%rsp)
+DISASM-NEXT: 180003026: 48 83 ec 68 subq $0x68, %rsp
+DISASM-NEXT: 18000302a: 66 0f 7f 44 24 20 movdqa %xmm0, 0x20(%rsp)
+DISASM-NEXT: 180003030: 66 0f 7f 4c 24 30 movdqa %xmm1, 0x30(%rsp)
+DISASM-NEXT: 180003036: 66 0f 7f 54 24 40 movdqa %xmm2, 0x40(%rsp)
+DISASM-NEXT: 18000303c: 66 0f 7f 5c 24 50 movdqa %xmm3, 0x50(%rsp)
+DISASM-NEXT: 180003042: 48 8b d0 movq %rax, %rdx
+DISASM-NEXT: 180003045: 48 8d 0d fc 12 00 00 leaq 0x12fc(%rip), %rcx # 0x180004348
+DISASM-NEXT: 18000304c: e8 b7 ef ff ff callq 0x180002008 <.text+0x1008>
+DISASM-NEXT: 180003051: 66 0f 6f 44 24 20 movdqa 0x20(%rsp), %xmm0
+DISASM-NEXT: 180003057: 66 0f 6f 4c 24 30 movdqa 0x30(%rsp), %xmm1
+DISASM-NEXT: 18000305d: 66 0f 6f 54 24 40 movdqa 0x40(%rsp), %xmm2
+DISASM-NEXT: 180003063: 66 0f 6f 5c 24 50 movdqa 0x50(%rsp), %xmm3
+DISASM-NEXT: 180003069: 48 8b 4c 24 70 movq 0x70(%rsp), %rcx
+DISASM-NEXT: 18000306e: 48 8b 54 24 78 movq 0x78(%rsp), %rdx
+DISASM-NEXT: 180003073: 4c 8b 84 24 80 00 00 00 movq 0x80(%rsp), %r8
+DISASM-NEXT: 18000307b: 4c 8b 8c 24 88 00 00 00 movq 0x88(%rsp), %r9
+DISASM-NEXT: 180003083: 48 83 c4 68 addq $0x68, %rsp
+DISASM-NEXT: 180003087: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out.dll | FileCheck --check-prefix=LOADCFG %s
LOADCFG: AuxiliaryDelayloadIAT: 0x5000
@@ -230,7 +230,7 @@ EC-IMPORTS-NEXT: Name: test.dll
EC-IMPORTS-NEXT: Attributes: 0x1
EC-IMPORTS-NEXT: ModuleHandle: 0x6080
EC-IMPORTS-NEXT: ImportAddressTable: 0x6088
-EC-IMPORTS-NEXT: ImportNameTable: 0x4388
+EC-IMPORTS-NEXT: ImportNameTable: 0x4380
EC-IMPORTS-NEXT: BoundDelayImportTable: 0x0
EC-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
EC-IMPORTS-NEXT: }
@@ -243,7 +243,7 @@ EC-IMPORTS-NEXT: Name: test.dll
EC-IMPORTS-NEXT: Attributes: 0x1
EC-IMPORTS-NEXT: ModuleHandle: 0x6080
EC-IMPORTS-NEXT: ImportAddressTable: 0x6090
-EC-IMPORTS-NEXT: ImportNameTable: 0x4390
+EC-IMPORTS-NEXT: ImportNameTable: 0x4388
EC-IMPORTS-NEXT: BoundDelayImportTable: 0x0
EC-IMPORTS-NEXT: UnloadDelayImportTable: 0x0
EC-IMPORTS-NEXT: Import {
@@ -279,28 +279,28 @@ EC-DISASM-NEXT: ...
EC-DISASM-NEXT: 180003000: ff 25 8a 30 00 00 jmpq *0x308a(%rip) # 0x180006090
EC-DISASM-NEXT: 180003006: 48 8d 05 83 30 00 00 leaq 0x3083(%rip), %rax # 0x180006090
EC-DISASM-NEXT: 18000300d: e9 00 00 00 00 jmp 0x180003012 <.text+0x2012>
-EC-DISASM-NEXT: 180003012: 51 pushq %rcx
-EC-DISASM-NEXT: 180003013: 52 pushq %rdx
-EC-DISASM-NEXT: 180003014: 41 50 pushq %r8
-EC-DISASM-NEXT: 180003016: 41 51 pushq %r9
-EC-DISASM-NEXT: 180003018: 48 83 ec 48 subq $0x48, %rsp
-EC-DISASM-NEXT: 18000301c: 66 0f 7f 04 24 movdqa %xmm0, (%rsp)
-EC-DISASM-NEXT: 180003021: 66 0f 7f 4c 24 10 movdqa %xmm1, 0x10(%rsp)
-EC-DISASM-NEXT: 180003027: 66 0f 7f 54 24 20 movdqa %xmm2, 0x20(%rsp)
-EC-DISASM-NEXT: 18000302d: 66 0f 7f 5c 24 30 movdqa %xmm3, 0x30(%rsp)
-EC-DISASM-NEXT: 180003033: 48 8b d0 movq %rax, %rdx
-EC-DISASM-NEXT: 180003036: 48 8d 0d 0b 13 00 00 leaq 0x130b(%rip), %rcx # 0x180004348
-EC-DISASM-NEXT: 18000303d: e8 c6 ef ff ff callq 0x180002008 <.text+0x1008>
-EC-DISASM-NEXT: 180003042: 66 0f 6f 04 24 movdqa (%rsp), %xmm0
-EC-DISASM-NEXT: 180003047: 66 0f 6f 4c 24 10 movdqa 0x10(%rsp), %xmm1
-EC-DISASM-NEXT: 18000304d: 66 0f 6f 54 24 20 movdqa 0x20(%rsp), %xmm2
-EC-DISASM-NEXT: 180003053: 66 0f 6f 5c 24 30 movdqa 0x30(%rsp), %xmm3
-EC-DISASM-NEXT: 180003059: 48 83 c4 48 addq $0x48, %rsp
-EC-DISASM-NEXT: 18000305d: 41 59 popq %r9
-EC-DISASM-NEXT: 18000305f: 41 58 popq %r8
-EC-DISASM-NEXT: 180003061: 5a popq %rdx
-EC-DISASM-NEXT: 180003062: 59 popq %rcx
-EC-DISASM-NEXT: 180003063: ff e0 jmpq *%rax
+EC-DISASM-NEXT: 180003012: 48 89 4c 24 08 movq %rcx, 0x8(%rsp)
+EC-DISASM-NEXT: 180003017: 48 89 54 24 10 movq %rdx, 0x10(%rsp)
+EC-DISASM-NEXT: 18000301c: 4c 89 44 24 18 movq %r8, 0x18(%rsp)
+EC-DISASM-NEXT: 180003021: 4c 89 4c 24 20 movq %r9, 0x20(%rsp)
+EC-DISASM-NEXT: 180003026: 48 83 ec 68 subq $0x68, %rsp
+EC-DISASM-NEXT: 18000302a: 66 0f 7f 44 24 20 movdqa %xmm0, 0x20(%rsp)
+EC-DISASM-NEXT: 180003030: 66 0f 7f 4c 24 30 movdqa %xmm1, 0x30(%rsp)
+EC-DISASM-NEXT: 180003036: 66 0f 7f 54 24 40 movdqa %xmm2, 0x40(%rsp)
+EC-DISASM-NEXT: 18000303c: 66 0f 7f 5c 24 50 movdqa %xmm3, 0x50(%rsp)
+EC-DISASM-NEXT: 180003042: 48 8b d0 movq %rax, %rdx
+EC-DISASM-NEXT: 180003045: 48 8d 0d f4 12 00 00 leaq 0x12f4(%rip), %rcx # 0x180004340
+EC-DISASM-NEXT: 18000304c: e8 b7 ef ff ff callq 0x180002008 <.text+0x1008>
+EC-DISASM-NEXT: 180003051: 66 0f 6f 44 24 20 movdqa 0x20(%rsp), %xmm0
+EC-DISASM-NEXT: 180003057: 66 0f 6f 4c 24 30 movdqa 0x30(%rsp), %xmm1
+EC-DISASM-NEXT: 18000305d: 66 0f 6f 54 24 40 movdqa 0x40(%rsp), %xmm2
+EC-DISASM-NEXT: 180003063: 66 0f 6f 5c 24 50 movdqa 0x50(%rsp), %xmm3
+EC-DISASM-NEXT: 180003069: 48 8b 4c 24 70 movq 0x70(%rsp), %rcx
+EC-DISASM-NEXT: 18000306e: 48 8b 54 24 78 movq 0x78(%rsp), %rdx
+EC-DISASM-NEXT: 180003073: 4c 8b 84 24 80 00 00 00 movq 0x80(%rsp), %r8
+EC-DISASM-NEXT: 18000307b: 4c 8b 8c 24 88 00 00 00 movq 0x88(%rsp), %r9
+EC-DISASM-NEXT: 180003083: 48 83 c4 68 addq $0x68, %rsp
+EC-DISASM-NEXT: 180003087: ff e0 jmpq *%rax
RUN: llvm-readobj --coff-load-config out-ec.dll | FileCheck --check-prefix=EC-LOADCFG %s
EC-LOADCFG: AuxiliaryDelayloadIAT: 0x5000
diff --git a/lld/test/COFF/delayimports.test b/lld/test/COFF/delayimports.test
index f410eef..ed074f4 100644
--- a/lld/test/COFF/delayimports.test
+++ b/lld/test/COFF/delayimports.test
@@ -10,7 +10,7 @@ IMPORT-NEXT: Name: std64.dll
IMPORT-NEXT: Attributes: 0x1
IMPORT-NEXT: ModuleHandle: 0x3018
IMPORT-NEXT: ImportAddressTable: 0x3020
-IMPORT-NEXT: ImportNameTable: 0x2050
+IMPORT-NEXT: ImportNameTable: 0x2048
IMPORT-NEXT: BoundDelayImportTable: 0x0
IMPORT-NEXT: UnloadDelayImportTable: 0x0
IMPORT-NEXT: Import {
@@ -44,22 +44,18 @@ BASEREL-NEXT: }
UNWIND: UnwindInformation [
UNWIND-NEXT: RuntimeFunction {
UNWIND-NEXT: StartAddress: (0x14000108A)
-UNWIND-NEXT: EndAddress: (0x1400010DD)
+UNWIND-NEXT: EndAddress: (0x140001101)
UNWIND-NEXT: UnwindInfoAddress: (0x140002000)
UNWIND-NEXT: UnwindInfo {
UNWIND-NEXT: Version: 1
UNWIND-NEXT: Flags [ (0x0)
UNWIND-NEXT: ]
-UNWIND-NEXT: PrologSize: 10
+UNWIND-NEXT: PrologSize: 24
UNWIND-NEXT: FrameRegister: -
UNWIND-NEXT: FrameOffset: -
-UNWIND-NEXT: UnwindCodeCount: 5
+UNWIND-NEXT: UnwindCodeCount: 1
UNWIND-NEXT: UnwindCodes [
-UNWIND-NEXT: 0x0A: ALLOC_SMALL size=72
-UNWIND-NEXT: 0x06: ALLOC_SMALL size=8
-UNWIND-NEXT: 0x04: ALLOC_SMALL size=8
-UNWIND-NEXT: 0x02: ALLOC_SMALL size=8
-UNWIND-NEXT: 0x01: ALLOC_SMALL size=8
+UNWIND-NEXT: 0x18: ALLOC_SMALL size=104
UNWIND-NEXT: ]
UNWIND-NEXT: }
UNWIND-NEXT: }
diff --git a/lld/test/COFF/delayimporttables.yaml b/lld/test/COFF/delayimporttables.yaml
index cf54c0a..ff66812 100644
--- a/lld/test/COFF/delayimporttables.yaml
+++ b/lld/test/COFF/delayimporttables.yaml
@@ -15,7 +15,7 @@
# CHECK-NEXT: Attributes: 0x1
# CHECK-NEXT: ModuleHandle: 0x3000
# CHECK-NEXT: ImportAddressTable: 0x3010
-# CHECK-NEXT: ImportNameTable: 0x2070
+# CHECK-NEXT: ImportNameTable: 0x2068
# CHECK-NEXT: BoundDelayImportTable: 0x0
# CHECK-NEXT: UnloadDelayImportTable: 0x0
# CHECK-NEXT: Import {
@@ -32,16 +32,16 @@
# CHECK-NEXT: Attributes: 0x1
# CHECK-NEXT: ModuleHandle: 0x3008
# CHECK-NEXT: ImportAddressTable: 0x3028
-# CHECK-NEXT: ImportNameTable: 0x2088
+# CHECK-NEXT: ImportNameTable: 0x2080
# CHECK-NEXT: BoundDelayImportTable: 0x0
# CHECK-NEXT: UnloadDelayImportTable: 0x0
# CHECK-NEXT: Import {
# CHECK-NEXT: Symbol: left (0)
-# CHECK-NEXT: Address: 0x1400010B8
+# CHECK-NEXT: Address: 0x1400010DC
# CHECK-NEXT: }
# CHECK-NEXT: Import {
# CHECK-NEXT: Symbol: right (0)
-# CHECK-NEXT: Address: 0x1400010C4
+# CHECK-NEXT: Address: 0x1400010E8
# CHECK-NEXT: }
# CHECK-NEXT: }
diff --git a/lld/test/COFF/embed-bitcode.test b/lld/test/COFF/embed-bitcode.test
new file mode 100644
index 0000000..10f88c5
--- /dev/null
+++ b/lld/test/COFF/embed-bitcode.test
@@ -0,0 +1,30 @@
+# RUN: yaml2obj %s -o %t.obj
+# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj
+# RUN: llvm-readobj -S %t.exe | FileCheck %s
+
+# CHECK-NOT: Name: .llvmbc
+# CHECK-NOT: Name: .llvmcmd
+
+--- !COFF
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ SectionData: "C3"
+ - Name: .llvmbc
+ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
+ SectionData: "4243C0DE"
+ - Name: .llvmcmd
+ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
+ SectionData: "2D63633100"
+
+symbols:
+ - Name: main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
diff --git a/lld/test/COFF/giats.s b/lld/test/COFF/giats.s
index f870429..c044210 100644
--- a/lld/test/COFF/giats.s
+++ b/lld/test/COFF/giats.s
@@ -37,14 +37,14 @@
# DELAY-CHECK: ImageBase: 0x140000000
# DELAY-CHECK: LoadConfig [
-# DELAY-CHECK: GuardCFFunctionTable: 0x140002124
+# DELAY-CHECK: GuardCFFunctionTable: 0x14000211C
# DELAY-CHECK: GuardCFFunctionCount: 2
# DELAY-CHECK: GuardFlags [ (0x10500)
# DELAY-CHECK: CF_FUNCTION_TABLE_PRESENT (0x400)
# DELAY-CHECK: CF_INSTRUMENTED (0x100)
# DELAY-CHECK: CF_LONGJUMP_TABLE_PRESENT (0x10000)
# DELAY-CHECK: ]
-# DELAY-CHECK: GuardAddressTakenIatEntryTable: 0x14000212C
+# DELAY-CHECK: GuardAddressTakenIatEntryTable: 0x140002124
# DELAY-CHECK: GuardAddressTakenIatEntryCount: 1
# DELAY-CHECK: ]
# DELAY-CHECK: GuardFidTable [
diff --git a/lld/test/COFF/nodefaultlib.test b/lld/test/COFF/nodefaultlib.test
index ceeb1f3..fbf6b43 100644
--- a/lld/test/COFF/nodefaultlib.test
+++ b/lld/test/COFF/nodefaultlib.test
@@ -1,5 +1,6 @@
-# RUN: cp %p/Inputs/hello64.obj %T
-# RUN: cp %p/Inputs/std64.lib %T
+# RUN: mkdir -p %t.dir
+# RUN: cp %p/Inputs/hello64.obj %t.dir
+# RUN: cp %p/Inputs/std64.lib %t.dir
# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console \
# RUN: hello64.obj /defaultlib:std64.lib >& %t.log
@@ -9,12 +10,12 @@
# RUN: hello64 /defaultlib:std64.lib >& %t.log
# RUN: FileCheck -DMSG=%errc_ENOENT -check-prefix=CHECK2 %s < %t.log
-# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
+# RUN: lld-link /libpath:%t.dir /out:%t.exe /entry:main \
# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib \
# RUN: /nodefaultlib:std64.lib >& %t.log || true
# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
-# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
+# RUN: lld-link /libpath:%t.dir /out:%t.exe /entry:main \
# RUN: /subsystem:console hello64.obj /defaultlib:std64 \
# RUN: /nodefaultlib:std64.lib >& %t.log || true
# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
@@ -24,10 +25,10 @@ CHECK2: error: could not open 'hello64': [[MSG]]
CHECK3: error: undefined symbol: MessageBoxA
CHECK3-NEXT: >>> referenced by {{.*}}hello64.obj:(main)
-# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
+# RUN: lld-link /libpath:%t.dir /out:%t.exe /entry:main \
# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib
-# RUN: env LIB=%T lld-link /out:%t.exe /entry:main \
+# RUN: env LIB=%t.dir lld-link /out:%t.exe /entry:main \
# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib
MSVC stamps uppercase references in OBJ directives, thus ensure that passing lowercase 'libcmt' and 'oldnames' to /nodefaultlib works.
@@ -37,11 +38,11 @@ MSVC stamps uppercase references in OBJ directives, thus ensure that passing low
UPPERCASE-NOT: OLDNAMES
UPPERCASE-NOT: LIBCMT
-# RUN: yaml2obj -o %T/defaultlib.obj %p/Inputs/defaultlib.yaml
+# RUN: yaml2obj -o %t.dir/defaultlib.obj %p/Inputs/defaultlib.yaml
# RUN: mkdir -p %t.dir/sysroot/VC/Tools/MSVC/1.1.1.1/lib/x64
# RUN: cp %p/Inputs/ret42.lib %t.dir/sysroot/VC/Tools/MSVC/1.1.1.1/lib/x64/default.lib
-# RUN: lld-link /winsysroot:%t.dir/sysroot /out:%t.exe /entry:main /subsystem:console %T/defaultlib.obj
-# RUN: not lld-link /winsysroot:%t.dir/sysroot /out:%t.exe /entry:main /subsystem:console /nodefaultlib:default.lib %T/defaultlib.obj 2>&1 | FileCheck -check-prefix=CHECK4 %s
+# RUN: lld-link /winsysroot:%t.dir/sysroot /out:%t.exe /entry:main /subsystem:console %t.dir/defaultlib.obj
+# RUN: not lld-link /winsysroot:%t.dir/sysroot /out:%t.exe /entry:main /subsystem:console /nodefaultlib:default.lib %t.dir/defaultlib.obj 2>&1 | FileCheck -check-prefix=CHECK4 %s
CHECK4: error: <root>: undefined symbol: main
diff --git a/lld/test/COFF/pdb-empty-sec.s b/lld/test/COFF/pdb-empty-sec.s
new file mode 100644
index 0000000..0d61447
--- /dev/null
+++ b/lld/test/COFF/pdb-empty-sec.s
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows %s -o %t.obj
+// RUN: lld-link -dll -noentry -debug %t.obj -out:%t.dll
+// RUN: llvm-pdbutil dump -publics %t.pdb | FileCheck %s
+
+// CHECK: Records
+// CHECK-NEXT: 0 | S_PUB32 [size = 20] `func`
+// CHECK-NEXT: flags = none, addr = 0001:0000
+// CHECK-NEXT: 20 | S_PUB32 [size = 20] `sym`
+// CHECK-NEXT: flags = none, addr = 0000:0000
+
+ .globl sym
+ .data
+sym:
+ .text
+ .globl func
+func:
+ ret
diff --git a/lld/test/COFF/pdb-options.test b/lld/test/COFF/pdb-options.test
index 70f6cbf..840040e 100644
--- a/lld/test/COFF/pdb-options.test
+++ b/lld/test/COFF/pdb-options.test
@@ -19,8 +19,10 @@
; If /DEBUG is specified but not /pdb, it uses a default name in the current
; directory. This is a bit hacky since but we need to be IN our test specific
; temporary directory when we run this command or we can't test this
-# RUN: cd %T
-# RUN: lld-link /DEBUG /entry:main /nodefaultlib %t1.obj %t2.obj
-# RUN: ls %t1.pdb
-# RUN: rm %t*
-# RUN: cd %T/..
+# RUN: mkdir -p %t.dir
+# RUN: cp %t1.obj %t.dir/1.obj
+# RUN: cp %t2.obj %t.dir/2.obj
+# RUN: cd %t.dir
+# RUN: lld-link /DEBUG /entry:main /nodefaultlib %t.dir/1.obj %t.dir/2.obj
+# RUN: ls %t.dir/1.pdb
+# RUN: rm -r %t*
diff --git a/lld/test/COFF/pdb-type-server-invalid-signature.yaml b/lld/test/COFF/pdb-type-server-invalid-signature.yaml
index 8f1528f..aedcefa 100644
--- a/lld/test/COFF/pdb-type-server-invalid-signature.yaml
+++ b/lld/test/COFF/pdb-type-server-invalid-signature.yaml
@@ -19,9 +19,10 @@
# VALID-SIGNATURE-NOT: The signature does not match; the file(s) might be out of date
# Test an invalid path reference to a PDB type server; as a fallback LLD should try to load the PDB in the same path as the OBJ
-# RUN: yaml2obj %S/Inputs/pdb-type-server-invalid-path.yaml -o %t3.obj
-# RUN: cp %S/Inputs/pdb-diff-cl.pdb %T
-# RUN: lld-link %t3.obj -out:%t3.exe -debug -pdb:%t3.pdb -nodefaultlib -entry:main 2>&1 | FileCheck -DMSG=%errc_ENOENT %s -check-prefix=INVALID-PATH -allow-empty
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/pdb-type-server-invalid-path.yaml -o %t.dir/3.obj
+# RUN: cp %S/Inputs/pdb-diff-cl.pdb %t.dir/pdb-diff-cl.pdb
+# RUN: lld-link %t.dir/3.obj -out:%t3.exe -debug -pdb:%t3.pdb -nodefaultlib -entry:main 2>&1 | FileCheck -DMSG=%errc_ENOENT %s -check-prefix=INVALID-PATH -allow-empty
# INVALID-PATH-NOT: warning: Cannot use debug info for '{{.*}}3.obj' [LNK4099]
# INVALID-PATH-NOT: failed to load reference 'c:\some_invalid_path_AABB98765\pdb-diff-cl.pdb': [[MSG]]
diff --git a/lld/test/COFF/wrap-lto-2.ll b/lld/test/COFF/wrap-lto-2.ll
index c50feab..4c74ff2 100644
--- a/lld/test/COFF/wrap-lto-2.ll
+++ b/lld/test/COFF/wrap-lto-2.ll
@@ -23,28 +23,30 @@
;; the wrapped symbol, when LTO or ThinLTO is involved. It checks for various
;; combinations of bitcode and regular objects.
+; RUN: mkdir -p %t.dir
+
;; LTO + LTO
-; RUN: lld-link -out:%t.bc-bc.exe %t.main.bc -libpath:%T %t.bc.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.bc-bc.exe %t.main.bc -libpath:%t.dir %t.bc.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.bc-bc.exe | FileCheck %s --check-prefixes=CHECK,JMP
;; LTO + Object
-; RUN: lld-link -out:%t.bc-obj.exe %t.main.bc -libpath:%T %t.obj.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.bc-obj.exe %t.main.bc -libpath:%t.dir %t.obj.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.bc-obj.exe | FileCheck %s --check-prefixes=CHECK,JMP
;; Object + LTO
-; RUN: lld-link -out:%t.obj-bc.exe %t.main.obj -libpath:%T %t.bc.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.obj-bc.exe %t.main.obj -libpath:%t.dir %t.bc.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.obj-bc.exe | FileCheck %s --check-prefixes=CHECK,CALL
;; ThinLTO + ThinLTO
-; RUN: lld-link -out:%t.thin-thin.exe %t.main.thin -libpath:%T %t.thin.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.thin-thin.exe %t.main.thin -libpath:%t.dir %t.thin.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.thin-thin.exe | FileCheck %s --check-prefixes=CHECK,JMP
;; ThinLTO + Object
-; RUN: lld-link -out:%t.thin-obj.exe %t.main.thin -libpath:%T %t.obj.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.thin-obj.exe %t.main.thin -libpath:%t.dir %t.obj.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.thin-obj.exe | FileCheck %s --check-prefixes=CHECK,JMP
;; Object + ThinLTO
-; RUN: lld-link -out:%t.obj-thin.exe %t.main.obj -libpath:%T %t.thin.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
+; RUN: lld-link -out:%t.obj-thin.exe %t.main.obj -libpath:%t.dir %t.thin.lib -entry:entry -subsystem:console -wrap:bar -debug:symtab -lldsavetemps
; RUN: llvm-objdump -d %t.obj-thin.exe | FileCheck %s --check-prefixes=CHECK,CALL
;; Make sure that calls in entry() are not eliminated and that bar is
diff --git a/lld/test/COFF/wrap-with-archive.s b/lld/test/COFF/wrap-with-archive.s
index 96b244a..d8a4fdb 100644
--- a/lld/test/COFF/wrap-with-archive.s
+++ b/lld/test/COFF/wrap-with-archive.s
@@ -6,7 +6,8 @@
// RUN: rm -f %t.lib
// RUN: llvm-ar rcs %t.lib %t.wrap.obj %t.other.obj
-// RUN: lld-link -out:%t.exe %t.main.obj -libpath:%T %t.lib -entry:entry -subsystem:console -wrap:foo
+// RUN: mkdir -p %t.dir
+// RUN: lld-link -out:%t.exe %t.main.obj -libpath:%t.dir %t.lib -entry:entry -subsystem:console -wrap:foo
// Note: No real definition of foo exists here, but that works fine as long
// as there's no actual references to __real_foo.
diff --git a/lld/test/ELF/aarch64-build-attributes-malformed.s b/lld/test/ELF/aarch64-build-attributes-malformed.s
index f40da1a..c8a0fd6 100644
--- a/lld/test/ELF/aarch64-build-attributes-malformed.s
+++ b/lld/test/ELF/aarch64-build-attributes-malformed.s
@@ -1,7 +1,7 @@
# REQUIRES: aarch64
# RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t.o
-# RUN: ld.lld %t.o /dev/null 2>&1 | FileCheck %s
+# RUN: ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
# CHECK: (.ARM.attributes): unexpected end of data at offset 0x3f while reading [0x3d, 0x41)
diff --git a/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s b/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
index a417d89..a33f866 100644
--- a/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
+++ b/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
@@ -1,22 +1,23 @@
# REQUIRES: loongarch
+# RUN: rm -rf %t && split-file %s %t && cd %t
-# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax %s -o %t.32.o
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t.64.o
+# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax a.s -o a.32.o
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax a.s -o a.64.o
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -o %t.32
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -o %t.64
-# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX %s
-# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX %s
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 a.32.o -o a.32
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 a.64.o -o a.64
+# RUN: llvm-objdump -td --no-show-raw-insn a.32 | FileCheck --check-prefixes=RELAX %s
+# RUN: llvm-objdump -td --no-show-raw-insn a.64 | FileCheck --check-prefixes=RELAX %s
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -shared -o %t.32s
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -shared -o %t.64s
-# RUN: llvm-objdump -td --no-show-raw-insn %t.32s | FileCheck --check-prefixes=RELAX %s
-# RUN: llvm-objdump -td --no-show-raw-insn %t.64s | FileCheck --check-prefixes=RELAX %s
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 a.32.o -shared -o a.32s
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 a.64.o -shared -o a.64s
+# RUN: llvm-objdump -td --no-show-raw-insn a.32s | FileCheck --check-prefixes=RELAX %s
+# RUN: llvm-objdump -td --no-show-raw-insn a.64s | FileCheck --check-prefixes=RELAX %s
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x410000 %t.32.o -o %t.32o
-# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x410000 %t.64.o -o %t.64o
-# RUN: llvm-objdump -td --no-show-raw-insn %t.32o | FileCheck --check-prefixes=NORELAX32 %s
-# RUN: llvm-objdump -td --no-show-raw-insn %t.64o | FileCheck --check-prefixes=NORELAX64 %s
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x410000 a.32.o -o a.32o
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x410000 a.64.o -o a.64o
+# RUN: llvm-objdump -td --no-show-raw-insn a.32o | FileCheck --check-prefixes=NORELAX32 %s
+# RUN: llvm-objdump -td --no-show-raw-insn a.64o | FileCheck --check-prefixes=NORELAX64 %s
# RELAX-LABEL: <_start>:
## offset = 0x14000 - 0x10000 = 4096<<2
@@ -49,6 +50,25 @@
# NORELAX64-NEXT: pcalau12i $a0, 1024
# NORELAX64-NEXT: ld.d $a0, $a0, 8
+
+## GOT references with non-zero addends. No relaxation.
+# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax nonzero.s -o nonzero.32.o
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax nonzero.s -o nonzero.64.o
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 nonzero.32.o -o nonzero.32
+# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 nonzero.64.o -o nonzero.64
+# RUN: llvm-objdump -td --no-show-raw-insn nonzero.32 | FileCheck --check-prefixes=NONZERO32 %s
+# RUN: llvm-objdump -td --no-show-raw-insn nonzero.64 | FileCheck --check-prefixes=NONZERO64 %s
+
+# NONZERO32-LABEL: <_start>:
+# NONZERO32-NEXT: 10000: pcalau12i $a0, 4
+# NONZERO32-NEXT: ld.w $a0, $a0, 8
+
+# NONZERO64-LABEL: <_start>:
+# NONZERO64-NEXT: 10000: pcalau12i $a0, 4
+# NONZERO64-NEXT: ld.d $a0, $a0, 12
+
+
+#--- a.s
.section .text
.global _start
_start:
@@ -60,3 +80,14 @@ _start:
.section .data
sym:
.zero 4
+
+
+#--- nonzero.s
+.section .text
+.global _start
+_start:
+ la.got $a0, sym+4
+
+.section .data
+sym:
+ .zero 4
diff --git a/lld/test/wasm/lto/save-temps.ll b/lld/test/wasm/lto/save-temps.ll
index 773978e..e5e96d3 100644
--- a/lld/test/wasm/lto/save-temps.ll
+++ b/lld/test/wasm/lto/save-temps.ll
@@ -1,4 +1,5 @@
-; RUN: cd %T
+; RUN: mkdir -p %t.dir
+; RUN: cd %t.dir
; RUN: rm -f a.out a.out.lto.bc a.out.lto.o
; RUN: llvm-as %s -o %t.o
; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o