diff options
Diffstat (limited to 'lld/COFF')
-rw-r--r-- | lld/COFF/DLL.cpp | 58 | ||||
-rw-r--r-- | lld/COFF/Driver.cpp | 23 | ||||
-rw-r--r-- | lld/COFF/InputFiles.cpp | 5 | ||||
-rw-r--r-- | lld/COFF/Options.td | 6 | ||||
-rw-r--r-- | lld/COFF/PDB.cpp | 9 | ||||
-rw-r--r-- | lld/COFF/SymbolTable.cpp | 37 | ||||
-rw-r--r-- | lld/COFF/SymbolTable.h | 3 |
7 files changed, 85 insertions, 56 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(); |