summaryrefslogtreecommitdiffstats
path: root/lld/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/InputFiles.cpp8
-rw-r--r--lld/ELF/Symbols.cpp8
-rw-r--r--lld/ELF/Symbols.h6
3 files changed, 19 insertions, 3 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 71d7a585583..bccbddf5058 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -12,6 +12,7 @@
#include "InputSection.h"
#include "Symbols.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Object/IRObjectFile.h"
@@ -498,8 +499,11 @@ BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
}
// FIXME: Expose a thread-local flag for module asm symbols.
- if (GV && GV->isThreadLocal())
- Body->Type = STT_TLS;
+ if (GV) {
+ if (GV->isThreadLocal())
+ Body->Type = STT_TLS;
+ Body->CanOmitFromDynSym = canBeOmittedFromSymbolTable(GV);
+ }
return Body;
}
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 747161efe8b..e6f8842b80d 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -109,6 +109,7 @@ void SymbolBody::init() {
K == DefinedSyntheticKind || K == UndefinedElfKind;
CanKeepUndefined = false;
MustBeInDynSym = false;
+ CanOmitFromDynSym = false;
NeedsCopyOrPltAddr = false;
}
@@ -241,6 +242,9 @@ int SymbolBody::compare(SymbolBody *Other) {
if (IsUsedInRegularObj || Other->IsUsedInRegularObj)
IsUsedInRegularObj = Other->IsUsedInRegularObj = true;
+ if (!CanOmitFromDynSym || !Other->CanOmitFromDynSym)
+ CanOmitFromDynSym = Other->CanOmitFromDynSym = false;
+
if (L != R)
return -1;
if (!isDefined() || isShared() || isWeak())
@@ -360,7 +364,9 @@ bool SymbolBody::includeInDynsym() const {
uint8_t V = getVisibility();
if (V != STV_DEFAULT && V != STV_PROTECTED)
return false;
- return Config->ExportDynamic || Config->Shared;
+ if (!Config->ExportDynamic && !Config->Shared)
+ return false;
+ return !CanOmitFromDynSym;
}
template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 11fcdcb5a45..da2ab59a72c 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -147,6 +147,12 @@ protected:
unsigned IsUsedInRegularObj : 1;
public:
+ // True if this symbol can be omitted from the symbol table if nothing else
+ // requires it to be there. Right now this is only used for linkonce_odr in
+ // LTO, but we could add the feature to ELF. It would be similar to
+ // MachO's .weak_def_can_be_hidden.
+ unsigned CanOmitFromDynSym : 1;
+
// If true, the symbol is added to .dynsym symbol table.
unsigned MustBeInDynSym : 1;
OpenPOWER on IntegriCloud