summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2007-04-29 18:35:00 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2007-04-29 18:35:00 +0000
commit6f9896fcc81a1128b5f436d1763cc6213745adf1 (patch)
tree89f99df6a320347cd98adf490edeea24432c86f6
parentc6c98af9e5814e8066c82f20ca11cf646a5fc289 (diff)
downloadllvm-6f9896fcc81a1128b5f436d1763cc6213745adf1.tar.gz
llvm-6f9896fcc81a1128b5f436d1763cc6213745adf1.tar.bz2
llvm-6f9896fcc81a1128b5f436d1763cc6213745adf1.tar.xz
Implement protected visibility. This partly implements PR1363. Linker
should be taught to deal with protected symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36565 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/BytecodeFormat.html4
-rw-r--r--docs/LangRef.html7
-rw-r--r--include/llvm/GlobalValue.h8
-rw-r--r--include/llvm/Target/TargetAsmInfo.h9
-rw-r--r--lib/AsmParser/Lexer.l1
-rw-r--r--lib/AsmParser/Lexer.l.cvs1
-rw-r--r--lib/AsmParser/llvmAsmParser.y9
-rw-r--r--lib/AsmParser/llvmAsmParser.y.cvs9
-rw-r--r--lib/Bytecode/Reader/Reader.cpp2
-rw-r--r--lib/Bytecode/Writer/Writer.cpp5
-rw-r--r--lib/Target/TargetAsmInfo.cpp1
-rwxr-xr-xlib/Target/X86/X86ATTAsmPrinter.cpp9
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp7
-rw-r--r--lib/VMCore/AsmWriter.cpp3
14 files changed, 57 insertions, 18 deletions
diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html
index f479ca57b5..1dc9c742bd 100644
--- a/docs/BytecodeFormat.html
+++ b/docs/BytecodeFormat.html
@@ -1044,7 +1044,7 @@ and can includes more information:</p>
</tr>
<tr>
<td><a href="#bit">bit(10-12)</a></td>
- <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+ <td class="td_left">Visibility style: 0=Default, 1=Hidden, 2=Protected.</td>
</tr>
<tr>
<td><a href="#bit">bit(13-31)</a></td>
@@ -1506,7 +1506,7 @@ other fields will be present as the function is defined elsewhere.</li>
</tr>
<tr>
<td><a href="#bit">bit(16-18)</a></td>
- <td class="td_left">Visibility style: 0=Default, 1=Hidden.</td>
+ <td class="td_left">Visibility style: 0=Default, 1=Hidden, 2=Protected.</td>
</tr>
<tr>
<td><a href="#bit">bit(19-31)</a></td>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 67a2fc8a4d..58e0e3c5f3 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.
</dd>
+ <dt><b>"<tt>protected</tt>" - Protected style</b>:</dt>
+
+ <dd>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.
+ </dd>
</dl>
</div>
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
index 014cdbe82a..4f6b1e6a9f 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 60de43015d..b13a3fb50f 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 382ce24462..b67f6ff102 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 382ce24462..b67f6ff102 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 c47b6fc6ea..63f2261fa1 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 c47b6fc6ea..63f2261fa1 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 99aac056ff..e75f0fcd61 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 f1c6f6c561..b4a2691600 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 8deda9fe6a..37ab073ffc 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 03a22865e2..634f41b920 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<Function>(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 76037f13bd..7e7dc8861a 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 ac68e8d32f..3a065b0cdf 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;
}
}