mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-22 19:49:49 +00:00
Implement protected visibility. This partly implements PR1363. Linker
should be taught to deal with protected symbols. llvm-svn: 36565
This commit is contained in:
parent
cb2004f82c
commit
3d95e52ea2
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ TargetAsmInfo::TargetAsmInfo() :
|
||||
UsedDirective(0),
|
||||
WeakRefDirective(0),
|
||||
HiddenDirective("\t.hidden\t"),
|
||||
ProtectedDirective("\t.protected\t"),
|
||||
AbsoluteSectionOffsets(false),
|
||||
HasLEB128(false),
|
||||
HasDotLoc(false),
|
||||
|
@ -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())
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user