Start adding support for internalizing shared libraries.

llvm-svn: 267045
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 0d35938..104411f 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -74,6 +74,17 @@
     saveBCFile(M, ".lto.opt.bc");
 }
 
+static bool shouldInternalize(const SmallPtrSet<GlobalValue *, 8> &Used,
+                              SymbolBody &B, GlobalValue *GV) {
+  if (B.isUsedInRegularObj())
+    return false;
+
+  if (Used.count(GV))
+    return false;
+
+  return !B.includeInDynsym();
+}
+
 void BitcodeCompiler::add(BitcodeFile &F) {
   std::unique_ptr<IRObjectFile> Obj =
       check(IRObjectFile::create(F.MB, Context));
@@ -121,13 +132,8 @@
     // we imported the symbols and satisfied undefined references
     // to it. We can't just change linkage here because otherwise
     // the IRMover will just rename the symbol.
-    // Shared libraries need to be handled slightly differently.
-    // For now, let's be conservative and just never internalize
-    // symbols when creating a shared library.
-    if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() &&
-        !B->MustBeInDynSym)
-      if (!Used.count(GV))
-        InternalizedSyms.insert(GV->getName());
+    if (shouldInternalize(Used, *B, GV))
+      InternalizedSyms.insert(GV->getName());
 
     Keep.push_back(GV);
   }
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index fe0e01e..747161e 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -354,6 +354,15 @@
 #endif
 }
 
+bool SymbolBody::includeInDynsym() const {
+  if (MustBeInDynSym)
+    return true;
+  uint8_t V = getVisibility();
+  if (V != STV_DEFAULT && V != STV_PROTECTED)
+    return false;
+  return Config->ExportDynamic || Config->Shared;
+}
+
 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index fae0e0b..af3cb71 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -130,6 +130,8 @@
   // they are duplicate (conflicting) symbols.
   int compare(SymbolBody *Other);
 
+  bool includeInDynsym() const;
+
 protected:
   SymbolBody(Kind K, StringRef Name, uint8_t Binding, uint8_t StOther,
              uint8_t Type);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 135eb3e..65dde8d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1053,15 +1053,6 @@
   return true;
 }
 
-static bool includeInDynsym(const SymbolBody &B) {
-  if (B.MustBeInDynSym)
-    return true;
-  uint8_t V = B.getVisibility();
-  if (V != STV_DEFAULT && V != STV_PROTECTED)
-    return false;
-  return Config->ExportDynamic || Config->Shared;
-}
-
 // This class knows how to create an output section for a given
 // input section. Output section type is determined by various
 // factors, including input section's sh_flags, sh_type and
@@ -1334,7 +1325,7 @@
     if (Out<ELFT>::SymTab)
       Out<ELFT>::SymTab->addSymbol(Body);
 
-    if (isOutputDynamic() && includeInDynsym(*Body))
+    if (isOutputDynamic() && Body->includeInDynsym())
       Out<ELFT>::DynSymTab->addSymbol(Body);
   }
 
diff --git a/lld/test/ELF/lto/internalize-exportdyn.ll b/lld/test/ELF/lto/internalize-exportdyn.ll
index b9333c8..fd70812 100644
--- a/lld/test/ELF/lto/internalize-exportdyn.ll
+++ b/lld/test/ELF/lto/internalize-exportdyn.ll
@@ -10,10 +10,15 @@
   ret void
 }
 
-define hidden void @foo() {
+define void @foo() {
   ret void
 }
 
-; Check that _start and foo are not internalized.
+define hidden void @bar() {
+  ret void
+}
+
+; Check that _start and foo are not internalized, but bar is.
 ; CHECK: define void @_start()
-; CHECK: define hidden void @foo()
+; CHECK: define void @foo()
+; CHECK: define internal void @bar()