ELF2: Implement --as-needed.

This patch adds AsNeeded and IsUsed bool fields to SharedFile. AsNeeded bit
is set if the DSO is enclosed with --as-needed and --no-as-needed. IsUsed
bit is off by default. When we adds a symbol to the symbol table for dynamic
linking, we set its SharedFile's IsUsed bit.

If AsNeeded is set but IsUsed is not set, we don't want to write that
file's SO name to DT_NEEDED field.

http://reviews.llvm.org/D13579

llvm-svn: 249998
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index bfb5dce..bb3cd1a 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -174,6 +174,14 @@
     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
     SymbolBody *Body = File.getSymbolBody(SymIndex);
     uint32_t Type = RI.getType(IsMips64EL);
+
+    // Set "used" bit for --as-needed.
+    if (Body && Body->isUndefined() && !Body->isWeak())
+      if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
+        S->File->IsUsed = true;
+
+    if (Body)
+      Body = Body->repl();
     if (Body) {
       if (Target->relocNeedsPlt(Type, *Body)) {
         if (Body->isInPlt())
@@ -186,12 +194,13 @@
         Out<ELFT>::Got->addEntry(Body);
       }
     }
-    if (canBePreempted(Body)) {
+
+    bool CBP = canBePreempted(Body);
+    if (!CBP && (!Config->Shared || Target->isRelRelative(Type)))
+      continue;
+    if (CBP)
       Body->setUsedInDynamicReloc();
-      Out<ELFT>::RelaDyn->addReloc({C, RI});
-    } else if (Config->Shared && !Target->isRelRelative(Type)) {
-      Out<ELFT>::RelaDyn->addReloc({C, RI});
-    }
+    Out<ELFT>::RelaDyn->addReloc({C, RI});
   }
 }