Implement .weakref.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117911 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 850983f..a0e326d 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -143,6 +143,7 @@
     };
 
     SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+    SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc;
     DenseMap<const MCSymbol *, const MCSymbol *> Renames;
 
     llvm::DenseMap<const MCSectionData*,
@@ -691,7 +692,7 @@
     Symbol = &AliasedSymbol(Target.getSymA()->getSymbol());
     Renamed = Renames.lookup(Symbol);
     if (!Renamed)
-      Renamed = Symbol;
+      Renamed = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
     MCFragment *F = SD.getFragment();
 
@@ -727,6 +728,10 @@
       Value += Layout.getSymbolAddress(&SD) - Layout.getSectionAddress(FSD);
     } else {
       UsedInReloc.insert(Renamed);
+      MCSymbolData &RenamedSD = Asm.getSymbolData(*Renamed);
+      if (RenamedSD.getFlags() & ELF_Other_Weakref) {
+        WeakrefUsedInReloc.insert(Symbol);
+      }
       Index = -1;
     }
     Addend = Value;
@@ -901,6 +906,9 @@
 
 static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
                        bool Used, bool Renamed) {
+  if (Data.getFlags() & ELF_Other_Weakref)
+    return false;
+
   if (Used)
     return true;
 
@@ -963,7 +971,9 @@
          ie = Asm.symbol_end(); it != ie; ++it) {
     const MCSymbol &Symbol = it->getSymbol();
 
-    if (!isInSymtab(Asm, *it, UsedInReloc.count(&Symbol),
+    bool Used = UsedInReloc.count(&Symbol);
+    bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
+    if (!isInSymtab(Asm, *it, Used || WeakrefUsed,
                     Renames.count(&Symbol)))
       continue;
 
@@ -972,6 +982,9 @@
     bool Local = isLocal(*it);
     const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
 
+    if (RefSymbol.isUndefined() && !Used && WeakrefUsed)
+      SetBinding(*it, ELF::STB_WEAK);
+
     if (it->isCommon()) {
       assert(!Local);
       MSD.SectionIndex = ELF::SHN_COMMON;