diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index a25b850e29d..24620659440 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -212,6 +212,10 @@ namespace llvm { /// directive. bool HasNoDeadStrip; // Defaults to false. + /// HasSymbolResolver - True if this target supports the MachO + /// .symbol_resolver directive. + bool HasSymbolResolver; // Defaults to false. + /// WeakRefDirective - This directive, if non-null, is used to declare a /// global as being a weak undefined symbol. const char *WeakRefDirective; // Defaults to NULL. @@ -395,6 +399,7 @@ namespace llvm { } bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } + bool hasSymbolResolver() const { return HasSymbolResolver; } const char *getWeakRefDirective() const { return WeakRefDirective; } const char *getWeakDefDirective() const { return WeakDefDirective; } const char *getLinkOnceDirective() const { return LinkOnceDirective; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 03337a9f521..1df55dc252e 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -34,6 +34,7 @@ enum MCSymbolAttr { MCSA_LazyReference, ///< .lazy_reference (MachO) MCSA_Local, ///< .local (ELF) MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) + MCSA_SymbolResolver, ///< .symbol_resolver (MachO) MCSA_PrivateExtern, ///< .private_extern (MachO) MCSA_Protected, ///< .protected (ELF) MCSA_Reference, ///< .reference (MachO) diff --git a/include/llvm/MC/MCMachOSymbolFlags.h b/include/llvm/MC/MCMachOSymbolFlags.h index c938c81f698..78713124554 100644 --- a/include/llvm/MC/MCMachOSymbolFlags.h +++ b/include/llvm/MC/MCMachOSymbolFlags.h @@ -36,7 +36,8 @@ namespace llvm { // Other 'desc' flags. SF_NoDeadStrip = 0x0020, SF_WeakReference = 0x0040, - SF_WeakDefinition = 0x0080 + SF_WeakDefinition = 0x0080, + SF_SymbolResolver = 0x0100 }; } // end namespace llvm diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 807aac26b02..edde4b1fcb4 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -58,6 +58,7 @@ MCAsmInfo::MCAsmInfo() { HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; HasNoDeadStrip = false; + HasSymbolResolver = false; WeakRefDirective = 0; WeakDefDirective = 0; LinkOnceDirective = 0; diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index e0e261a63c7..fd155135df0 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -44,6 +44,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { HasDotTypeDotSizeDirective = false; HasNoDeadStrip = true; + HasSymbolResolver = true; DwarfUsesAbsoluteLabelForStmtList = false; DwarfUsesLabelOffsetForRanges = false; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 97cfb217d21..012c79c8829 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -326,6 +326,7 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break; case MCSA_Local: OS << "\t.local\t"; break; case MCSA_NoDeadStrip: OS << "\t.no_dead_strip\t"; break; + case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; case MCSA_PrivateExtern: OS << "\t.private_extern\t"; break; case MCSA_Protected: OS << "\t.protected\t"; break; case MCSA_Reference: OS << "\t.reference\t"; break; diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index cac48170642..a3c716bdcb7 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -281,6 +281,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_LazyReference: case MCSA_Reference: case MCSA_NoDeadStrip: + case MCSA_SymbolResolver: case MCSA_PrivateExtern: case MCSA_WeakDefinition: case MCSA_WeakDefAutoPrivate: diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 3236432fb8d..88fa2304932 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -235,6 +235,10 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, SD.setFlags(SD.getFlags() | SF_NoDeadStrip); break; + case MCSA_SymbolResolver: + SD.setFlags(SD.getFlags() | SF_SymbolResolver); + break; + case MCSA_PrivateExtern: SD.setExternal(true); SD.setPrivateExtern(true); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 303353b2b65..63ddfb9f825 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1012,6 +1012,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveSymbolAttribute(MCSA_LazyReference); if (IDVal == ".no_dead_strip") return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip); + if (IDVal == ".symbol_resolver") + return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); if (IDVal == ".private_extern") return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); if (IDVal == ".protected") diff --git a/test/MC/MachO/symbol-flags.s b/test/MC/MachO/symbol-flags.s index 705fa39fad5..b16476ed4bc 100644 --- a/test/MC/MachO/symbol-flags.s +++ b/test/MC/MachO/symbol-flags.s @@ -49,6 +49,9 @@ sym_private_ext_C: .no_dead_strip sym_no_dead_strip_A +sym_symbol_resolver_A: + .symbol_resolver sym_symbol_resolver_A + .reference sym_ref_A .desc sym_ref_A, 1 .desc sym_ref_A, 0x1234 @@ -112,10 +115,10 @@ sym_desc_flags: // CHECK: (('command', 2) // CHECK: ('size', 24) // CHECK: ('symoff', 324) -// CHECK: ('nsyms', 23) -// CHECK: ('stroff', 600) -// CHECK: ('strsize', 368) -// CHECK: ('_string_data', '\x00sym_ref_A\x00sym_ref_def_D\x00sym_ref_def_E\x00sym_weak_ref_A\x00sym_weak_def_A\x00sym_weak_def_B\x00sym_weak_def_C\x00sym_lazy_ref_A\x00sym_lazy_ref_D\x00sym_lazy_ref_E\x00sym_private_ext_A\x00sym_private_ext_B\x00sym_private_ext_C\x00sym_private_ext_D\x00sym_private_ext_E\x00sym_no_dead_strip_A\x00sym_ref_def_A\x00sym_ref_def_C\x00sym_weak_ref_def_A\x00sym_weak_ref_def_B\x00sym_lazy_ref_B\x00sym_lazy_ref_C\x00sym_desc_flags\x00\x00\x00\x00') +// CHECK: ('nsyms', 24) +// CHECK: ('stroff', 612) +// CHECK: ('strsize', 388) +// CHECK: ('_string_data', '\x00sym_ref_A\x00sym_ref_def_D\x00sym_ref_def_E\x00sym_weak_ref_A\x00sym_weak_def_A\x00sym_weak_def_B\x00sym_weak_def_C\x00sym_lazy_ref_A\x00sym_lazy_ref_D\x00sym_lazy_ref_E\x00sym_private_ext_A\x00sym_private_ext_B\x00sym_private_ext_C\x00sym_private_ext_D\x00sym_private_ext_E\x00sym_no_dead_strip_A\x00sym_ref_def_A\x00sym_ref_def_C\x00sym_weak_ref_def_A\x00sym_weak_ref_def_B\x00sym_lazy_ref_B\x00sym_lazy_ref_C\x00sym_symbol_resolver_A\x00sym_desc_flags\x00\x00') // CHECK: ('_symbols', [ // CHECK: # Symbol 0 // CHECK: (('n_strx', 254) @@ -169,11 +172,19 @@ sym_desc_flags: // CHECK: (('n_strx', 350) // CHECK: ('n_type', 0xe) // CHECK: ('n_sect', 2) +// CHECK: ('n_desc', 256) +// CHECK: ('n_value', 0) +// CHECK: ('_string', 'sym_symbol_resolver_A') +// CHECK: ), +// CHECK: # Symbol 7 +// CHECK: (('n_strx', 372) +// CHECK: ('n_type', 0xe) +// CHECK: ('n_sect', 2) // CHECK: ('n_desc', 64) // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_desc_flags') // CHECK: ), -// CHECK: # Symbol 7 +// CHECK: # Symbol 8 // CHECK: (('n_strx', 162) // CHECK: ('n_type', 0x1f) // CHECK: ('n_sect', 2) @@ -181,7 +192,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_private_ext_B') // CHECK: ), -// CHECK: # Symbol 8 +// CHECK: # Symbol 9 // CHECK: (('n_strx', 180) // CHECK: ('n_type', 0x1f) // CHECK: ('n_sect', 2) @@ -189,7 +200,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_private_ext_C') // CHECK: ), -// CHECK: # Symbol 9 +// CHECK: # Symbol 10 // CHECK: (('n_strx', 54) // CHECK: ('n_type', 0xf) // CHECK: ('n_sect', 2) @@ -197,7 +208,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_weak_def_A') // CHECK: ), -// CHECK: # Symbol 10 +// CHECK: # Symbol 11 // CHECK: (('n_strx', 69) // CHECK: ('n_type', 0xf) // CHECK: ('n_sect', 2) @@ -205,7 +216,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_weak_def_B') // CHECK: ), -// CHECK: # Symbol 11 +// CHECK: # Symbol 12 // CHECK: (('n_strx', 84) // CHECK: ('n_type', 0xf) // CHECK: ('n_sect', 2) @@ -213,7 +224,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_weak_def_C') // CHECK: ), -// CHECK: # Symbol 12 +// CHECK: # Symbol 13 // CHECK: (('n_strx', 99) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -221,7 +232,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_lazy_ref_A') // CHECK: ), -// CHECK: # Symbol 13 +// CHECK: # Symbol 14 // CHECK: (('n_strx', 114) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -229,7 +240,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_lazy_ref_D') // CHECK: ), -// CHECK: # Symbol 14 +// CHECK: # Symbol 15 // CHECK: (('n_strx', 129) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -237,7 +248,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_lazy_ref_E') // CHECK: ), -// CHECK: # Symbol 15 +// CHECK: # Symbol 16 // CHECK: (('n_strx', 234) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -245,7 +256,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_no_dead_strip_A') // CHECK: ), -// CHECK: # Symbol 16 +// CHECK: # Symbol 17 // CHECK: (('n_strx', 144) // CHECK: ('n_type', 0x11) // CHECK: ('n_sect', 0) @@ -253,7 +264,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_private_ext_A') // CHECK: ), -// CHECK: # Symbol 17 +// CHECK: # Symbol 18 // CHECK: (('n_strx', 198) // CHECK: ('n_type', 0x11) // CHECK: ('n_sect', 0) @@ -261,7 +272,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_private_ext_D') // CHECK: ), -// CHECK: # Symbol 18 +// CHECK: # Symbol 19 // CHECK: (('n_strx', 216) // CHECK: ('n_type', 0x11) // CHECK: ('n_sect', 0) @@ -269,7 +280,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_private_ext_E') // CHECK: ), -// CHECK: # Symbol 19 +// CHECK: # Symbol 20 // CHECK: (('n_strx', 1) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -277,7 +288,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_ref_A') // CHECK: ), -// CHECK: # Symbol 20 +// CHECK: # Symbol 21 // CHECK: (('n_strx', 11) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -285,7 +296,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_ref_def_D') // CHECK: ), -// CHECK: # Symbol 21 +// CHECK: # Symbol 22 // CHECK: (('n_strx', 25) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -293,7 +304,7 @@ sym_desc_flags: // CHECK: ('n_value', 0) // CHECK: ('_string', 'sym_ref_def_E') // CHECK: ), -// CHECK: # Symbol 22 +// CHECK: # Symbol 23 // CHECK: (('n_strx', 39) // CHECK: ('n_type', 0x1) // CHECK: ('n_sect', 0) @@ -307,10 +318,10 @@ sym_desc_flags: // CHECK: (('command', 11) // CHECK: ('size', 80) // CHECK: ('ilocalsym', 0) -// CHECK: ('nlocalsym', 7) -// CHECK: ('iextdefsym', 7) +// CHECK: ('nlocalsym', 8) +// CHECK: ('iextdefsym', 8) // CHECK: ('nextdefsym', 5) -// CHECK: ('iundefsym', 12) +// CHECK: ('iundefsym', 13) // CHECK: ('nundefsym', 11) // CHECK: ('tocoff', 0) // CHECK: ('ntoc', 0)