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()