|
@@ -715,6 +715,63 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
|
|
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
|
|
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
|
|
|
|
+ llvm::GlobalValue *GV, const NamedDecl *D) {
|
|
|
|
+ const llvm::Triple &TT = CGM.getTriple();
|
|
|
|
+ // Only handle ELF for now.
|
|
|
|
+ if (!TT.isOSBinFormatELF())
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ // If this is not an executable, don't assume anything is local.
|
|
|
|
+ const auto &CGOpts = CGM.getCodeGenOpts();
|
|
|
|
+ llvm::Reloc::Model RM = CGOpts.RelocationModel;
|
|
|
|
+ const auto &LOpts = CGM.getLangOpts();
|
|
|
|
+ if (RM != llvm::Reloc::Static && !LOpts.PIE)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ // A definition cannot be preempted from an executable.
|
|
|
|
+ if (!GV->isDeclarationForLinker())
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ // Most PIC code sequences that assume that a symbol is local cannot produce a
|
|
|
|
+ // 0 if it turns out the symbol is undefined. While this is ABI and relocation
|
|
|
|
+ // depended, it seems worth it to handle it here.
|
|
|
|
+ if (RM == llvm::Reloc::PIC_ && GV->hasExternalWeakLinkage())
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ // PPC has no copy relocations and cannot use a plt entry as a symbol address.
|
|
|
|
+ llvm::Triple::ArchType Arch = TT.getArch();
|
|
|
|
+ if (Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
|
|
|
|
+ Arch == llvm::Triple::ppc64le)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ // If we can use copy relocations we can assume it is local.
|
|
|
|
+ if (isa<VarDecl>(D) &&
|
|
|
|
+ (RM == llvm::Reloc::Static || CGOpts.PIECopyRelocations))
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ // If we can use a plt entry as the symbol address we can assume it
|
|
|
|
+ // is local.
|
|
|
|
+ // FIXME: This should work for PIE, but the gold linker doesn't support it.
|
|
|
|
+ if (isa<FunctionDecl>(D) && !CGOpts.NoPLT && RM == llvm::Reloc::Static)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ // Otherwise don't assue it is local.
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CodeGenModule::setDSOLocal(llvm::GlobalValue *GV,
|
|
|
|
+ const NamedDecl *D) const {
|
|
|
|
+ if (shouldAssumeDSOLocal(*this, GV, D))
|
|
|
|
+ GV->setDSOLocal(true);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CodeGenModule::setGVProperties(llvm::GlobalValue *GV,
|
|
|
|
+ const NamedDecl *D) const {
|
|
|
|
+ setGlobalVisibility(GV, D);
|
|
|
|
+ setDSOLocal(GV, D);
|
|
|
|
+}
|
|
|
|
+
|
|
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
|
|
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
|
|
return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
|
|
return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
|
|
.Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
|
|
.Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
|
|
@@ -1172,7 +1229,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
|
void CodeGenModule::SetCommonAttributes(const Decl *D,
|
|
void CodeGenModule::SetCommonAttributes(const Decl *D,
|
|
llvm::GlobalValue *GV) {
|
|
llvm::GlobalValue *GV) {
|
|
if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
|
|
if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
|
|
- setGlobalVisibility(GV, ND);
|
|
|
|
|
|
+ setGVProperties(GV, ND);
|
|
else
|
|
else
|
|
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
|
|
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
|
|
|
|
|
|
@@ -1312,7 +1369,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
|
|
// overridden by a definition.
|
|
// overridden by a definition.
|
|
|
|
|
|
setLinkageForGV(F, FD);
|
|
setLinkageForGV(F, FD);
|
|
- setGlobalVisibility(F, FD);
|
|
|
|
|
|
+ setGVProperties(F, FD);
|
|
|
|
|
|
if (FD->getAttr<PragmaClangTextSectionAttr>()) {
|
|
if (FD->getAttr<PragmaClangTextSectionAttr>()) {
|
|
F->addFnAttr("implicit-section-name");
|
|
F->addFnAttr("implicit-section-name");
|
|
@@ -2639,7 +2696,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
|
|
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
|
|
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
|
|
|
|
|
|
setLinkageForGV(GV, D);
|
|
setLinkageForGV(GV, D);
|
|
- setGlobalVisibility(GV, D);
|
|
|
|
|
|
+ setGVProperties(GV, D);
|
|
|
|
|
|
if (D->getTLSKind()) {
|
|
if (D->getTLSKind()) {
|
|
if (D->getTLSKind() == VarDecl::TLS_Dynamic)
|
|
if (D->getTLSKind() == VarDecl::TLS_Dynamic)
|
|
@@ -3458,7 +3515,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
|
|
setFunctionDLLStorageClass(GD, Fn);
|
|
setFunctionDLLStorageClass(GD, Fn);
|
|
|
|
|
|
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
|
|
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
|
|
- setGlobalVisibility(Fn, D);
|
|
|
|
|
|
+ setGVProperties(Fn, D);
|
|
|
|
|
|
MaybeHandleStaticInExternC(D, Fn);
|
|
MaybeHandleStaticInExternC(D, Fn);
|
|
|
|
|
|
@@ -4054,7 +4111,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
|
|
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
|
|
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
|
|
/*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
|
|
/*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
|
|
if (emitter) emitter->finalize(GV);
|
|
if (emitter) emitter->finalize(GV);
|
|
- setGlobalVisibility(GV, VD);
|
|
|
|
|
|
+ setGVProperties(GV, VD);
|
|
GV->setAlignment(Align.getQuantity());
|
|
GV->setAlignment(Align.getQuantity());
|
|
if (supportsCOMDAT() && GV->isWeakForLinker())
|
|
if (supportsCOMDAT() && GV->isWeakForLinker())
|
|
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
|
|
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
|