Introducing the "linker_weak" linkage type. This will be used for Objective-C

metadata types which should be marked as "weak", but which the linker will
remove upon final linkage. For example, the "objc_msgSend_fixup_alloc" symbol is
defined like this:

       .globl l_objc_msgSend_fixup_alloc
       .weak_definition l_objc_msgSend_fixup_alloc
       .section __DATA, __objc_msgrefs, coalesced
       .align 3
l_objc_msgSend_fixup_alloc:
        .quad   _objc_msgSend_fixup
        .quad   L_OBJC_METH_VAR_NAME_1

This is different from the "linker_private" linkage type, because it can't have
the metadata defined with ".weak_definition".

llvm-svn: 107205
This commit is contained in:
Bill Wendling 2010-06-29 21:24:00 +00:00
parent e1b05180de
commit 05a4c0b1f2
26 changed files with 94 additions and 39 deletions

View File

@ -316,7 +316,8 @@ package llvm is
LLVMExternalWeakLinkage,
LLVMGhostLinkage,
LLVMCommonLinkage,
LLVMLinkerPrivateLinkage);
LLVMLinkerPrivateLinkage,
LLVMLinkerWeakLinkage);
for LLVMLinkage use
(LLVMExternalLinkage => 0,
@ -333,7 +334,8 @@ package llvm is
LLVMExternalWeakLinkage => 11,
LLVMGhostLinkage => 12,
LLVMCommonLinkage => 13,
LLVMLinkerPrivateLinkage => 14);
LLVMLinkerPrivateLinkage => 14,
LLVMLinkerWeakLinkage => 15);
pragma Convention (C, LLVMLinkage);

View File

@ -24,6 +24,7 @@
<ol>
<li><a href="#linkage_private">'<tt>private</tt>' Linkage</a></li>
<li><a href="#linkage_linker_private">'<tt>linker_private</tt>' Linkage</a></li>
<li><a href="#linkage_linker_weak">'<tt>linker_weak</tt>' Linkage</a></li>
<li><a href="#linkage_internal">'<tt>internal</tt>' Linkage</a></li>
<li><a href="#linkage_available_externally">'<tt>available_externally</tt>' Linkage</a></li>
<li><a href="#linkage_linkonce">'<tt>linkonce</tt>' Linkage</a></li>
@ -546,23 +547,27 @@ define i32 @main() { <i>; i32()* </i>
<dl>
<dt><tt><b><a name="linkage_private">private</a></b></tt></dt>
<dd>Global values with private linkage are only directly accessible by objects
in the current module. In particular, linking code into a module with an
private global value may cause the private to be renamed as necessary to
avoid collisions. Because the symbol is private to the module, all
references can be updated. This doesn't show up in any symbol table in the
object file.</dd>
<dd>Global values with "<tt>private</tt>" linkage are only directly accessible
by objects in the current module. In particular, linking code into a
module with an private global value may cause the private to be renamed as
necessary to avoid collisions. Because the symbol is private to the
module, all references can be updated. This doesn't show up in any symbol
table in the object file.</dd>
<dt><tt><b><a name="linkage_linker_private">linker_private</a></b></tt></dt>
<dd>Similar to private, but the symbol is passed through the assembler and
removed by the linker after evaluation. Note that (unlike private
symbols) linker_private symbols are subject to coalescing by the linker:
weak symbols get merged and redefinitions are rejected. However, unlike
normal strong symbols, they are removed by the linker from the final
linked image (executable or dynamic library).</dd>
<dd>Similar to <tt>private</tt>, but the symbol is passed through the
assembler and removed by the linker after evaluation. Note that (unlike
<tt>private</tt> symbols) <tt>linker_private</tt> symbols are subject to
coalescing by the linker: weak symbols get merged and redefinitions are
rejected. However, unlike normal strong symbols, they are removed by the
linker from the final linked image (executable or dynamic library).</dd>
<dt><tt><b><a name="linkage_linker_weak">linker_weak</a></b></tt></dt>
<dd>Global values with "<tt>linker_weak</tt>" linkage are given weak linkage,
but are removed by the linker after evaluation.</dd>
<dt><tt><b><a name="linkage_internal">internal</a></b></tt></dt>
<dd>Similar to private, but the value shows as a local symbol
<dd>Similar to <tt>private</tt>, but the value shows as a local symbol
(<tt>STB_LOCAL</tt> in the case of ELF) in the object file. This
corresponds to the notion of the '<tt>static</tt>' keyword in C.</dd>

View File

@ -226,7 +226,8 @@ typedef enum {
LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */
LLVMLinkerPrivateLinkage /**< Like Private, but linker removes. */
LLVMLinkerPrivateLinkage, /**< Like private, but linker removes. */
LLVMLinkerWeakLinkage /**< Like linker private, but weak. */
} LLVMLinkage;
typedef enum {

View File

@ -285,7 +285,7 @@ namespace llvm {
MCSymbol *GetCPISymbol(unsigned CPID) const;
/// GetJTISymbol - Return the symbol for the specified jump table entry.
MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
MCSymbol *GetJTISymbol(unsigned JTID, bool PassToLinker = false) const;
/// GetJTSetSymbol - Return the symbol for the specified jump table .set
/// FIXME: privatize to AsmPrinter.

View File

@ -402,10 +402,10 @@ public:
//
/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
/// normal 'L' label is returned.
MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
bool isLinkerPrivate = false) const;
/// If PassToLinker is specified, an 'l' label is returned, otherwise a normal
/// 'L' label is returned.
MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
bool PassToLinker = false) const;
};
//===--------------------------------------------------------------------===//

View File

@ -39,7 +39,8 @@ public:
AppendingLinkage, ///< Special purpose, only applies to global arrays
InternalLinkage, ///< Rename collisions when linking (static functions).
PrivateLinkage, ///< Like Internal, but omit from symbol table.
LinkerPrivateLinkage, ///< Like Private, but linker removes.
LinkerPrivateLinkage, ///< Like private, but linker removes.
LinkerWeakLinkage, ///< Like linker private, but weak.
DLLImportLinkage, ///< Function to be imported from DLL
DLLExportLinkage, ///< Function to be accessible from DLL.
ExternalWeakLinkage,///< ExternalWeak linkage description.
@ -132,7 +133,10 @@ public:
return Linkage == PrivateLinkage;
}
static bool isLinkerPrivateLinkage(LinkageTypes Linkage) {
return Linkage==LinkerPrivateLinkage;
return Linkage == LinkerPrivateLinkage;
}
static bool isLinkerWeakLinkage(LinkageTypes Linkage) {
return Linkage == LinkerWeakLinkage;
}
static bool isLocalLinkage(LinkageTypes Linkage) {
return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) ||
@ -187,6 +191,7 @@ public:
bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
bool hasLinkerPrivateLinkage() const { return isLinkerPrivateLinkage(Linkage); }
bool hasLinkerWeakLinkage() const { return isLinkerWeakLinkage(Linkage); }
bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); }
bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); }

View File

@ -85,6 +85,11 @@ namespace llvm {
/// be passed through the assembler but be removed by the linker. This
/// is "l" on Darwin, currently used for some ObjC metadata.
const char *LinkerPrivateGlobalPrefix; // Defaults to ""
/// LinkerWeakGlobalPrefix - This prefix is used for symbols that are marked
/// "weak" and should be passed through the assembler, but be removed by the
/// linker. This is "l" on Darwin, currently used for some ObjC metadata.
const char *LinkerWeakGlobalPrefix; // Defaults to ""
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
/// emit before and after an inline assembly statement.
@ -335,6 +340,9 @@ namespace llvm {
const char *getLinkerPrivateGlobalPrefix() const {
return LinkerPrivateGlobalPrefix;
}
const char *getLinkerWeakGlobalPrefix() const {
return LinkerWeakGlobalPrefix;
}
const char *getInlineAsmStart() const {
return InlineAsmStart;
}

View File

@ -32,7 +32,8 @@ public:
enum ManglerPrefixTy {
Default, ///< Emit default string before each symbol.
Private, ///< Emit "private" prefix before each symbol.
LinkerPrivate ///< Emit "linker private" prefix before each symbol.
LinkerPrivate, ///< Emit "linker private" prefix before each symbol.
LinkerWeak ///< Emit "linker weak" prefix before each symbol.
};
private:

View File

@ -492,6 +492,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(private);
KEYWORD(linker_private);
KEYWORD(linker_weak);
KEYWORD(internal);
KEYWORD(available_externally);
KEYWORD(linkonce);

View File

@ -198,6 +198,7 @@ bool LLParser::ParseTopLevelEntities() {
// OptionalAddrSpace ('constant'|'global') ...
case lltok::kw_private : // OptionalLinkage
case lltok::kw_linker_private: // OptionalLinkage
case lltok::kw_linker_weak: // OptionalLinkage
case lltok::kw_internal: // OptionalLinkage
case lltok::kw_weak: // OptionalLinkage
case lltok::kw_weak_odr: // OptionalLinkage
@ -629,7 +630,8 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
Linkage != GlobalValue::WeakODRLinkage &&
Linkage != GlobalValue::InternalLinkage &&
Linkage != GlobalValue::PrivateLinkage &&
Linkage != GlobalValue::LinkerPrivateLinkage)
Linkage != GlobalValue::LinkerPrivateLinkage &&
Linkage != GlobalValue::LinkerWeakLinkage)
return Error(LinkageLoc, "invalid linkage type for alias");
Constant *Aliasee;
@ -1013,6 +1015,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
/// ::= /*empty*/
/// ::= 'private'
/// ::= 'linker_private'
/// ::= 'linker_weak'
/// ::= 'internal'
/// ::= 'weak'
/// ::= 'weak_odr'
@ -1030,6 +1033,7 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
default: Res=GlobalValue::ExternalLinkage; return false;
case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
case lltok::kw_linker_private: Res = GlobalValue::LinkerPrivateLinkage; break;
case lltok::kw_linker_weak: Res = GlobalValue::LinkerWeakLinkage; break;
case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break;
case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
@ -2704,6 +2708,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
break;
case GlobalValue::PrivateLinkage:
case GlobalValue::LinkerPrivateLinkage:
case GlobalValue::LinkerWeakLinkage:
case GlobalValue::InternalLinkage:
case GlobalValue::AvailableExternallyLinkage:
case GlobalValue::LinkOnceAnyLinkage:

View File

@ -37,8 +37,9 @@ namespace lltok {
kw_declare, kw_define,
kw_global, kw_constant,
kw_private, kw_linker_private, kw_internal, kw_linkonce, kw_linkonce_odr,
kw_weak, kw_weak_odr, kw_appending, kw_dllimport, kw_dllexport, kw_common,
kw_private, kw_linker_private, kw_linker_weak, kw_internal, kw_linkonce,
kw_linkonce_odr, kw_weak, kw_weak_odr, kw_appending, kw_dllimport,
kw_dllexport, kw_common,
kw_available_externally,
kw_default, kw_hidden, kw_protected,
kw_extern_weak,

View File

@ -75,6 +75,7 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) {
case 11: return GlobalValue::LinkOnceODRLinkage;
case 12: return GlobalValue::AvailableExternallyLinkage;
case 13: return GlobalValue::LinkerPrivateLinkage;
case 14: return GlobalValue::LinkerWeakLinkage;
}
}

View File

@ -313,6 +313,7 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
case GlobalValue::LinkOnceODRLinkage: return 11;
case GlobalValue::AvailableExternallyLinkage: return 12;
case GlobalValue::LinkerPrivateLinkage: return 13;
case GlobalValue::LinkerWeakLinkage: return 14;
}
}

View File

@ -199,6 +199,7 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const {
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
case GlobalValue::LinkerWeakLinkage:
case GlobalValue::LinkerPrivateLinkage:
if (MAI->getWeakDefDirective() != 0) {
// .globl _foo
@ -1610,8 +1611,8 @@ MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
}
/// GetJTISymbol - Return the symbol for the specified jump table entry.
MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {
return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate);
MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool PassToLinker) const {
return MF->getJTISymbol(JTID, OutContext, PassToLinker);
}
/// GetJTSetSymbol - Return the symbol for the specified jump table .set

View File

@ -410,17 +410,18 @@ unsigned MachineFunction::addLiveIn(unsigned PReg,
}
/// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
/// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
/// normal 'L' label is returned.
MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
bool isLinkerPrivate) const {
/// If isLinkerPrivate or isLinkerWeak is specified, an 'l' label is returned,
/// otherwise a normal 'L' label is returned.
MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
bool PassToLinker) const {
assert(JumpTableInfo && "No jump tables");
assert(JTI < JumpTableInfo->getJumpTables().size() && "Invalid JTI!");
const MCAsmInfo &MAI = *getTarget().getMCAsmInfo();
const char *Prefix = isLinkerPrivate ? MAI.getLinkerPrivateGlobalPrefix() :
MAI.getPrivateGlobalPrefix();
const char *Prefix = PassToLinker ?
MAI.getLinkerPrivateGlobalPrefix() :
MAI.getPrivateGlobalPrefix();
SmallString<60> Name;
raw_svector_ostream(Name)
<< Prefix << "JTI" << getFunctionNumber() << '_' << JTI;

View File

@ -755,11 +755,12 @@ shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
/// the directive emitted (this occurs in ObjC metadata).
if (!GV) return false;
// Check whether the mangled name has the "Private" or "LinkerPrivate" prefix.
// Check whether the mangled name has the "Private", "LinkerPrivate", or
// "LinkerWeak" prefix.
if (GV->hasLocalLinkage() && !isa<Function>(GV)) {
// FIXME: ObjC metadata is currently emitted as internal symbols that have
// \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
// this horrible hack can go away.
// \1L and \1l prefixes on them. Fix them to be Private / LinkerPrivate /
// LinkerWeak and this horrible hack can go away.
MCSymbol *Sym = Mang->getSymbol(GV);
if (Sym->getName()[0] == 'L' || Sym->getName()[0] == 'l')
return false;

View File

@ -735,6 +735,9 @@ CalculateAliasLinkage(const GlobalValue *SGV, const GlobalValue *DGV) {
else if (SL == GlobalValue::LinkerPrivateLinkage &&
DL == GlobalValue::LinkerPrivateLinkage)
return GlobalValue::LinkerPrivateLinkage;
else if (SL == GlobalValue::LinkerWeakLinkage &&
DL == GlobalValue::LinkerWeakLinkage)
return GlobalValue::LinkerWeakLinkage;
else {
assert (SL == GlobalValue::PrivateLinkage &&
DL == GlobalValue::PrivateLinkage && "Unexpected linkage type");

View File

@ -31,6 +31,7 @@ MCAsmInfo::MCAsmInfo() {
GlobalPrefix = "";
PrivateGlobalPrefix = ".";
LinkerPrivateGlobalPrefix = "";
LinkerWeakGlobalPrefix = "";
InlineAsmStart = "APP";
InlineAsmEnd = "NO_APP";
AssemblerDialect = 0;

View File

@ -21,6 +21,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
GlobalPrefix = "_";
PrivateGlobalPrefix = "L";
LinkerPrivateGlobalPrefix = "l";
LinkerWeakGlobalPrefix = "l";
AllowQuotesInName = true;
HasSingleParameterDotFile = false;
HasSubsectionsViaSymbols = true;

View File

@ -286,6 +286,8 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
Out << "GlobalValue::PrivateLinkage"; break;
case GlobalValue::LinkerPrivateLinkage:
Out << "GlobalValue::LinkerPrivateLinkage"; break;
case GlobalValue::LinkerWeakLinkage:
Out << "GlobalValue::LinkerWeakLinkage"; break;
case GlobalValue::AvailableExternallyLinkage:
Out << "GlobalValue::AvailableExternallyLinkage "; break;
case GlobalValue::LinkOnceAnyLinkage:

View File

@ -118,6 +118,9 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
} else if (PrefixTy == Mangler::LinkerPrivate) {
const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
OutName.append(Prefix, Prefix+strlen(Prefix));
} else if (PrefixTy == Mangler::LinkerWeak) {
const char *Prefix = MAI.getLinkerWeakGlobalPrefix();
OutName.append(Prefix, Prefix+strlen(Prefix));
}
const char *Prefix = MAI.getGlobalPrefix();
@ -182,6 +185,8 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
PrefixTy = Mangler::Private;
else if (GV->hasLinkerPrivateLinkage())
PrefixTy = Mangler::LinkerPrivate;
else if (GV->hasLinkerWeakLinkage())
PrefixTy = Mangler::LinkerWeak;
// If this global has a name, handle it simply.
if (GV->hasName()) {

View File

@ -129,6 +129,7 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
case GlobalValue::ExternalLinkage:
case GlobalValue::LinkerWeakLinkage:
emitArrayBound(GVSym, GV);
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);

View File

@ -535,6 +535,7 @@ static LinkageCategory categorize(const Function *F) {
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
case GlobalValue::ExternalWeakLinkage:
case GlobalValue::LinkerWeakLinkage:
return ExternalWeak;
case GlobalValue::ExternalLinkage:

View File

@ -1419,6 +1419,7 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT,
case GlobalValue::ExternalLinkage: break;
case GlobalValue::PrivateLinkage: Out << "private "; break;
case GlobalValue::LinkerPrivateLinkage: Out << "linker_private "; break;
case GlobalValue::LinkerWeakLinkage: Out << "linker_weak "; break;
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break;
case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break;

View File

@ -1058,6 +1058,8 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) {
return LLVMPrivateLinkage;
case GlobalValue::LinkerPrivateLinkage:
return LLVMLinkerPrivateLinkage;
case GlobalValue::LinkerWeakLinkage:
return LLVMLinkerWeakLinkage;
case GlobalValue::DLLImportLinkage:
return LLVMDLLImportLinkage;
case GlobalValue::DLLExportLinkage:
@ -1108,6 +1110,9 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) {
case LLVMLinkerPrivateLinkage:
GV->setLinkage(GlobalValue::LinkerPrivateLinkage);
break;
case LLVMLinkerWeakLinkage:
GV->setLinkage(GlobalValue::LinkerWeakLinkage);
break;
case LLVMDLLImportLinkage:
GV->setLinkage(GlobalValue::DLLImportLinkage);
break;

View File

@ -89,7 +89,8 @@ static char TypeCharForSymbol(GlobalValue &GV) {
static void DumpSymbolNameForGlobalValue(GlobalValue &GV) {
// Private linkage and available_externally linkage don't exist in symtab.
if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() ||
GV.hasAvailableExternallyLinkage()) return;
GV.hasLinkerWeakLinkage() || GV.hasAvailableExternallyLinkage())
return;
const std::string SymbolAddrStr = " "; // Not used yet...
char TypeChar = TypeCharForSymbol(GV);