diff options
Diffstat (limited to 'llvm/lib/MC/MCMachOStreamer.cpp')
| -rw-r--r-- | llvm/lib/MC/MCMachOStreamer.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 4b74c569531..69995fa11d2 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -459,7 +459,30 @@ void MCMachOStreamer::FinishImpl() { // We have to set the fragment atom associations so we can relax properly for // Mach-O. - addFragmentAtoms(); + + // First, scan the symbol table to build a lookup table from fragments to + // defining symbols. + DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap; + for (const MCSymbol &Symbol : getAssembler().symbols()) { + if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.isInSection() && + !Symbol.isVariable()) { + // An atom defining symbol should never be internal to a fragment. + assert(Symbol.getOffset() == 0 && + "Invalid offset in atom defining symbol!"); + DefiningSymbolMap[Symbol.getFragment()] = &Symbol; + } + } + + // Set the fragment atom associations by tracking the last seen atom defining + // symbol. + for (MCSection &Sec : getAssembler()) { + const MCSymbol *CurrentAtom = nullptr; + for (MCFragment &Frag : Sec) { + if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(&Frag)) + CurrentAtom = Symbol; + Frag.setAtom(CurrentAtom); + } + } this->MCObjectStreamer::FinishImpl(); } |

