MCMachOStreamer.cpp revision c304718fd8fa25f3f36f47f3de0e0cfe7578bc9e
1fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===// 2fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 3fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// The LLVM Compiler Infrastructure 4fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 5fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// This file is distributed under the University of Illinois Open Source 6fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// License. See LICENSE.TXT for details. 7fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar// 8fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar//===----------------------------------------------------------------------===// 9fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 10fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCStreamer.h" 11fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 12fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCAssembler.h" 13fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCContext.h" 144fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCCodeEmitter.h" 158c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar#include "llvm/MC/MCExpr.h" 164fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCInst.h" 17fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSection.h" 18fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSymbol.h" 19fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 204fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/Support/raw_ostream.h" 21d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar#include "llvm/Target/TargetAsmBackend.h" 22d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar 23fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm; 24fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 25fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarnamespace { 26fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 27fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MCMachOStreamer : public MCStreamer { 286aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest 296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar /// 16 bits of the implementation defined flags. 306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar enum SymbolFlags { // See <mach-o/nlist.h>. 316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_DescFlagsMask = 0xFFFF, 326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Reference type flags. 346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeMask = 0x0007, 356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeUndefinedNonLazy = 0x0000, 366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeUndefinedLazy = 0x0001, 376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeDefined = 0x0002, 386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateDefined = 0x0003, 396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, 406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateUndefinedLazy = 0x0005, 416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Other 'desc' flags. 436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_NoDeadStrip = 0x0020, 446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_WeakReference = 0x0040, 456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_WeakDefinition = 0x0080 466aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar }; 476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 486aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbarprivate: 49fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar MCAssembler Assembler; 50fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar MCSectionData *CurSectionData; 51f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 52f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarprivate: 53f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCFragment *getCurrentFragment() const { 54f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(CurSectionData && "No current section!"); 55f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 56f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!CurSectionData->empty()) 57f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar return &CurSectionData->getFragmentList().back(); 58f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 59f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar return 0; 60f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 61f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 62f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar /// Get a data fragment to write into, creating a new one if the current 63f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar /// fragment is not a data fragment. 64f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar MCDataFragment *getOrCreateDataFragment() const { 65f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 66f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar if (!F) 67f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar F = new MCDataFragment(CurSectionData); 68f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar return F; 69f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar } 70f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar 71fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic: 721f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 731f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar raw_ostream &_OS, MCCodeEmitter *_Emitter) 74cf871e5abff63a53f9e97ff9e37fb7297d0cb847Daniel Dunbar : MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS), 754fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar CurSectionData(0) {} 76fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar ~MCMachOStreamer() {} 77fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 78ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar MCAssembler &getAssembler() { return Assembler; } 79ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar 808c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCExpr *AddValueSymbols(const MCExpr *Value) { 818c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar switch (Value->getKind()) { 825d917a8952c09a345180ec36f0df4ee5dd5eddeaChris Lattner case MCExpr::Target: assert(0 && "Can't handle target exprs yet!"); 838c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar case MCExpr::Constant: 848c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar break; 858c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 868c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar case MCExpr::Binary: { 878c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 888c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar AddValueSymbols(BE->getLHS()); 898c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar AddValueSymbols(BE->getRHS()); 908c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar break; 918c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar } 928c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 938c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar case MCExpr::SymbolRef: 9446836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar Assembler.getOrCreateSymbolData( 9546836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar cast<MCSymbolRefExpr>(Value)->getSymbol()); 968c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar break; 978c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 988c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar case MCExpr::Unary: 998c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 1008c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar break; 1018c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar } 1028c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 1038c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar return Value; 1048c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar } 1058c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar 106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @name MCStreamer Interface 107fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @{ 108fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 109fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void SwitchSection(const MCSection *Section); 110fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitLabel(MCSymbol *Symbol); 111a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 112821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 113a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 114fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 1159eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 1167092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar unsigned ByteAlignment); 11799328add833807f12a4950c7de29fb2a5df04703Chris Lattner virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 11899328add833807f12a4950c7de29fb2a5df04703Chris Lattner assert(0 && "macho doesn't support this directive"); 11999328add833807f12a4950c7de29fb2a5df04703Chris Lattner } 1209eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 1219eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner assert(0 && "macho doesn't support this directive"); 1229eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner } 1238751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 1247092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar unsigned Size = 0, unsigned ByteAlignment = 0); 125aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 126aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 127718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner virtual void EmitGPRel32Value(const MCExpr *Value) { 128718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner assert(0 && "macho doesn't support this directive"); 129718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner } 130fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 131fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned ValueSize = 1, 132fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned MaxBytesToEmit = 0); 1336e72048add2a6464e038121c6c275da37528aa0aKevin Enderby virtual void EmitCodeAlignment(unsigned ByteAlignment, 1346e72048add2a6464e038121c6c275da37528aa0aKevin Enderby unsigned MaxBytesToEmit = 0); 135821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar virtual void EmitValueToOffset(const MCExpr *Offset, 136fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned char Value = 0); 137a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 138a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner virtual void EmitFileDirective(StringRef Filename) { 139a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner errs() << "FIXME: MCMachoStreamer:EmitFileDirective not implemented\n"; 140a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 141a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { 142a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner errs() << "FIXME: MCMachoStreamer:EmitDwarfFileDirective not implemented\n"; 143a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner } 144a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner 145fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitInstruction(const MCInst &Inst); 146fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void Finish(); 147fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 148fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @} 149fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}; 150fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 151fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} // end anonymous namespace. 152fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 153fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::SwitchSection(const MCSection *Section) { 154fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar assert(Section && "Cannot switch to a null section!"); 155cda7f78233b889772e1454a1246130c576681bb8Chris Lattner 156cda7f78233b889772e1454a1246130c576681bb8Chris Lattner // If already in this section, then this is a noop. 157cda7f78233b889772e1454a1246130c576681bb8Chris Lattner if (Section == CurSection) return; 158fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1590f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar CurSection = Section; 16046836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar CurSectionData = &Assembler.getOrCreateSectionData(*Section); 161fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 162fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 163fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { 1648906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 165c304718fd8fa25f3f36f47f3de0e0cfe7578bc9eDaniel Dunbar assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 166c304718fd8fa25f3f36f47f3de0e0cfe7578bc9eDaniel Dunbar assert(CurSection && "Cannot emit before setting section!"); 167fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 168f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar // FIXME: This is wasteful, we don't necessarily need to create a data 169f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar // fragment. Instead, we should mark the symbol as pointing into the data 170f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar // fragment if it exists, otherwise we should just queue the label and set its 171f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar // fragment pointer when we emit the next fragment. 172f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar MCDataFragment *F = getOrCreateDataFragment(); 17346836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 174f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 175f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SD.setFragment(F); 176f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SD.setOffset(F->getContents().size()); 1776aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 1786aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // This causes the reference type and weak reference flags to be cleared. 1796aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask)); 180f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 1818906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar Symbol->setSection(*CurSection); 182fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 183fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 184a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattnervoid MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 1856009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar switch (Flag) { 186a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCAF_SubsectionsViaSymbols: 1876009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Assembler.setSubsectionsViaSymbols(true); 1888c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar return; 1896009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar } 1908c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar 1918c3eaf46a1fb69004723ce78aaa82965d6474175Daniel Dunbar assert(0 && "invalid assembler flag!"); 192fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 193fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 194821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarvoid MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 195a4d8667c870759a70aa9bea99e64b7f7e938b1a1Daniel Dunbar // FIXME: Lift context changes into super class. 196a4d8667c870759a70aa9bea99e64b7f7e938b1a1Daniel Dunbar // FIXME: Set associated section. 19708a408a4b3224627db07eb27e174085d8e1d2426Daniel Dunbar Symbol->setVariableValue(AddValueSymbols(Value)); 198fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 199fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 200fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 201a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner MCSymbolAttr Attribute) { 2020c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Indirect symbols are handled differently, to match how 'as' handles 2030c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // them. This makes writing matching .o files easier. 204a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner if (Attribute == MCSA_IndirectSymbol) { 205ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Note that we intentionally cannot use the symbol data here; this is 206ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // important for matching the string table that 'as' generates. 2070c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar IndirectSymbolData ISD; 2080c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ISD.Symbol = Symbol; 2090c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ISD.SectionData = CurSectionData; 2100c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar Assembler.getIndirectSymbols().push_back(ISD); 2110c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar return; 2120c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 2130c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 2146aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Adding a symbol attribute always introduces the symbol, note that an 21546836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar // important side effect of calling getOrCreateSymbolData here is to register 21646836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar // the symbol with the assembler. 21746836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 2186aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2196aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // The implementation of symbol attributes is designed to match 'as', but it 2206aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // leaves much to desired. It doesn't really make sense to arbitrarily add and 2216aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // remove flags, but 'as' allows this (in particular, see .desc). 2226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // 2236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // In the future it might be worth trying to make these operations more well 2246aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // defined. 2253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar switch (Attribute) { 226a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Invalid: 227ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeFunction: 228ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeIndFunction: 229ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeObject: 230ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeTLS: 231ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeCommon: 232ed0ab15170f0f8fc4269d58757378bc8726b56a1Chris Lattner case MCSA_ELF_TypeNoType: 233a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_IndirectSymbol: 234a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Hidden: 235a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Internal: 236a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Protected: 237a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Weak: 238a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Local: 2396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar assert(0 && "Invalid symbol attribute for Mach-O!"); 2406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2413edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 242a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Global: 2438f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar SD.setExternal(true); 2443edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar break; 2456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 246a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_LazyReference: 2476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: This requires -dynamic. 2486aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 2496aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar if (Symbol->isUndefined()) 2506aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy); 2516aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2536aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Since .reference sets the no dead strip bit, it is equivalent to 2546aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // .no_dead_strip in practice. 255a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_Reference: 256a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_NoDeadStrip: 2576aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 2586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 260a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_PrivateExtern: 2616aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setExternal(true); 2626aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setPrivateExtern(true); 2636aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 265a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_WeakReference: 2666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: This requires -dynamic. 2676aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar if (Symbol->isUndefined()) 2686aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_WeakReference); 2696aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2706aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 271a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner case MCSA_WeakDefinition: 2726aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: 'as' enforces that this is defined and global. The manual claims 2736aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // it has to be in a coalesced section, but this isn't enforced. 2746aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_WeakDefinition); 2756aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2763edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 277fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 278fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 279fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 2806aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Encode the 'desc' value into the lowest implementation defined bits. 2816aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar assert(DescValue == (DescValue & SF_DescFlagsMask) && 2826aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar "Invalid .desc value!"); 28346836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); 284fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 285fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2869eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattnervoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 2877092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar unsigned ByteAlignment) { 2888f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 2898f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 2908f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 29146836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 2928f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar SD.setExternal(true); 2937092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar SD.setCommon(Size, ByteAlignment); 294fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 295fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2968751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbarvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 2977092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar unsigned Size, unsigned ByteAlignment) { 29846836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section); 299d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 300d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // The symbol may not be present, which only creates the section. 301d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (!Symbol) 302d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar return; 303d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 304d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // FIXME: Assert that this section has the zerofill type. 305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 306d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 307d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 30846836a783ab29f9cb49655d8b9cb8f5538a626feDaniel Dunbar MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 309d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 3107092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData); 311d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFragment(F); 312d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 313d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar Symbol->setSection(*Section); 314d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 315d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Update the maximum alignment on the zero fill section if necessary. 316d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (ByteAlignment > SectData.getAlignment()) 317d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SectData.setAlignment(ByteAlignment); 318fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 319fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 320aaec205b87637cd0d59d4f11630db603686eb73dChris Lattnervoid MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 321f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 322fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 323fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 324aaec205b87637cd0d59d4f11630db603686eb73dChris Lattnervoid MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size, 325aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner unsigned AddrSpace) { 326f70f477024a23408d3a535920e6d4750478ac9aeDaniel Dunbar MCDataFragment *DF = getOrCreateDataFragment(); 32745f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar 32845f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar // Avoid fixups when possible. 32945f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar int64_t AbsValue; 33040ebe2473a2032356daccf05d4e5ffe39f437c8dDaniel Dunbar if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 33145f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar // FIXME: Endianness assumption. 33245f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar for (unsigned i = 0; i != Size; ++i) 33345f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 33445f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar } else { 3358315a357e48f2eeb4fa929168d3cb65924d9893eDaniel Dunbar DF->addFixup(MCAsmFixup(DF->getContents().size(), *AddValueSymbols(Value), 3368315a357e48f2eeb4fa929168d3cb65924d9893eDaniel Dunbar MCFixup::getKindForSize(Size))); 33745f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar DF->getContents().resize(DF->getContents().size() + Size, 0); 33845f48746110f5e6f7e65af7de239333dbd45d1d1Daniel Dunbar } 339fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 340fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 341fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, 342fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar int64_t Value, unsigned ValueSize, 343fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned MaxBytesToEmit) { 344d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar if (MaxBytesToEmit == 0) 345d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MaxBytesToEmit = ByteAlignment; 3460705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 3476e72048add2a6464e038121c6c275da37528aa0aKevin Enderby false /* EmitNops */, CurSectionData); 3486e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 3496e72048add2a6464e038121c6c275da37528aa0aKevin Enderby // Update the maximum alignment on the current section if necessary. 3506e72048add2a6464e038121c6c275da37528aa0aKevin Enderby if (ByteAlignment > CurSectionData->getAlignment()) 3516e72048add2a6464e038121c6c275da37528aa0aKevin Enderby CurSectionData->setAlignment(ByteAlignment); 3526e72048add2a6464e038121c6c275da37528aa0aKevin Enderby} 3536e72048add2a6464e038121c6c275da37528aa0aKevin Enderby 3546e72048add2a6464e038121c6c275da37528aa0aKevin Enderbyvoid MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment, 3556e72048add2a6464e038121c6c275da37528aa0aKevin Enderby unsigned MaxBytesToEmit) { 3566e72048add2a6464e038121c6c275da37528aa0aKevin Enderby if (MaxBytesToEmit == 0) 3576e72048add2a6464e038121c6c275da37528aa0aKevin Enderby MaxBytesToEmit = ByteAlignment; 3588f9b80e5df12779a56d763ebf20864dad2bc72daDaniel Dunbar new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 3596e72048add2a6464e038121c6c275da37528aa0aKevin Enderby true /* EmitNops */, CurSectionData); 3600705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 361f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Update the maximum alignment on the current section if necessary. 3620705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (ByteAlignment > CurSectionData->getAlignment()) 3630705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar CurSectionData->setAlignment(ByteAlignment); 364fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 365fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 366821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbarvoid MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset, 367fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned char Value) { 3681253a6fa3b0d79dc6ea25f2578f6473219d40047Daniel Dunbar new MCOrgFragment(*Offset, Value, CurSectionData); 369fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 370fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 371fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitInstruction(const MCInst &Inst) { 3724fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar // Scan for values. 3734fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar for (unsigned i = 0; i != Inst.getNumOperands(); ++i) 3748c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar if (Inst.getOperand(i).isExpr()) 3758c2eebe4074ef218b30d94358f6b2e45c079605cDaniel Dunbar AddValueSymbols(Inst.getOperand(i).getExpr()); 3764fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar 377e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar CurSectionData->setHasInstructions(true); 378e1ec617c6abf0b9dc1eecbbfe483bda3bb2b7795Daniel Dunbar 3793f4dcd92daef80f87919507b6baf2a97d4bfaa2eDaniel Dunbar // FIXME-PERF: Common case is that we don't need to relax, encode directly 3803f4dcd92daef80f87919507b6baf2a97d4bfaa2eDaniel Dunbar // onto the data fragments buffers. 3813f4dcd92daef80f87919507b6baf2a97d4bfaa2eDaniel Dunbar 38273c557458c0e28899f37c557bcaf36c2b6701260Daniel Dunbar SmallVector<MCFixup, 4> Fixups; 3834fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar SmallString<256> Code; 3844fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar raw_svector_ostream VecOS(Code); 385cf871e5abff63a53f9e97ff9e37fb7297d0cb847Daniel Dunbar Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 386f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar VecOS.flush(); 387f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar 388337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar // FIXME: Eliminate this copy. 389337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar SmallVector<MCAsmFixup, 4> AsmFixups; 390f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 391f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar MCFixup &F = Fixups[i]; 392337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar AsmFixups.push_back(MCAsmFixup(F.getOffset(), *F.getValue(), 393337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar F.getKind())); 394337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar } 395337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar 396d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // See if we might need to relax this instruction, if so it needs its own 397d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // fragment. 398d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // 399d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // FIXME-PERF: Support target hook to do a fast path that avoids the encoder, 400d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // when we can immediately tell that we will get something which might need 401d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // relaxation (and compute its size). 402d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // 403d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // FIXME-PERF: We should also be smart about immediately relaxing instructions 404d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // which we can already show will never possibly fit (we can also do a very 405d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // good job of this before we do the first relaxation pass, because we have 406d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // total knowledge about undefined symbols at that point). Even now, though, 407d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // we can do a decent job, especially on Darwin where scattering means that we 408d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // are going to often know that we can never fully resolve a fixup. 409d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar if (Assembler.getBackend().MayNeedRelaxation(Inst, AsmFixups)) { 410d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); 411d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar 412d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // Add the fixups and data. 413d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // 414d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // FIXME: Revisit this design decision when relaxation is done, we may be 415d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar // able to get away with not storing any extra data in the MCInst. 416d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar IF->getCode() = Code; 417d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar IF->getFixups() = AsmFixups; 418d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar 419d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar return; 420d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar } 421d8036fb0deb7daff7959b0a5407c8a45acb5e603Daniel Dunbar 422337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar // Add the fixups and data. 423337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar MCDataFragment *DF = getOrCreateDataFragment(); 424337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) { 425337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar AsmFixups[i].Offset += DF->getContents().size(); 426337055e62f28f18a9a8c4a090633cae1c2256ae1Daniel Dunbar DF->addFixup(AsmFixups[i]); 427f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar } 428f6346769b344f9b134f0661e8bd2b4245f6490eaDaniel Dunbar DF->getContents().append(Code.begin(), Code.end()); 429fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 430fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 431fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::Finish() { 432fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Assembler.Finish(); 433fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 434fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 4351f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel DunbarMCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 436ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar raw_ostream &OS, MCCodeEmitter *CE, 437ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar bool RelaxAll) { 438ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar MCMachOStreamer *S = new MCMachOStreamer(Context, TAB, OS, CE); 439ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar if (RelaxAll) 440ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar S->getAssembler().setRelaxAll(true); 441ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar return S; 442fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 443