[llvm-commits] [PATCH] MC abstraction and stub patches

Matt Fleming matt at console-pimps.org
Wed May 19 12:20:47 PDT 2010


Ping?

On Sun, 16 May 2010 18:55:04 +0100, Matt Fleming <matt at console-pimps.org> wrote:
> Hi,
> 
> attached are some patches to try and de-MachO-ify some of the MC code
> and put in some stubs to help with adding ELF support. These general
> cleanups will make adding ELF support easier. I've tried to arrange them
> to take into account the feedback that Daniel gave to the last set of
> patches.
> 
> I ran the DejaGNU tests and they still pass with these patches applied.
> 
> 0001-type-asm-directive.patch:
> This patch adds support for the ELF .type directive.
> 
> 0002-split-elfx86-asmbackend.patch:
> This splits the ELF X86 AsmBackend classes into 64Bit and 32Bit which
> will help when ELF support gets merged as the createObjectWriter
> implementations will differ for 64Bit and 32Bit.
> 
> 0003-target-streamer.patch:
> Currently createMachOStreamer is invoked directly in llvm-mc which isn't
> a good idea if we want to be able to use another object file
> format. This patch adds a createStreamer() factory method to the correct
> object file streamer to be instantiated for a given target triple.
> 
> 0004-section-abstraction.patch:
> 
> Instead of calling getMachOSection() directly when parsing section
> directives we should be asking the streamer backend to create the
> correct section given a section name. One thing I didn't understand when
> writing this patch was exactly how MCAsmStreamer should behave, hence
> the FIXME in MCAsmStreamer::LookupSection(). I've left the current
> behaviour in place, e.g. creating a MachOSection because I couldn't
> think of what else to do. I'm guessing the type of Section doesn't
> really matter?
> 
> Comments?
> 
> Index: llvm/lib/MC/MCParser/AsmParser.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCParser/AsmParser.cpp
> +++ llvm/lib/MC/MCParser/AsmParser.cpp
> @@ -13,6 +13,7 @@
>  
>  #include "llvm/MC/MCParser/AsmParser.h"
>  #include "llvm/ADT/SmallString.h"
> +#include "llvm/ADT/StringSwitch.h"
>  #include "llvm/ADT/Twine.h"
>  #include "llvm/MC/MCContext.h"
>  #include "llvm/MC/MCExpr.h"
> @@ -686,6 +687,8 @@ bool AsmParser::ParseStatement() {
>        return ParseDirectiveSymbolAttribute(MCSA_Protected);
>      if (IDVal == ".reference")
>        return ParseDirectiveSymbolAttribute(MCSA_Reference);
> +    if (IDVal == ".type")
> +      return ParseDirectiveELFType();
>      if (IDVal == ".weak")
>        return ParseDirectiveSymbolAttribute(MCSA_Weak);
>      if (IDVal == ".weak_definition")
> @@ -1241,6 +1244,52 @@ bool AsmParser::ParseDirectiveSymbolAttr
>    return false;  
>  }
>  
> +/// ParseDirectiveELFType
> +///  ::= .type identifier , @attribute
> +bool AsmParser::ParseDirectiveELFType() {
> +  StringRef Name;
> +  if (ParseIdentifier(Name))
> +    return TokError("expected identifier in directive");
> +
> +  // Handle the identifier as the key symbol.
> +  MCSymbol *Sym = CreateSymbol(Name);
> +
> +  if (Lexer.isNot(AsmToken::Comma))
> +    return TokError("unexpected token in '.type' directive");
> +  Lex();
> +
> +  if (Lexer.isNot(AsmToken::At))
> +    return TokError("expected '@' before type");
> +  Lex();
> +
> +  StringRef Type;
> +  SMLoc TypeLoc;
> +
> +  TypeLoc = Lexer.getLoc();
> +  if (ParseIdentifier(Type))
> +    return TokError("expected symbol type in directive");
> +
> +  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
> +    .Case("function", MCSA_ELF_TypeFunction)
> +    .Case("object", MCSA_ELF_TypeObject)
> +    .Case("tls_object", MCSA_ELF_TypeTLS)
> +    .Case("common", MCSA_ELF_TypeCommon)
> +    .Case("notype", MCSA_ELF_TypeNoType)
> +    .Default(MCSA_Invalid);
> +
> +  if (Attr == MCSA_Invalid)
> +    return Error(TypeLoc, "unsupported attribute in '.type' directive");
> +
> +  if (Lexer.isNot(AsmToken::EndOfStatement))
> +    return TokError("unexpected token in '.type' directive");
> +
> +  Lex();
> +
> +  Out.EmitSymbolAttribute(Sym, Attr);
> +
> +  return false;
> +}
> +
>  /// ParseDirectiveDarwinSymbolDesc
>  ///  ::= .desc identifier , expression
>  bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
> Index: llvm/include/llvm/MC/MCParser/AsmParser.h
> ===================================================================
> --- llvm.orig/include/llvm/MC/MCParser/AsmParser.h
> +++ llvm/include/llvm/MC/MCParser/AsmParser.h
> @@ -131,6 +131,7 @@ private:
>    /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
>    /// accepts a single symbol (which should be a label or an external).
>    bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
> +  bool ParseDirectiveELFType(); // ELF specific ".type"
>    bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
>    bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
>  
> Index: llvm/include/llvm/MC/MCParser/MCAsmLexer.h
> ===================================================================
> --- llvm.orig/include/llvm/MC/MCParser/MCAsmLexer.h
> +++ llvm/include/llvm/MC/MCParser/MCAsmLexer.h
> @@ -47,7 +47,7 @@ public:
>      Pipe, PipePipe, Caret, 
>      Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
>      Less, LessEqual, LessLess, LessGreater,
> -    Greater, GreaterEqual, GreaterGreater
> +    Greater, GreaterEqual, GreaterGreater, At
>    };
>  
>    TokenKind Kind;
> Index: llvm/lib/MC/MCParser/AsmLexer.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCParser/AsmLexer.cpp
> +++ llvm/lib/MC/MCParser/AsmLexer.cpp
> @@ -280,6 +280,7 @@ AsmToken AsmLexer::LexToken() {
>    case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
>    case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
>    case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
> +  case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
>    case '=': 
>      if (*CurPtr == '=')
>        return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
> Index: llvm/lib/Target/X86/X86AsmBackend.cpp
> ===================================================================
> --- llvm.orig/lib/Target/X86/X86AsmBackend.cpp
> +++ llvm/lib/Target/X86/X86AsmBackend.cpp
> @@ -211,6 +211,18 @@ public:
>    }
>  };
>  
> +class ELFX86_32AsmBackend : public ELFX86AsmBackend {
> +public:
> +  ELFX86_32AsmBackend(const Target &T)
> +    : ELFX86AsmBackend(T) {}
> +};
> +
> +class ELFX86_64AsmBackend : public ELFX86AsmBackend {
> +public:
> +  ELFX86_64AsmBackend(const Target &T)
> +    : ELFX86AsmBackend(T) {}
> +};
> +
>  class DarwinX86AsmBackend : public X86AsmBackend {
>  public:
>    DarwinX86AsmBackend(const Target &T)
> @@ -289,7 +301,7 @@ TargetAsmBackend *llvm::createX86_32AsmB
>    case Triple::Darwin:
>      return new DarwinX86_32AsmBackend(T);
>    default:
> -    return new ELFX86AsmBackend(T);
> +    return new ELFX86_32AsmBackend(T);
>    }
>  }
>  
> @@ -299,6 +311,6 @@ TargetAsmBackend *llvm::createX86_64AsmB
>    case Triple::Darwin:
>      return new DarwinX86_64AsmBackend(T);
>    default:
> -    return new ELFX86AsmBackend(T);
> +    return new ELFX86_64AsmBackend(T);
>    }
>  }
> Index: llvm/include/llvm/Target/TargetRegistry.h
> ===================================================================
> --- llvm.orig/include/llvm/Target/TargetRegistry.h
> +++ llvm/include/llvm/Target/TargetRegistry.h
> @@ -73,6 +73,13 @@ namespace llvm {
>      typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
>                                                  TargetMachine &TM,
>                                                  MCContext &Ctx);
> +    typedef MCStreamer *(*StreamerCtorTy)(const Target &T,
> +                                          const std::string &TT,
> +                                          MCContext &Ctx,
> +                                          TargetAsmBackend &TAB,
> +                                          raw_ostream &_OS,
> +                                          MCCodeEmitter *_Emitter,
> +                                          bool RelaxAll);
>  
>    private:
>      /// Next - The next registered target in the linked list, maintained by the
> @@ -126,6 +133,10 @@ namespace llvm {
>      /// if registered.
>      CodeEmitterCtorTy CodeEmitterCtorFn;
>  
> +    /// StreamerCtorFn - Construction function for this target's Streamer,
> +    /// if registered.
> +    StreamerCtorTy StreamerCtorFn;
> +
>    public:
>      /// @name Target Information
>      /// @{
> @@ -170,6 +181,9 @@ namespace llvm {
>      /// hasCodeEmitter - Check if this target supports instruction encoding.
>      bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
>  
> +    /// hasStreamer - Check if this target supports streaming to files.
> +    bool hasStreamer() const { return StreamerCtorFn != 0; }
> +
>      /// @}
>      /// @name Feature Constructors
>      /// @{
> @@ -258,6 +272,24 @@ namespace llvm {
>        return CodeEmitterCtorFn(*this, TM, Ctx);
>      }
>  
> +    /// createStreamer - Create a target specific MCStreamer.
> +    ///
> +    /// \arg TT - The target triple.
> +    /// \arg Ctx - The target context.
> +    /// \arg TAB - The target assembler backend object.
> +    /// \arg _OS - The stream object.
> +    /// \arg _Emitter - The target independent assembler object.
> +    /// \arg RelaxAll - Relax all fixups?
> +    MCStreamer *createStreamer(const std::string &TT, MCContext &Ctx,
> +                               TargetAsmBackend &TAB,
> +                               raw_ostream &_OS,
> +                               MCCodeEmitter *_Emitter,
> +                               bool RelaxAll) const {
> +      if (!StreamerCtorFn)
> +        return 0;
> +      return StreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
> +    }
> +
>      /// @}
>    };
>  
> @@ -479,6 +511,20 @@ namespace llvm {
>          T.CodeEmitterCtorFn = Fn;
>      }
>  
> +    /// RegisterStreamer - Register a MCStreamer implementation for the
> +    /// given target.
> +    ///
> +    /// Clients are responsible for ensuring that registration doesn't occur
> +    /// while another thread is attempting to access the registry. Typically
> +    /// this is done by initializing all targets at program startup.
> +    ///
> +    /// @param T - The target being registered.
> +    /// @param Fn - A function to construct an MCStreamer for the target.
> +    static void RegisterStreamer(Target &T, Target::StreamerCtorTy Fn) {
> +      if (!T.StreamerCtorFn)
> +        T.StreamerCtorFn = Fn;
> +    }
> +
>      /// @}
>    };
>  
> Index: llvm/tools/llvm-mc/llvm-mc.cpp
> ===================================================================
> --- llvm.orig/tools/llvm-mc/llvm-mc.cpp
> +++ llvm/tools/llvm-mc/llvm-mc.cpp
> @@ -304,7 +304,8 @@ static int AssembleInput(const char *Pro
>      assert(FileType == OFT_ObjectFile && "Invalid file type!");
>      CE.reset(TheTarget->createCodeEmitter(*TM, Ctx));
>      TAB.reset(TheTarget->createAsmBackend(TripleName));
> -    Str.reset(createMachOStreamer(Ctx, *TAB, *Out, CE.get(), RelaxAll));
> +    Str.reset(TheTarget->createStreamer(TripleName, Ctx, *TAB,
> +                                        *Out, CE.get(), RelaxAll));
>    }
>  
>    AsmParser Parser(SrcMgr, Ctx, *Str.get(), *MAI);
> Index: llvm/lib/Target/X86/X86TargetMachine.cpp
> ===================================================================
> --- llvm.orig/lib/Target/X86/X86TargetMachine.cpp
> +++ llvm/lib/Target/X86/X86TargetMachine.cpp
> @@ -17,6 +17,8 @@
>  #include "llvm/PassManager.h"
>  #include "llvm/CodeGen/MachineFunction.h"
>  #include "llvm/CodeGen/Passes.h"
> +#include "llvm/MC/MCCodeEmitter.h"
> +#include "llvm/MC/MCStreamer.h"
>  #include "llvm/Support/FormattedStream.h"
>  #include "llvm/Target/TargetOptions.h"
>  #include "llvm/Target/TargetRegistry.h"
> @@ -37,6 +39,18 @@ static MCAsmInfo *createMCAsmInfo(const
>    }
>  }
>  
> +static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
> +                                    MCContext &Ctx, TargetAsmBackend &TAB,
> +                                    raw_ostream &_OS,
> +                                    MCCodeEmitter *_Emitter,
> +                                    bool RelaxAll) {
> +  Triple TheTriple(TT);
> +  switch (TheTriple.getOS()) {
> +  default:
> +    return createMachOStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
> +  }
> +}
> +
>  extern "C" void LLVMInitializeX86Target() { 
>    // Register the target.
>    RegisterTargetMachine<X86_32TargetMachine> X(TheX86_32Target);
> @@ -57,6 +71,12 @@ extern "C" void LLVMInitializeX86Target(
>                                       createX86_32AsmBackend);
>    TargetRegistry::RegisterAsmBackend(TheX86_64Target,
>                                       createX86_64AsmBackend);
> +
> +  // Register the streamer.
> +  TargetRegistry::RegisterStreamer(TheX86_32Target,
> +                                   createMCStreamer);
> +  TargetRegistry::RegisterStreamer(TheX86_64Target,
> +                                   createMCStreamer);
>  }
>  
>  
> Index: llvm/lib/MC/MCParser/AsmParser.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCParser/AsmParser.cpp
> +++ llvm/lib/MC/MCParser/AsmParser.cpp
> @@ -23,6 +23,7 @@
>  #include "llvm/MC/MCSymbol.h"
>  #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
>  #include "llvm/Support/Compiler.h"
> +#include "llvm/Support/ELF.h"
>  #include "llvm/Support/SourceMgr.h"
>  #include "llvm/Support/raw_ostream.h"
>  #include "llvm/Target/TargetAsmParser.h"
> @@ -103,11 +104,9 @@ const AsmToken &AsmParser::Lex() {
>  bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
>    // Create the initial section, if requested.
>    //
> -  // FIXME: Target hook & command line option for initial section.
> +  // FIXME: Command line option for initial section.
>    if (!NoInitialTextSection)
> -    Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
> -                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> -                                      0, SectionKind::getText()));
> +    Out.SwitchSection(Out.LookupSection(".text"));
>  
>    // Prime the lexer.
>    Lex();
> @@ -482,145 +481,28 @@ bool AsmParser::ParseStatement() {
>      // FIXME: This should be driven based on a hash lookup and callback.
>      if (IDVal == ".section")
>        return ParseDirectiveDarwinSection();
> -    if (IDVal == ".text")
> -      // FIXME: This changes behavior based on the -static flag to the
> -      // assembler.
> -      return ParseDirectiveSectionSwitch("__TEXT", "__text",
> -                                     MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
> -    if (IDVal == ".const")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__const");
> -    if (IDVal == ".static_const")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
> -    if (IDVal == ".cstring")
> -      return ParseDirectiveSectionSwitch("__TEXT","__cstring", 
> -                                         MCSectionMachO::S_CSTRING_LITERALS);
> -    if (IDVal == ".literal4")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
> -                                         MCSectionMachO::S_4BYTE_LITERALS,
> -                                         4);
> -    if (IDVal == ".literal8")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
> -                                         MCSectionMachO::S_8BYTE_LITERALS,
> -                                         8);
> -    if (IDVal == ".literal16")
> -      return ParseDirectiveSectionSwitch("__TEXT","__literal16",
> -                                         MCSectionMachO::S_16BYTE_LITERALS,
> -                                         16);
> -    if (IDVal == ".constructor")
> -      return ParseDirectiveSectionSwitch("__TEXT","__constructor");
> -    if (IDVal == ".destructor")
> -      return ParseDirectiveSectionSwitch("__TEXT","__destructor");
> -    if (IDVal == ".fvmlib_init0")
> -      return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
> -    if (IDVal == ".fvmlib_init1")
> -      return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
> -
> -    // FIXME: The assembler manual claims that this has the self modify code
> -    // flag, at least on x86-32, but that does not appear to be correct.
> -    if (IDVal == ".symbol_stub")
> -      return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
> -                                         MCSectionMachO::S_SYMBOL_STUBS |
> -                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> -                                          // FIXME: Different on PPC and ARM.
> -                                         0, 16);
> -    // FIXME: PowerPC only?
> -    if (IDVal == ".picsymbol_stub")
> -      return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
> -                                         MCSectionMachO::S_SYMBOL_STUBS |
> -                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> -                                         0, 26);
> -    if (IDVal == ".data")
> -      return ParseDirectiveSectionSwitch("__DATA", "__data");
> -    if (IDVal == ".static_data")
> -      return ParseDirectiveSectionSwitch("__DATA", "__static_data");
> -
> -    // FIXME: The section names of these two are misspelled in the assembler
> -    // manual.
> -    if (IDVal == ".non_lazy_symbol_pointer")
> -      return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
> -                                     MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
> -                                         4);
> -    if (IDVal == ".lazy_symbol_pointer")
> -      return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
> -                                         MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
> -                                         4);
> -
> -    if (IDVal == ".dyld")
> -      return ParseDirectiveSectionSwitch("__DATA", "__dyld");
> -    if (IDVal == ".mod_init_func")
> -      return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
> -                                       MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
> -                                         4);
> -    if (IDVal == ".mod_term_func")
> -      return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
> -                                       MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
> -                                         4);
> -    if (IDVal == ".const_data")
> -      return ParseDirectiveSectionSwitch("__DATA", "__const");
> -    
> -    
> -    if (IDVal == ".objc_class")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__class", 
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_meta_class")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_cat_cls_meth")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_cat_inst_meth")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_protocol")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_string_object")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_cls_meth")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_inst_meth")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_cls_refs")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
> -                                         MCSectionMachO::S_LITERAL_POINTERS,
> -                                         4);
> -    if (IDVal == ".objc_message_refs")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
> -                                         MCSectionMachO::S_LITERAL_POINTERS,
> -                                         4);
> -    if (IDVal == ".objc_symbols")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_category")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__category",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_class_vars")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_instance_vars")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_module_info")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
> -                                         MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
> -    if (IDVal == ".objc_class_names")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
> -                                         MCSectionMachO::S_CSTRING_LITERALS);
> -    if (IDVal == ".objc_meth_var_types")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
> -                                         MCSectionMachO::S_CSTRING_LITERALS);
> -    if (IDVal == ".objc_meth_var_names")
> -      return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
> -                                         MCSectionMachO::S_CSTRING_LITERALS);
> -    if (IDVal == ".objc_selector_strs")
> -      return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
> -                                         MCSectionMachO::S_CSTRING_LITERALS);
> -    
> +
> +    if (IDVal == ".text" || IDVal == ".const" || IDVal == ".static_const" ||
> +        IDVal == ".cstring" || IDVal == ".literal4" || IDVal == ".literal8" ||
> +        IDVal == ".literal16" || IDVal == ".constructor" ||
> +        IDVal == ".destructor" || IDVal == ".fvmlib_init0" ||
> +        IDVal == ".fvmlib_init1" || IDVal == ".symbol_stub" ||
> +        IDVal == ".picsymbol_stub" || IDVal == ".data" ||
> +        IDVal == ".static_data" || IDVal == ".non_lazy_symbol_pointer" ||
> +        IDVal == ".lazy_symbol_pointer" || IDVal == ".dyld" ||
> +        IDVal == ".mod_init_func" || IDVal == ".mod_term_func" ||
> +        IDVal == ".const_data" || IDVal == ".objc_class" ||
> +        IDVal == ".objc_meta_class" || IDVal == ".objc_cat_cls_meth" ||
> +        IDVal == ".objc_cat_inst_meth" || IDVal == ".objc_protocol" ||
> +        IDVal == ".objc_string_object" || IDVal == ".objc_cls_meth" ||
> +        IDVal == ".objc_inst_meth" || IDVal == ".objc_cls_refs" ||
> +        IDVal == ".objc_message_refs" || IDVal == ".objc_symbols" ||
> +        IDVal == ".objc_category" || IDVal == ".objc_class_vars" ||
> +        IDVal == ".objc_instance_vars" || IDVal == ".objc_module_info" ||
> +        IDVal == ".objc_class_names" || IDVal == ".objc_meth_var_types" ||
> +        IDVal == ".objc_meth_var_names" || IDVal == ".objc_selector_strs")
> +      return ParseDirectiveSectionSwitch(IDVal);
> +
>      // Assembler features
>      if (IDVal == ".set")
>        return ParseDirectiveSet();
> @@ -886,30 +768,12 @@ bool AsmParser::ParseDirectiveDarwinSect
>  }
>  
>  /// ParseDirectiveSectionSwitch - 
> -bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
> -                                            const char *Section,
> -                                            unsigned TAA, unsigned Align,
> -                                            unsigned StubSize) {
> +bool AsmParser::ParseDirectiveSectionSwitch(StringRef Section) {
>    if (Lexer.isNot(AsmToken::EndOfStatement))
>      return TokError("unexpected token in section switching directive");
>    Lex();
>    
> -  // FIXME: Arch specific.
> -  bool isText = StringRef(Segment) == "__TEXT";  // FIXME: Hack.
> -  Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
> -                                        isText ? SectionKind::getText()
> -                                               : SectionKind::getDataRel()));
> -
> -  // Set the implicit alignment, if any.
> -  //
> -  // FIXME: This isn't really what 'as' does; I think it just uses the implicit
> -  // alignment on the section (e.g., if one manually inserts bytes into the
> -  // section, then just issueing the section switch directive will not realign
> -  // the section. However, this is arguably more reasonable behavior, and there
> -  // is no good reason for someone to intentionally emit incorrectly sized
> -  // values into the implicitly aligned sections.
> -  if (Align)
> -    Out.EmitValueToAlignment(Align, 0, 1, 0);
> +  Out.SwitchSection(Out.LookupSection(Section));
>  
>    return false;
>  }
> Index: llvm/include/llvm/MC/MCParser/AsmParser.h
> ===================================================================
> --- llvm.orig/include/llvm/MC/MCParser/AsmParser.h
> +++ llvm/include/llvm/MC/MCParser/AsmParser.h
> @@ -116,9 +116,7 @@ private:
>    
>    // Directive Parsing.
>    bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
> -  bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section,
> -                                   unsigned TAA = 0, unsigned ImplicitAlign = 0,
> -                                   unsigned StubSize = 0);
> +  bool ParseDirectiveSectionSwitch(StringRef Section);
>    bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
>    bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
>    bool ParseDirectiveFill(); // ".fill"
> Index: llvm/include/llvm/MC/MCStreamer.h
> ===================================================================
> --- llvm.orig/include/llvm/MC/MCStreamer.h
> +++ llvm/include/llvm/MC/MCStreamer.h
> @@ -102,6 +102,9 @@ namespace llvm {
>      /// This corresponds to assembler directives like .section, .text, etc.
>      virtual void SwitchSection(const MCSection *Section) = 0;
>      
> +    /// LookupSection - Return the corresponding output section for @Section.
> +    virtual const MCSection *LookupSection(StringRef Section) = 0;
> +
>      /// EmitLabel - Emit a label for @p Symbol into the current section.
>      ///
>      /// This corresponds to an assembler statement such as:
> Index: llvm/lib/MC/MCMachOStreamer.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCMachOStreamer.cpp
> +++ llvm/lib/MC/MCMachOStreamer.cpp
> @@ -15,6 +15,7 @@
>  #include "llvm/MC/MCExpr.h"
>  #include "llvm/MC/MCInst.h"
>  #include "llvm/MC/MCSection.h"
> +#include "llvm/MC/MCSectionMachO.h"
>  #include "llvm/MC/MCSymbol.h"
>  #include "llvm/MC/MCMachOSymbolFlags.h"
>  #include "llvm/Support/ErrorHandling.h"
> @@ -95,10 +96,41 @@ public:
>      return Value;
>    }
>  
> +  // Set the implicit alignment, if any.
> +  //
> +  // FIXME: This isn't really what 'as' does; I think it just uses the implicit
> +  // alignment on the section (e.g., if one manually inserts bytes into the
> +  // section, then just issueing the section switch directive will not realign
> +  // the section. However, this is arguably more reasonable behavior, and there
> +  // is no good reason for someone to intentionally emit incorrectly sized
> +  // values into the implicitly aligned sections.
> +  const MCSection *AlignedSection(StringRef Segment,
> +                                  StringRef Section,
> +                                  unsigned TypeAndAttributes,
> +                                  unsigned Reserved2,
> +                                  SectionKind K,
> +                                  unsigned Align) {
> +    const MCSection *S = getContext().getMachOSection(Segment, Section,
> +                                                      TypeAndAttributes,
> +                                                      Reserved2, K);
> +
> +    MCSectionData *SD = &Assembler.getOrCreateSectionData(*S);
> +
> +    MCFragment *F = new MCAlignFragment(Align, 0, 1, Align, SD);
> +    F->setAtom(CurrentAtomMap.lookup(SD));
> +
> +    // Update the maximum alignment on the current section if necessary.
> +    if (Align > SD->getAlignment())
> +      SD->setAlignment(Align);
> +
> +    return S;
> +  }
> +
>    /// @name MCStreamer Interface
>    /// @{
>  
>    virtual void SwitchSection(const MCSection *Section);
> +  virtual const MCSection *LookupSection(StringRef Section);
>    virtual void EmitLabel(MCSymbol *Symbol);
>    virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
>    virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
> @@ -166,6 +198,178 @@ void MCMachOStreamer::SwitchSection(cons
>    CurSectionData = &Assembler.getOrCreateSectionData(*Section);
>  }
>  
> +
> +const MCSection *MCMachOStreamer::LookupSection(StringRef S) {
> +
> +  MCContext &Ctx = getContext();
> +
> +    if (S == ".text") {
> +      return Ctx.getMachOSection("__TEXT", "__text",
> +                                 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> +                                 0, SectionKind::getText());
> +    } else if (S == ".const") {
> +      return Ctx.getMachOSection("__TEXT", "__const", 0, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".static_const") {
> +      return Ctx.getMachOSection("__TEXT", "__static_const", 0, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".cstring") {
> +      return Ctx.getMachOSection("__TEXT","__cstring",
> +                                 MCSectionMachO::S_CSTRING_LITERALS, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".literal4") {
> +      return AlignedSection("__TEXT", "__literal4",
> +                            MCSectionMachO::S_4BYTE_LITERALS,
> +                            0, SectionKind::getText(), 4);
> +    } else if (S == ".literal8") {
> +      return AlignedSection("__TEXT", "__literal8",
> +                            MCSectionMachO::S_8BYTE_LITERALS,
> +                            0, SectionKind::getText(), 8);
> +    } else if (S == ".literal16") {
> +      return AlignedSection("__TEXT","__literal16",
> +                            MCSectionMachO::S_16BYTE_LITERALS,
> +                            0, SectionKind::getText(), 16);
> +    } else if (S == ".constructor") {
> +      return Ctx.getMachOSection("__TEXT","__constructor", 0, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".destructor") {
> +      return Ctx.getMachOSection("__TEXT","__destructor", 0, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".fvmlib_init0") {
> +      return Ctx.getMachOSection("__TEXT","__fvmlib_init0", 0, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".fvmlib_init1") {
> +      return Ctx.getMachOSection("__TEXT","__fvmlib_init1", 0, 0,
> +                                 SectionKind::getText());
> +
> +    // FIXME: The assembler manual claims that this has the self modify code
> +    // flag, at least on x86-32, but that does not appear to be correct.
> +    } else if (S == ".symbol_stub") {
> +      return Ctx.getMachOSection("__TEXT","__symbol_stub",
> +                                 MCSectionMachO::S_SYMBOL_STUBS |
> +                                 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> +                                 // FIXME: Different on PPC and ARM.
> +                                 16, SectionKind::getText());
> +    // FIXME: PowerPC only?
> +    } else if (S == ".picsymbol_stub") {
> +      return Ctx.getMachOSection("__TEXT","__picsymbol_stub",
> +                                 MCSectionMachO::S_SYMBOL_STUBS |
> +                                 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> +                                 26, SectionKind::getText());
> +    } else if (S == ".data") {
> +      return Ctx.getMachOSection("__DATA", "__data", 0, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".static_data") {
> +      return Ctx.getMachOSection("__DATA", "__static_data", 0, 0,
> +                                 SectionKind::getDataRel());
> +
> +    // FIXME: The section names of these two are misspelled in the assembler
> +    // manual.
> +    } else if (S == ".non_lazy_symbol_pointer") {
> +      return AlignedSection("__DATA", "__nl_symbol_ptr",
> +                            MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".lazy_symbol_pointer") {
> +      return AlignedSection("__DATA", "__la_symbol_ptr",
> +                            MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".dyld") {
> +      return Ctx.getMachOSection("__DATA", "__dyld", 0, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".mod_init_func") {
> +      return AlignedSection("__DATA", "__mod_init_func",
> +                            MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".mod_term_func") {
> +      return AlignedSection("__DATA", "__mod_term_func",
> +                            MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".const_data") {
> +      return Ctx.getMachOSection("__DATA", "__const", 0, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_class") {
> +      return Ctx.getMachOSection("__OBJC", "__class",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_meta_class") {
> +      return Ctx.getMachOSection("__OBJC", "__meta_class",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_cat_cls_meth") {
> +      return Ctx.getMachOSection("__OBJC", "__cat_cls_meth",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_cat_inst_meth") {
> +      return Ctx.getMachOSection("__OBJC", "__cat_inst_meth",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_protocol") {
> +      return Ctx.getMachOSection("__OBJC", "__protocol",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_string_object") {
> +      return Ctx.getMachOSection("__OBJC", "__string_object",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_cls_meth") {
> +      return Ctx.getMachOSection("__OBJC", "__cls_meth",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_inst_meth") {
> +      return Ctx.getMachOSection("__OBJC", "__inst_meth",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_cls_refs") {
> +      return AlignedSection("__OBJC", "__cls_refs",
> +                            MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
> +                            MCSectionMachO::S_LITERAL_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".objc_message_refs") {
> +      return AlignedSection("__OBJC", "__message_refs",
> +                            MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
> +                            MCSectionMachO::S_LITERAL_POINTERS,
> +                            0, SectionKind::getDataRel(), 4);
> +    } else if (S == ".objc_symbols") {
> +      return Ctx.getMachOSection("__OBJC", "__symbols",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_category") {
> +      return Ctx.getMachOSection("__OBJC", "__category",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_class_vars") {
> +      return Ctx.getMachOSection("__OBJC", "__class_vars",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_instance_vars") {
> +      return Ctx.getMachOSection("__OBJC", "__instance_vars",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_module_info") {
> +      return Ctx.getMachOSection("__OBJC", "__module_info",
> +                                 MCSectionMachO::S_ATTR_NO_DEAD_STRIP, 0,
> +                                 SectionKind::getDataRel());
> +    } else if (S == ".objc_class_names") {
> +      return Ctx.getMachOSection("__TEXT", "__cstring",
> +                                 MCSectionMachO::S_CSTRING_LITERALS, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".objc_meth_var_types") {
> +      return Ctx.getMachOSection("__TEXT", "__cstring",
> +                                 MCSectionMachO::S_CSTRING_LITERALS, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".objc_meth_var_names") {
> +      return Ctx.getMachOSection("__TEXT", "__cstring",
> +                                 MCSectionMachO::S_CSTRING_LITERALS, 0,
> +                                 SectionKind::getText());
> +    } else if (S == ".objc_selector_strs") {
> +      return Ctx.getMachOSection("__OBJC", "__selector_strs",
> +                                 MCSectionMachO::S_CSTRING_LITERALS, 0,
> +                                 SectionKind::getDataRel());
> +    }
> +
> +   return 0;
> +}
> +
>  void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
>    assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
>    assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
> Index: llvm/lib/MC/MCAsmStreamer.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCAsmStreamer.cpp
> +++ llvm/lib/MC/MCAsmStreamer.cpp
> @@ -100,6 +100,15 @@ public:
>  
>    virtual void SwitchSection(const MCSection *Section);
>  
> +  virtual const MCSection *LookupSection(StringRef Section) {
> +    // FIXME: What sort of section should we create? Does it even
> +    // matter? I think we're just doing this to appease the other
> +    // layers.
> +    return getContext().getMachOSection("__TEXT", ".text",
> +                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
> +                                   0, SectionKind::getText());
> +  }
> +
>    virtual void EmitLabel(MCSymbol *Symbol);
>  
>    virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
> Index: llvm/lib/MC/MCNullStreamer.cpp
> ===================================================================
> --- llvm.orig/lib/MC/MCNullStreamer.cpp
> +++ llvm/lib/MC/MCNullStreamer.cpp
> @@ -13,6 +13,7 @@
>  #include "llvm/MC/MCInst.h"
>  #include "llvm/MC/MCSectionMachO.h"
>  #include "llvm/MC/MCSymbol.h"
> +#include "llvm/Support/raw_ostream.h"
>  
>  using namespace llvm;
>  
> @@ -29,6 +30,11 @@ namespace {
>        CurSection = Section;
>      }
>  
> +    virtual const MCSection *LookupSection(StringRef Section) {
> +      errs() << "FIXME: MCNullStreamer:LookupSection not implemented\n";
> +      return 0;
> +    }
> +
>      virtual void EmitLabel(MCSymbol *Symbol) {
>        assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
>        assert(CurSection && "Cannot emit before setting section!");
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list