diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index cc09a494ec9bf..85036135570aa 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -122,7 +122,7 @@ class ConcatInputSection final : public InputSection { void writeTo(uint8_t *buf); void foldIdentical(ConcatInputSection *redundant); - InputSection *canonical() override { + ConcatInputSection *canonical() override { return replacement ? replacement : this; } @@ -131,7 +131,7 @@ class ConcatInputSection final : public InputSection { } // Points to the surviving section after this one is folded by ICF - InputSection *replacement = nullptr; + ConcatInputSection *replacement = nullptr; // Equivalence-class ID for ICF uint64_t icfEqClass[2] = {0, 0}; diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp index 2385a7ca96ed9..c663b21dd7d9c 100644 --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -66,7 +66,7 @@ uint64_t Defined::getVA() const { if (isAbsolute()) return value; - if (!isec->canonical()->isFinal) { + if (!isec->isFinal) { // A target arch that does not use thunks ought never ask for // the address of a function that has not yet been finalized. assert(target->usesThunks()); @@ -77,7 +77,14 @@ uint64_t Defined::getVA() const { // expedient to return a contrived out-of-range address. return TargetInfo::outOfRangeVA; } - return isec->canonical()->getVA(value); + return isec->getVA(value); +} + +void Defined::canonicalize() { + if (compactUnwind) + compactUnwind = compactUnwind->canonical(); + if (isec) + isec = isec->canonical(); } uint64_t DylibSymbol::getVA() const { diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h index 01c60c4d75d79..54f1a35127282 100644 --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -126,6 +126,10 @@ class Defined : public Symbol { uint64_t getVA() const override; + // Ensure this symbol's pointers to InputSections point to their canonical + // copies. + void canonicalize(); + static bool classof(const Symbol *s) { return s->kind() == DefinedKind; } InputSection *isec; diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index c5dc5e6b9e5a7..8a3a4aa658a95 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -924,7 +924,7 @@ void SymtabSection::emitStabs() { } StabsEntry symStab; - symStab.sect = defined->isec->canonical()->parent->index; + symStab.sect = defined->isec->parent->index; symStab.strx = stringTableSection.addString(defined->getName()); symStab.value = defined->getVA(); @@ -1049,7 +1049,7 @@ template void SymtabSectionImpl::writeTo(uint8_t *buf) const { nList->n_value = defined->value; } else { nList->n_type = scope | N_SECT; - nList->n_sect = defined->isec->canonical()->parent->index; + nList->n_sect = defined->isec->parent->index; // For the N_SECT symbol type, n_value is the address of the symbol nList->n_value = defined->getVA(); } diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index c2aef4d554002..4c01398a6d57b 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -671,10 +671,11 @@ void Writer::scanRelocations() { void Writer::scanSymbols() { TimeTraceScope timeScope("Scan symbols"); - for (const Symbol *sym : symtab->getSymbols()) { - if (const auto *defined = dyn_cast(sym)) { + for (Symbol *sym : symtab->getSymbols()) { + if (auto *defined = dyn_cast(sym)) { if (!defined->isLive()) continue; + defined->canonicalize(); if (defined->overridesWeakDef) in.weakBinding->addNonWeakDefinition(defined); if (!defined->isAbsolute() && isCodeSection(defined->isec)) @@ -691,10 +692,14 @@ void Writer::scanSymbols() { for (const InputFile *file : inputFiles) { if (auto *objFile = dyn_cast(file)) for (Symbol *sym : objFile->symbols) { - if (auto *defined = dyn_cast_or_null(sym)) - if (!defined->isExternal() && defined->isLive() && - !defined->isAbsolute() && isCodeSection(defined->isec)) + if (auto *defined = dyn_cast_or_null(sym)) { + if (!defined->isLive()) + continue; + defined->canonicalize(); + if (!defined->isExternal() && !defined->isAbsolute() && + isCodeSection(defined->isec)) in.unwindInfo->addSymbol(defined); + } } } } @@ -1120,6 +1125,8 @@ template void Writer::run() { treatSpecialUndefineds(); if (config->entry && !isa(config->entry)) prepareBranchTarget(config->entry); + // Canonicalization of all pointers to InputSections should be handled by + // these two methods. scanSymbols(); scanRelocations();