-fvisibility=hidden: Hide init symbols, TypeInfos and vtables too if the associated aggregate isn't exported (#3129)

This commit is contained in:
Martin Kinkelin 2019-08-20 01:41:26 +02:00 committed by GitHub
parent ceee37dda2
commit c1725809c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 85 additions and 16 deletions

View file

@ -146,7 +146,7 @@ public:
auto &initZ = ir->getInitSymbol();
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
setLinkage(decl, initGlobal);
setLinkageAndVisibility(decl, initGlobal);
// emit typeinfo
if (!ir->suppressTypeInfo()) {
@ -198,7 +198,7 @@ public:
auto &initZ = ir->getInitSymbol();
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
setLinkage(decl, initGlobal);
setLinkageAndVisibility(decl, initGlobal);
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
defineGlobal(vtbl, ir->getVtblInit(), decl);

View file

@ -1790,12 +1790,12 @@ llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
}
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
Dsymbol *symbolForLinkage) {
Dsymbol *symbolForLinkageAndVisibility) {
assert(global->isDeclaration() && "Global variable already defined");
assert(init);
global->setInitializer(init);
if (symbolForLinkage)
setLinkage(symbolForLinkage, global);
if (symbolForLinkageAndVisibility)
setLinkageAndVisibility(symbolForLinkageAndVisibility, global);
}
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,

View file

@ -254,10 +254,10 @@ llvm::GlobalVariable *declareGlobal(const Loc &loc, llvm::Module &module,
bool isThreadLocal = false);
/// Defines an existing LLVM global, i.e., sets the initial value and finalizes
/// its linkage.
/// its linkage and visibility.
/// Asserts that a global isn't defined multiple times this way.
void defineGlobal(llvm::GlobalVariable *global, llvm::Constant *init,
Dsymbol *symbolForLinkage);
Dsymbol *symbolForLinkageAndVisibility);
/// Declares (if not already declared) & defines an LLVM global.
llvm::GlobalVariable *defineGlobal(const Loc &loc, llvm::Module &module,

View file

@ -16,6 +16,7 @@
#include "dmd/id.h"
#include "dmd/init.h"
#include "dmd/module.h"
#include "driver/cl_options.h"
#include "gen/abi.h"
#include "gen/arrays.h"
#include "gen/classes.h"
@ -243,8 +244,14 @@ void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj) {
obj->setComdat(gIR->module.getOrInsertComdat(obj->getName()));
}
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj) {
void setLinkageAndVisibility(Dsymbol *sym, llvm::GlobalObject *obj) {
setLinkage(DtoLinkage(sym), obj);
setVisibility(sym, obj);
}
void setVisibility(Dsymbol *sym, llvm::GlobalObject *obj) {
if (opts::defaultToHiddenVisibility && !sym->isExport())
obj->setVisibility(LLGlobalValue::HiddenVisibility);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -71,7 +71,12 @@ LinkageWithCOMDAT DtoLinkage(Dsymbol *sym);
bool supportsCOMDAT();
void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj);
void setLinkage(Dsymbol *sym, llvm::GlobalObject *obj);
// Sets the linkage of the specified IR global and possibly hides it, both based
// on the specified D symbol.
void setLinkageAndVisibility(Dsymbol *sym, llvm::GlobalObject *obj);
// Hides the specified IR global if using `-fvisibility=hidden` and the
// specified D symbol is not exported.
void setVisibility(Dsymbol *sym, llvm::GlobalObject *obj);
// some types
LLIntegerType *DtoSize_t();

View file

@ -666,6 +666,8 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
decl->accept(&v);
setLinkage({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()}, gvar);
if (auto forStructType = forType->isTypeStruct())
setVisibility(forStructType->sym, gvar);
}
/* ========================================================================= */

View file

@ -0,0 +1,55 @@
// Tests -fvisibility={default,hidden} for special symbols generated for
// aggregates on non-Windows targets.
// UNSUPPORTED: Windows
// RUN: %ldc %s -shared -fvisibility=default -of=lib%t_default%so
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT -check-prefix=BOTH %s
// RUN: %ldc %s -shared -fvisibility=hidden -of=lib%t_hidden%so
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN -check-prefix=BOTH %s
// DEFAULT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC11__interface24export_aggregate_symbols8DefaultI{{.*}}__vtblZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC16__interfaceInfosZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__initZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__initZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC6__vtblZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC6__vtblZ
// DEFAULT: _D24export_aggregate_symbols8DefaultC7__ClassZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultC7__ClassZ
class DefaultC : DefaultI { void foo() {} }
// DEFAULT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultI11__InterfaceZ
interface DefaultI { void foo(); }
// DEFAULT: _D24export_aggregate_symbols8DefaultS6__initZ
// HIDDEN-NOT: _D24export_aggregate_symbols8DefaultS6__initZ
struct DefaultS {}
// BOTH: _D24export_aggregate_symbols9ExportedC11__interface24export_aggregate_symbols9ExportedI{{.*}}__vtblZ
// BOTH: _D24export_aggregate_symbols9ExportedC16__interfaceInfosZ
// BOTH: _D24export_aggregate_symbols9ExportedC6__initZ
// BOTH: _D24export_aggregate_symbols9ExportedC6__vtblZ
// BOTH: _D24export_aggregate_symbols9ExportedC7__ClassZ
export class ExportedC : ExportedI { void foo() {} }
// BOTH: _D24export_aggregate_symbols9ExportedI11__InterfaceZ
export interface ExportedI { void foo(); }
// BOTH: _D24export_aggregate_symbols9ExportedS6__initZ
export struct ExportedS {}
// struct TypeInfos:
// DEFAULT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
// HIDDEN-NOT: _D45TypeInfo_S24export_aggregate_symbols8DefaultS6__initZ
// BOTH: _D46TypeInfo_S24export_aggregate_symbols9ExportedS6__initZ

View file

@ -3,10 +3,10 @@
// UNSUPPORTED: Windows
// RUN: ldc2 %s -betterC -shared -fvisibility=default -of=lib%t_default%so
// RUN: %ldc %s -betterC -shared -fvisibility=default -of=lib%t_default%so
// RUN: nm -g lib%t_default%so | FileCheck -check-prefix=DEFAULT %s
// RUN: ldc2 %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
// RUN: %ldc %s -betterC -shared -fvisibility=hidden -of=lib%t_hidden%so
// RUN: nm -g lib%t_hidden%so | FileCheck -check-prefix=HIDDEN %s
extern(C) export int test__exportedFun() { return 42; }

View file

@ -3,9 +3,9 @@
// UNSUPPORTED: Windows
// RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
// RUN: ldc2 %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so
// RUN: ldc2 %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -shared -of=%t_lib%so
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so
// RUN: %ldc %s -I%S/inputs -fvisibility=hidden -of=%t%exe %t_lib%so -d-version=DECLARE_MANUALLY
version (DECLARE_MANUALLY)
{

View file

@ -3,8 +3,8 @@
// REQUIRES: LTO
// RUN: ldc2 %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
// RUN: ldc2 %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
// RUN: %ldc %S/inputs/export_marked_symbols_lib.d -c -fvisibility=hidden -flto=thin -of=%t_lib%obj
// RUN: %ldc %s -I%S/inputs -flto=thin -of=%t%exe %t_lib%obj
import export_marked_symbols_lib;