diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html index f479ca57b5f..1dc9c742bd9 100644 --- a/docs/BytecodeFormat.html +++ b/docs/BytecodeFormat.html @@ -1044,7 +1044,7 @@ and can includes more information:

bit(10-12) - Visibility style: 0=Default, 1=Hidden. + Visibility style: 0=Default, 1=Hidden, 2=Protected. bit(13-31) @@ -1506,7 +1506,7 @@ other fields will be present as the function is defined elsewhere. bit(16-18) - Visibility style: 0=Default, 1=Hidden. + Visibility style: 0=Default, 1=Hidden, 2=Protected. bit(19-31) diff --git a/docs/LangRef.html b/docs/LangRef.html index 67a2fc8a4dd..58e0e3c5f39 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -591,6 +591,13 @@ All Global Variables and Functions have one of the following visibility styles: directly. +
"protected" - Protected style:
+ +
On ELF, protected visibility indicates that the symbol will be placed in + the dynamic symbol table, but that references within the defining module will + bind to the local symbol. That is, the symbol cannot be overridden by another + module. +
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 014cdbe82af..4f6b1e6a9f9 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -43,7 +43,8 @@ public: /// @brief An enumeration for the kinds of visibility of global values. enum VisibilityTypes { DefaultVisibility = 0, ///< The GV is visible - HiddenVisibility ///< The GV is hidden + HiddenVisibility, ///< The GV is hidden + ProtectedVisibility ///< The GV is protected }; protected: @@ -58,7 +59,7 @@ protected: // Note: VC++ treats enums as signed, so an extra bit is required to prevent // Linkage and Visibility from turning into negative values. LinkageTypes Linkage : 5; // The linkage of this global - unsigned Visibility : 1; // The visibility style of this global + unsigned Visibility : 2; // The visibility style of this global unsigned Alignment : 16; // Alignment of this symbol, must be power of two std::string Section; // Section to emit this into, empty mean default public: @@ -74,6 +75,9 @@ public: VisibilityTypes getVisibility() const { return (VisibilityTypes)Visibility; } bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; } + bool hasProtectedVisibility() const { + return Visibility == ProtectedVisibility; + } void setVisibility(VisibilityTypes V) { Visibility = V; } bool hasSection() const { return !Section.empty(); } diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 60de43015dc..b13a3fb50f4 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -256,7 +256,11 @@ namespace llvm { /// HiddenDirective - This directive, if non-null, is used to declare a /// global or function as having hidden visibility. const char *HiddenDirective; // Defaults to "\t.hidden\t". - + + /// ProtectedDirective - This directive, if non-null, is used to declare a + /// global or function as having protected visibility. + const char *ProtectedDirective; // Defaults to "\t.protected\t". + //===--- Dwarf Emission Directives -----------------------------------===// /// AbsoluteSectionOffsets - True if we should emit abolute section @@ -523,6 +527,9 @@ namespace llvm { const char *getHiddenDirective() const { return HiddenDirective; } + const char *getProtectedDirective() const { + return ProtectedDirective; + } bool isAbsoluteSectionOffsets() const { return AbsoluteSectionOffsets; } diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 382ce24462a..b67f6ff1024 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -206,6 +206,7 @@ appending { return APPENDING; } dllimport { return DLLIMPORT; } dllexport { return DLLEXPORT; } hidden { return HIDDEN; } +protected { return PROTECTED; } extern_weak { return EXTERN_WEAK; } external { return EXTERNAL; } thread_local { return THREAD_LOCAL; } diff --git a/lib/AsmParser/Lexer.l.cvs b/lib/AsmParser/Lexer.l.cvs index 382ce24462a..b67f6ff1024 100644 --- a/lib/AsmParser/Lexer.l.cvs +++ b/lib/AsmParser/Lexer.l.cvs @@ -206,6 +206,7 @@ appending { return APPENDING; } dllimport { return DLLIMPORT; } dllexport { return DLLEXPORT; } hidden { return HIDDEN; } +protected { return PROTECTED; } extern_weak { return EXTERN_WEAK; } external { return EXTERNAL; } thread_local { return THREAD_LOCAL; } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index c47b6fc6ea9..63f2261fa11 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1099,7 +1099,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token NORETURN INREG SRET NOUNWIND // Visibility Styles -%token DEFAULT HIDDEN +%token DEFAULT HIDDEN PROTECTED %start Module %% @@ -1180,9 +1180,10 @@ GVExternalLinkage ; GVVisibilityStyle - : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } - | DEFAULT { $$ = GlobalValue::DefaultVisibility; } - | HIDDEN { $$ = GlobalValue::HiddenVisibility; } + : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } + | DEFAULT { $$ = GlobalValue::DefaultVisibility; } + | HIDDEN { $$ = GlobalValue::HiddenVisibility; } + | PROTECTED { $$ = GlobalValue::ProtectedVisibility; } ; FunctionDeclareLinkage diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index c47b6fc6ea9..63f2261fa11 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -1099,7 +1099,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token NORETURN INREG SRET NOUNWIND // Visibility Styles -%token DEFAULT HIDDEN +%token DEFAULT HIDDEN PROTECTED %start Module %% @@ -1180,9 +1180,10 @@ GVExternalLinkage ; GVVisibilityStyle - : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } - | DEFAULT { $$ = GlobalValue::DefaultVisibility; } - | HIDDEN { $$ = GlobalValue::HiddenVisibility; } + : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } + | DEFAULT { $$ = GlobalValue::DefaultVisibility; } + | HIDDEN { $$ = GlobalValue::HiddenVisibility; } + | PROTECTED { $$ = GlobalValue::ProtectedVisibility; } ; FunctionDeclareLinkage diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 99aac056ff3..e75f0fcd610 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -1532,6 +1532,7 @@ void BytecodeReader::ParseFunctionBody(Function* F) { switch (VisibilityID) { case 0: Visibility = GlobalValue::DefaultVisibility; break; case 1: Visibility = GlobalValue::HiddenVisibility; break; + case 2: Visibility = GlobalValue::ProtectedVisibility; break; default: error("Unknown visibility type: " + utostr(VisibilityID)); Visibility = GlobalValue::DefaultVisibility; @@ -1767,6 +1768,7 @@ void BytecodeReader::ParseModuleGlobalInfo() { switch (VisibilityID) { case 0: Visibility = GlobalValue::DefaultVisibility; break; case 1: Visibility = GlobalValue::HiddenVisibility; break; + case 2: Visibility = GlobalValue::ProtectedVisibility; break; default: error("Unknown visibility type: " + utostr(VisibilityID)); Visibility = GlobalValue::DefaultVisibility; diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index f1c6f6c5619..b4a26916008 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -957,8 +957,9 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { static unsigned getEncodedVisibility(const GlobalValue *GV) { switch (GV->getVisibility()) { default: assert(0 && "Invalid visibility!"); - case GlobalValue::DefaultVisibility: return 0; - case GlobalValue::HiddenVisibility: return 1; + case GlobalValue::DefaultVisibility: return 0; + case GlobalValue::HiddenVisibility: return 1; + case GlobalValue::ProtectedVisibility: return 2; } } diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 8deda9fe6a5..37ab073ffcd 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -74,6 +74,7 @@ TargetAsmInfo::TargetAsmInfo() : UsedDirective(0), WeakRefDirective(0), HiddenDirective("\t.hidden\t"), + ProtectedDirective("\t.protected\t"), AbsoluteSectionOffsets(false), HasLEB128(false), HasDotLoc(false), diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index 03a22865e2c..634f41b9200 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -125,9 +125,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { } break; } - if (F->hasHiddenVisibility()) + if (F->hasHiddenVisibility()) { if (const char *Directive = TAI->getHiddenDirective()) O << Directive << CurrentFnName << "\n"; + } else if (F->hasProtectedVisibility()) { + if (const char *Directive = TAI->getProtectedDirective()) + O << Directive << CurrentFnName << "\n"; + } if (Subtarget->isTargetELF()) O << "\t.type " << CurrentFnName << ",@function\n"; @@ -322,7 +326,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, if (isCallOp && isa(GV)) { if (printGOT(TM, Subtarget)) { // Assemble call via PLT for non-local symbols - if (!GV->hasHiddenVisibility() || GV->isDeclaration()) + if (!(GV->hasHiddenVisibility() || GV->hasProtectedVisibility()) || + GV->isDeclaration()) O << "@PLT"; } if (Subtarget->isTargetCygMing() && GV->isDeclaration()) diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 76037f13bd5..7e7dc8861a7 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -155,9 +155,14 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { unsigned Size = TD->getTypeSize(Type); unsigned Align = TD->getPreferredAlignmentLog(I); - if (I->hasHiddenVisibility()) + if (I->hasHiddenVisibility()) { if (const char *Directive = TAI->getHiddenDirective()) O << Directive << name << "\n"; + } else if (I->hasProtectedVisibility()) { + if (const char *Directive = TAI->getProtectedDirective()) + O << Directive << name << "\n"; + } + if (Subtarget->isTargetELF()) O << "\t.type " << name << ",@object\n"; diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index ac68e8d32fb..3a065b0cdfe 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -886,6 +886,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { default: assert(0 && "Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } } @@ -914,6 +915,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { default: assert(0 && "Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } Out << "alias "; @@ -998,6 +1000,7 @@ void AssemblyWriter::printFunction(const Function *F) { default: assert(0 && "Invalid visibility style!"); case GlobalValue::DefaultVisibility: break; case GlobalValue::HiddenVisibility: Out << "hidden "; break; + case GlobalValue::ProtectedVisibility: Out << "protected "; break; } }