Move ELF to HasReliableSymbolDifference=true. Also take the opportunity to put
symbols defined in merge sections in independent atoms.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114786 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 5dc5ab0..6bf61a1 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -149,20 +149,43 @@
   SetSectionText();
 }
 
+static bool isSymbolLinkerVisible(const MCAssembler &Asm,
+                                  const MCSymbolData &Data) {
+  const MCSymbol &Symbol = Data.getSymbol();
+  // Absolute temporary labels are never visible.
+  if (!Symbol.isInSection())
+    return false;
+
+  if (Asm.getBackend().doesSectionRequireSymbols(Symbol.getSection()))
+    return true;
+
+  if (!Data.isExternal())
+    return false;
+
+  return Asm.isSymbolLinkerVisible(Symbol);
+}
+
 void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
 
+  Symbol->setSection(*CurSection);
+
+  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
+  // We have to create a new fragment if this is an atom defining symbol,
+  // fragments cannot span atoms.
+  if (isSymbolLinkerVisible(getAssembler(), SD))
+    new MCDataFragment(getCurrentSectionData());
+
   // FIXME: This is wasteful, we don't necessarily need to create a data
   // fragment. Instead, we should mark the symbol as pointing into the data
   // fragment if it exists, otherwise we should just queue the label and set its
   // fragment pointer when we emit the next fragment.
   MCDataFragment *F = getOrCreateDataFragment();
-  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+
   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
   SD.setFragment(F);
   SD.setOffset(F->getContents().size());
-
-  Symbol->setSection(*CurSection);
 }
 
 void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
@@ -476,7 +499,37 @@
 }
 
 void MCELFStreamer::Finish() {
-  getAssembler().Finish();
+  // FIXME: We create more atoms than it is necessary. Some relocations to
+  // merge sections can be implemented with section address + offset,
+  // figure out which ones and why.
+
+  // First, scan the symbol table to build a lookup table from fragments to
+  // defining symbols.
+  DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap;
+  for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(),
+         ie = getAssembler().symbol_end(); it != ie; ++it) {
+    if (isSymbolLinkerVisible(getAssembler(), *it) &&
+        it->getFragment()) {
+      // An atom defining symbol should never be internal to a fragment.
+      assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!");
+      DefiningSymbolMap[it->getFragment()] = it;
+    }
+  }
+
+  // Set the fragment atom associations by tracking the last seen atom defining
+  // symbol.
+  for (MCAssembler::iterator it = getAssembler().begin(),
+         ie = getAssembler().end(); it != ie; ++it) {
+    MCSymbolData *CurrentAtom = 0;
+    for (MCSectionData::iterator it2 = it->begin(),
+           ie2 = it->end(); it2 != ie2; ++it2) {
+      if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2))
+        CurrentAtom = SD;
+      it2->setAtom(CurrentAtom);
+    }
+  }
+
+  this->MCObjectStreamer::Finish();
 }
 
 MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,