[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