[llvm] r189497 - The integrated darwin assembler can hang in an infinite loop (or get an assert

Kevin Enderby enderby at apple.com
Wed Aug 28 10:50:59 PDT 2013


Author: enderby
Date: Wed Aug 28 12:50:59 2013
New Revision: 189497

URL: http://llvm.org/viewvc/llvm-project?rev=189497&view=rev
Log:
The integrated darwin assembler can hang in an infinite loop (or get an assert 
with a debug build) with this buggy .indirect_symbol directive usage:

% cat test.s
x: .indirect_symbol _y

The assertion is because it is trying to get the symbol index for the
symbol _y when it is writing out the indirect symbol table. This line of
code in MachObjectWriter::WriteObject() :

        Write32(Asm.getSymbolData(*it->Symbol).getIndex());

And while there is a symbol _y it does not have any getSymbolData set which
is only done in MachObjectWriter::BindIndirectSymbols() for pointer sections
or stub sections.  I added a check and an error in there to catch this in case
something slips through.

But to get a better error the parser should detect when a .indirect_symbol
directive is used and it is not in a pointer section or stub section.  To make
that work I moved the handling of the indirect symbol out of the target
independent AsmParser code into the DarwinAsmParser code that can check
for the proper Mach-O section types.

rdar://14825505

Added:
    llvm/trunk/test/MC/MachO/bad-indirect-symbols.s
Modified:
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp
    llvm/trunk/lib/MC/MachObjectWriter.cpp

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=189497&r1=189496&r2=189497&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Wed Aug 28 12:50:59 2013
@@ -342,7 +342,7 @@ private:
     DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
     DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
     DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
-    DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_INDIRECT_SYMBOL,
+    DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
     DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
     DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
     DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
@@ -1365,8 +1365,6 @@ bool AsmParser::ParseStatement(ParseStat
       case DK_GLOBL:
       case DK_GLOBAL:
         return ParseDirectiveSymbolAttribute(MCSA_Global);
-      case DK_INDIRECT_SYMBOL:
-        return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
       case DK_LAZY_REFERENCE:
         return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
       case DK_NO_DEAD_STRIP:
@@ -3755,7 +3753,6 @@ void AsmParser::initializeDirectiveKindM
   DirectiveKindMap[".extern"] = DK_EXTERN;
   DirectiveKindMap[".globl"] = DK_GLOBL;
   DirectiveKindMap[".global"] = DK_GLOBAL;
-  DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL;
   DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
   DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
   DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;

Modified: llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp?rev=189497&r1=189496&r2=189497&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/DarwinAsmParser.cpp Wed Aug 28 12:50:59 2013
@@ -45,6 +45,8 @@ public:
     this->MCAsmParserExtension::Initialize(Parser);
 
     addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
+    addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
+      ".indirect_symbol");
     addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
     addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
       ".subsections_via_symbols");
@@ -163,6 +165,7 @@ public:
   }
 
   bool ParseDirectiveDesc(StringRef, SMLoc);
+  bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
   bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
   bool ParseDirectiveLsym(StringRef, SMLoc);
   bool ParseDirectiveLinkerOption(StringRef, SMLoc);
@@ -414,6 +417,39 @@ bool DarwinAsmParser::ParseDirectiveDesc
 
   return false;
 }
+
+/// ParseDirectiveIndirectSymbol
+///  ::= .indirect_symbol identifier
+bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
+  const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
+                                       getStreamer().getCurrentSection().first);
+  unsigned SectionType = Current->getType();
+  if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
+      SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+      SectionType != MCSectionMachO::S_SYMBOL_STUBS)
+    return Error(Loc, "indirect symbol not in a symbol pointer or stub "
+                      "section");
+
+  StringRef Name;
+  if (getParser().parseIdentifier(Name))
+    return TokError("expected identifier in .indirect_symbol directive");
+
+  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+  // Assembler local symbols don't make any sense here. Complain loudly.
+  if (Sym->isTemporary())
+    return TokError("non-local symbol required in directive");
+
+  if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
+    return TokError("unable to emit indirect symbol attribute for: " + Name);
+
+  if (getLexer().isNot(AsmToken::EndOfStatement))
+    return TokError("unexpected token in '.indirect_symbol' directive");
+
+  Lex();
+
+  return false;
+}
 
 /// ParseDirectiveDumpOrLoad
 ///  ::= ( .dump | .load ) "filename"

Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=189497&r1=189496&r2=189497&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/MachObjectWriter.cpp Wed Aug 28 12:50:59 2013
@@ -428,6 +428,22 @@ void MachObjectWriter::BindIndirectSymbo
   //
   // FIXME: Revisit this when the dust settles.
 
+  // Report errors for use of .indirect_symbol not in a symbol pointer section
+  // or stub section.
+  for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
+         ie = Asm.indirect_symbol_end(); it != ie; ++it) {
+    const MCSectionMachO &Section =
+      cast<MCSectionMachO>(it->SectionData->getSection());
+
+    if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
+        Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+        Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) {
+	MCSymbol &Symbol = *it->Symbol;
+	report_fatal_error("indirect symbol '" + Symbol.getName() +
+                           "' not in a symbol pointer or stub section");
+    }
+  }
+
   // Bind non lazy symbol pointers first.
   unsigned IndirectIndex = 0;
   for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),

Added: llvm/trunk/test/MC/MachO/bad-indirect-symbols.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/bad-indirect-symbols.s?rev=189497&view=auto
==============================================================================
--- llvm/trunk/test/MC/MachO/bad-indirect-symbols.s (added)
+++ llvm/trunk/test/MC/MachO/bad-indirect-symbols.s Wed Aug 28 12:50:59 2013
@@ -0,0 +1,5 @@
+// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - 2> %t.err > %t
+// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s
+
+x: .indirect_symbol _y
+// CHECK-ERROR: 4:4: error: indirect symbol not in a symbol pointer or stub section





More information about the llvm-commits mailing list