Implement protected visibility. This partly implements PR1363. Linker

should be taught to deal with protected symbols.

llvm-svn: 36565
This commit is contained in:
Anton Korobeynikov 2007-04-29 18:35:00 +00:00
parent cb2004f82c
commit 3d95e52ea2
14 changed files with 57 additions and 18 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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(); }

View File

@ -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;
}

View File

@ -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; }

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}

View File

@ -74,6 +74,7 @@ TargetAsmInfo::TargetAsmInfo() :
UsedDirective(0),
WeakRefDirective(0),
HiddenDirective("\t.hidden\t"),
ProtectedDirective("\t.protected\t"),
AbsoluteSectionOffsets(false),
HasLEB128(false),
HasDotLoc(false),

View File

@ -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())

View File

@ -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";

View File

@ -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;
}
}