X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCMachOStreamer.cpp;h=1b21249ca3212ccba9071fc54b7ed98b269c6165;hb=672b93a3324cc1da6d374eed4c75c050a9cad7be;hp=8759f2b51ca6c369d2e52f046887ea01847d7590;hpb=ba21957cbd7b25e3d25a3e9befe6151000242853;p=oota-llvm.git diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 8759f2b51ca..1b21249ca32 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -31,19 +31,20 @@ namespace { class MCMachOStreamer : public MCObjectStreamer { private: - virtual void EmitInstToFragment(const MCInst &Inst); virtual void EmitInstToData(const MCInst &Inst); public: MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter, true) {} + : MCObjectStreamer(Context, TAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ virtual void InitSections(); virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, + MCSymbol *EHSymbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitThumbFunc(MCSymbol *Func); virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); @@ -74,17 +75,11 @@ public: virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0); virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); - virtual void EmitGPRel32Value(const MCExpr *Value) { - assert(0 && "macho doesn't support this directive"); - } virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, unsigned MaxBytesToEmit = 0); virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0); - virtual void EmitValueToOffset(const MCExpr *Offset, - unsigned char Value = 0); virtual void EmitFileDirective(StringRef Filename) { // FIXME: Just ignore the .file; it isn't important enough to fail the @@ -92,12 +87,6 @@ public: //report_fatal_error("unsupported directive: '.file'"); } - virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { - // FIXME: Just ignore the .file; it isn't important enough to fail the - // entire assembly. - - //report_fatal_error("unsupported directive: '.file'"); - } virtual void Finish(); @@ -113,31 +102,31 @@ void MCMachOStreamer::InitSections() { } +void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, + MCSymbol *EHSymbol) { + MCSymbolData &SD = + getAssembler().getOrCreateSymbolData(*Symbol); + if (SD.isExternal()) + EmitSymbolAttribute(EHSymbol, MCSA_Global); + if (SD.getFlags() & SF_WeakDefinition) + EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition); + if (SD.isPrivateExtern()) + EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); +} + void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { - // TODO: This is almost exactly the same as WinCOFFStreamer. Consider merging - // into MCObjectStreamer. assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); - assert(CurSection && "Cannot emit before setting section!"); - - Symbol->setSection(*CurSection); - - MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + // isSymbolLinkerVisible uses the section. + Symbol->setSection(*getCurrentSection()); // We have to create a new fragment if this is an atom defining symbol, // fragments cannot span atoms. - if (getAssembler().isSymbolLinkerVisible(SD.getSymbol())) + if (getAssembler().isSymbolLinkerVisible(*Symbol)) new MCDataFragment(getCurrentSectionData()); - // FIXME: This is wasteful, we don't necessarily need to create a data - // fragment. Instead, we should mark the symbol as pointing into the data - // fragment if it exists, otherwise we should just queue the label and set its - // fragment pointer when we emit the next fragment. - MCDataFragment *F = getOrCreateDataFragment(); - assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); - SD.setFragment(F); - SD.setOffset(F->getContents().size()); + MCObjectStreamer::EmitLabel(Symbol); + MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); // This causes the reference type flag to be cleared. Darwin 'as' was "trying" // to clear the weak reference and weak definition bits too, but the // implementation was buggy. For now we just try to match 'as', for @@ -149,6 +138,9 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { } void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { + // Let the target do whatever target specific stuff it needs to do. + getAssembler().getBackend().HandleAssemblerFlag(Flag); + // Do any generic stuff we need to do. switch (Flag) { case MCAF_SyntaxUnified: return; // no-op here. case MCAF_Code16: return; // no-op here. @@ -161,8 +153,16 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { } } -void MCMachOStreamer::EmitThumbFunc(MCSymbol *Func) { +void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { // FIXME: Flag the function ISA as thumb with DW_AT_APPLE_isa. + + // Remember that the function is a thumb function. Fixup and relocation + // values will need adjusted. + getAssembler().setIsThumbFunc(Symbol); + + // Mark the thumb bit on the symbol. + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + SD.setFlags(SD.getFlags() | SF_ThumbFunc); } void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { @@ -206,6 +206,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeTLS: case MCSA_ELF_TypeCommon: case MCSA_ELF_TypeNoType: + case MCSA_ELF_TypeGnuUniqueObject: case MCSA_IndirectSymbol: case MCSA_Hidden: case MCSA_Internal: @@ -240,6 +241,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); @@ -323,26 +328,6 @@ void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); } -void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - MCDataFragment *DF = getOrCreateDataFragment(); - - // Avoid fixups when possible. - int64_t AbsValue; - if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { - // FIXME: Endianness assumption. - for (unsigned i = 0; i != Size; ++i) - DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); - } else { - DF->addFixup(MCFixup::Create(DF->getContents().size(), - AddValueSymbols(Value), - MCFixup::getKindForSize(Size))); - DF->getContents().resize(DF->getContents().size() + Size, 0); - } -} - void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit) { @@ -373,28 +358,6 @@ void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment, getCurrentSectionData()->setAlignment(ByteAlignment); } -void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset, - unsigned char Value) { - new MCOrgFragment(*Offset, Value, getCurrentSectionData()); -} - -void MCMachOStreamer::EmitInstToFragment(const MCInst &Inst) { - MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData()); - - // Add the fixups and data. - // - // FIXME: Revisit this design decision when relaxation is done, we may be - // able to get away with not storing any extra data in the MCInst. - SmallVector Fixups; - SmallString<256> Code; - raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); - VecOS.flush(); - - IF->getCode() = Code; - IF->getFixups() = Fixups; -} - void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { MCDataFragment *DF = getOrCreateDataFragment(); @@ -413,14 +376,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { } void MCMachOStreamer::Finish() { - // Dump out the dwarf file & directory tables and line tables. - if (getContext().hasDwarfFiles()) { - const MCSection *DwarfLineSection = getContext().getMachOSection("__DWARF", - "__debug_line", - MCSectionMachO::S_ATTR_DEBUG, - 0, SectionKind::getDataRelLocal()); - MCDwarfFileTable::Emit(this, DwarfLineSection); - } + EmitFrames(true); // We have to set the fragment atom associations so we can relax properly for // Mach-O.