diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -122,7 +122,7 @@ void writeTo(uint8_t *buf); void foldIdentical(ConcatInputSection *redundant); - InputSection *canonical() override { + ConcatInputSection *canonical() override { return replacement ? replacement : this; } @@ -131,7 +131,7 @@ } // 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.h b/lld/MachO/Symbols.h --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -126,6 +126,10 @@ 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/Symbols.cpp b/lld/MachO/Symbols.cpp --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -66,7 +66,7 @@ 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 @@ // 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/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -924,7 +924,7 @@ } 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 @@ 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 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -671,10 +671,11 @@ 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 @@ 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 @@ 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();