MCMachOStreamer.cpp revision 8f4d146c340c9423271ebd7bb3fd32b880000bc9
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" 154fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/MC/MCInst.h" 16fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSection.h" 17fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/MC/MCSymbol.h" 18fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 194fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar#include "llvm/Support/raw_ostream.h" 20fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarusing namespace llvm; 21fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 22fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarnamespace { 23fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 24fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass MCMachOStreamer : public MCStreamer { 256aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest 266aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar /// 16 bits of the implementation defined flags. 276aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar enum SymbolFlags { // See <mach-o/nlist.h>. 286aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_DescFlagsMask = 0xFFFF, 296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Reference type flags. 316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeMask = 0x0007, 326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeUndefinedNonLazy = 0x0000, 336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeUndefinedLazy = 0x0001, 346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypeDefined = 0x0002, 356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateDefined = 0x0003, 366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, 376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_ReferenceTypePrivateUndefinedLazy = 0x0005, 386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Other 'desc' flags. 406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_NoDeadStrip = 0x0020, 416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_WeakReference = 0x0040, 426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SF_WeakDefinition = 0x0080 436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar }; 446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbarprivate: 46fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar MCAssembler Assembler; 47fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 484fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar MCCodeEmitter *Emitter; 494fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar 50fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar MCSectionData *CurSectionData; 51fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 52fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar DenseMap<const MCSection*, MCSectionData*> SectionMap; 53f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 54f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; 55f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 56f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbarprivate: 57f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCFragment *getCurrentFragment() const { 58f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(CurSectionData && "No current section!"); 59f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 60f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!CurSectionData->empty()) 61f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar return &CurSectionData->getFragmentList().back(); 62f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 63f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar return 0; 64f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 65f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 660f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar MCSectionData &getSectionData(const MCSection &Section) { 670f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar MCSectionData *&Entry = SectionMap[&Section]; 680f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar 690f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar if (!Entry) 700f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar Entry = new MCSectionData(Section, &Assembler); 710f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar 720f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar return *Entry; 730f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar } 740f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar 75f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCSymbolData &getSymbolData(MCSymbol &Symbol) { 76f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCSymbolData *&Entry = SymbolMap[&Symbol]; 77f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 78f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!Entry) 79f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar Entry = new MCSymbolData(Symbol, 0, 0, &Assembler); 80f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 81f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar return *Entry; 82f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar } 83fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 84fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarpublic: 854fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter) 864fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar : MCStreamer(Context), Assembler(_OS), Emitter(_Emitter), 874fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar CurSectionData(0) {} 88fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar ~MCMachOStreamer() {} 89fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 90a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar const MCValue &AddValueSymbols(const MCValue &Value) { 91a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar if (Value.getSymA()) 92a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar getSymbolData(*const_cast<MCSymbol*>(Value.getSymA())); 93a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar if (Value.getSymB()) 94a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar getSymbolData(*const_cast<MCSymbol*>(Value.getSymB())); 95a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar return Value; 96a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar } 97a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar 98fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @name MCStreamer Interface 99fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @{ 100fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 101fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void SwitchSection(const MCSection *Section); 102fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 103fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitLabel(MCSymbol *Symbol); 104fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 105fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitAssemblerFlag(AssemblerFlag Flag); 106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 107fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value, 108fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar bool MakeAbsolute = false); 109fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 110fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute); 111fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 112fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 113fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 114fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value); 115fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 116fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, 117e6cdbf2f92a753ad547e3287e279bf47585b228dDaniel Dunbar unsigned Pow2Alignment); 118fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1198751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 120fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned Size = 0, unsigned Pow2Alignment = 0); 121fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 122fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitBytes(const StringRef &Data); 123fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 124fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitValue(const MCValue &Value, unsigned Size); 125fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 126fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 127fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned ValueSize = 1, 128fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned MaxBytesToEmit = 0); 129fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 130fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitValueToOffset(const MCValue &Offset, 131fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned char Value = 0); 132fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 133fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void EmitInstruction(const MCInst &Inst); 134fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 135fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar virtual void Finish(); 136fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 137fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar /// @} 138fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar}; 139fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 140fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} // end anonymous namespace. 141fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 142fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::SwitchSection(const MCSection *Section) { 143fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar assert(Section && "Cannot switch to a null section!"); 144cda7f78233b889772e1454a1246130c576681bb8Chris Lattner 145cda7f78233b889772e1454a1246130c576681bb8Chris Lattner // If already in this section, then this is a noop. 146cda7f78233b889772e1454a1246130c576681bb8Chris Lattner if (Section == CurSection) return; 147fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1480f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar CurSection = Section; 1490f5fa6955199cc7e0964524d73c8a9820d8f78c1Daniel Dunbar CurSectionData = &getSectionData(*Section); 150fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 151fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 152fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { 1538906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 154fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 1555e835967dd5dda294d0ef3392f4c1d4a2260f532Daniel Dunbar // FIXME: We should also use offsets into Fill fragments. 156f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 157f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!F) 158f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar F = new MCDataFragment(CurSectionData); 159fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 160f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCSymbolData &SD = getSymbolData(*Symbol); 161f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 162f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SD.setFragment(F); 163f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar SD.setOffset(F->getContents().size()); 1646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 1656aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // This causes the reference type and weak reference flags to be cleared. 1666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask)); 167f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar 1688906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar Symbol->setSection(*CurSection); 169fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 170fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 171fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) { 1726009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar switch (Flag) { 1736009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar default: 1746009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 1756009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar 1766009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar case SubsectionsViaSymbols: 1776009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar Assembler.setSubsectionsViaSymbols(true); 1786009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar break; 1796009db486e7fba448ccb28dff676c012efade8f0Daniel Dunbar } 180fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 181fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 182fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, 183fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar const MCValue &Value, 184fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar bool MakeAbsolute) { 1858906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar // Only absolute symbols can be redefined. 1868906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar assert((Symbol->isUndefined() || Symbol->isAbsolute()) && 1878906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar "Cannot define a symbol twice!"); 188fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 189fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 190fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 191fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 192fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 193fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar SymbolAttr Attribute) { 1940c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // Indirect symbols are handled differently, to match how 'as' handles 1950c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar // them. This makes writing matching .o files easier. 1960c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar if (Attribute == MCStreamer::IndirectSymbol) { 197ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // Note that we intentionally cannot use the symbol data here; this is 198ad7c3d55932f949e6bd428232999088a53f54a4fDaniel Dunbar // important for matching the string table that 'as' generates. 1990c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar IndirectSymbolData ISD; 2000c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ISD.Symbol = Symbol; 2010c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar ISD.SectionData = CurSectionData; 2020c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar Assembler.getIndirectSymbols().push_back(ISD); 2030c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar return; 2040c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar } 2050c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar 2066aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Adding a symbol attribute always introduces the symbol, note that an 2076aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // important side effect of calling getSymbolData here is to register the 2086aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // symbol with the assembler. 2096aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar MCSymbolData &SD = getSymbolData(*Symbol); 2106aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2116aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // The implementation of symbol attributes is designed to match 'as', but it 2126aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // leaves much to desired. It doesn't really make sense to arbitrarily add and 2136aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // remove flags, but 'as' allows this (in particular, see .desc). 2146aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // 2156aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // In the future it might be worth trying to make these operations more well 2166aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // defined. 2173edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar switch (Attribute) { 2180c7761b3f98fee270d73f5b9c440fe15e82af263Daniel Dunbar case MCStreamer::IndirectSymbol: 2196aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::Hidden: 2206aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::Internal: 2216aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::Protected: 2226aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::Weak: 2236aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar assert(0 && "Invalid symbol attribute for Mach-O!"); 2246aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2253edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar 2263edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar case MCStreamer::Global: 2278f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar SD.setExternal(true); 2283edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar break; 2296aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2306aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::LazyReference: 2316aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: This requires -dynamic. 2326aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 2336aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar if (Symbol->isUndefined()) 2346aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy); 2356aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2366aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2376aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Since .reference sets the no dead strip bit, it is equivalent to 2386aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // .no_dead_strip in practice. 2396aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::Reference: 2406aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::NoDeadStrip: 2416aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 2426aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2436aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2446aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::PrivateExtern: 2456aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setExternal(true); 2466aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setPrivateExtern(true); 2476aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2486aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2496aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::WeakReference: 2506aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: This requires -dynamic. 2516aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar if (Symbol->isUndefined()) 2526aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_WeakReference); 2536aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2546aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar 2556aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar case MCStreamer::WeakDefinition: 2566aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // FIXME: 'as' enforces that this is defined and global. The manual claims 2576aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // it has to be in a coalesced section, but this isn't enforced. 2586aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar SD.setFlags(SD.getFlags() | SF_WeakDefinition); 2596aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar break; 2603edd9bb7a3da8526eb2f4a5dae2962a987d3d566Daniel Dunbar } 261fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 262fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 263fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 2646aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar // Encode the 'desc' value into the lowest implementation defined bits. 2656aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar assert(DescValue == (DescValue & SF_DescFlagsMask) && 2666aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar "Invalid .desc value!"); 2676aff2fbd56d4bc2d6029f7c9bd49a97f6dc01213Daniel Dunbar getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask); 268fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 269fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 270fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) { 271fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 272fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 273fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 274fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, 275e6cdbf2f92a753ad547e3287e279bf47585b228dDaniel Dunbar unsigned Pow2Alignment) { 2768f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 2778f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 2788f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar 2798f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar MCSymbolData &SD = getSymbolData(*Symbol); 2808f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar SD.setExternal(true); 2818f4d146c340c9423271ebd7bb3fd32b880000bc9Daniel Dunbar SD.setCommon(Size, 1 << Pow2Alignment); 282fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 283fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2848751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbarvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 285fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned Size, unsigned Pow2Alignment) { 286d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar unsigned ByteAlignment = 1 << Pow2Alignment; 287d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCSectionData &SectData = getSectionData(*Section); 288d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 289d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // The symbol may not be present, which only creates the section. 290d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (!Symbol) 291d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar return; 292d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 293d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // FIXME: Assert that this section has the zerofill type. 294d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 295d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 296d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 297d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCSymbolData &SD = getSymbolData(*Symbol); 298d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 299d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar MCFragment *F = new MCZeroFillFragment(Size, 1 << Pow2Alignment, &SectData); 300d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SD.setFragment(F); 301d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 302d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar Symbol->setSection(*Section); 303d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar 304d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar // Update the maximum alignment on the zero fill section if necessary. 305d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar if (ByteAlignment > SectData.getAlignment()) 306d5a8e98ef627a35284c9b5989664514f8f163968Daniel Dunbar SectData.setAlignment(ByteAlignment); 307fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 308fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 309fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitBytes(const StringRef &Data) { 310f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 311f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar if (!DF) 312f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar DF = new MCDataFragment(CurSectionData); 3130705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar DF->getContents().append(Data.begin(), Data.end()); 314fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 315fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 316fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValue(const MCValue &Value, unsigned Size) { 317a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar new MCFillFragment(AddValueSymbols(Value), Size, 1, CurSectionData); 318fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 319fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 320fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, 321fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar int64_t Value, unsigned ValueSize, 322fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned MaxBytesToEmit) { 323d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar if (MaxBytesToEmit == 0) 324d6f761e0eb610936a6b8495360b62696dcd85164Daniel Dunbar MaxBytesToEmit = ByteAlignment; 3250705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 3260705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar CurSectionData); 3270705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar 328f3d2ef0c9712381a105118336975adcfbf733db0Daniel Dunbar // Update the maximum alignment on the current section if necessary. 3290705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar if (ByteAlignment > CurSectionData->getAlignment()) 3300705fbf52fcaade0c6b9d5d33bec163ee4c2daf4Daniel Dunbar CurSectionData->setAlignment(ByteAlignment); 331fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 332fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 333fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitValueToOffset(const MCValue &Offset, 334fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar unsigned char Value) { 335a421de11df9d2a07b9f95a1ad817467af426803aDaniel Dunbar new MCOrgFragment(AddValueSymbols(Offset), Value, CurSectionData); 336fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 337fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 338fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::EmitInstruction(const MCInst &Inst) { 3394fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar // Scan for values. 3404fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar for (unsigned i = 0; i != Inst.getNumOperands(); ++i) 3414fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar if (Inst.getOperand(i).isMCValue()) 3424fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar AddValueSymbols(Inst.getOperand(i).getMCValue()); 3434fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar 3444fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar if (!Emitter) 3454fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar llvm_unreachable("no code emitter available!"); 3464fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar 3474fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar // FIXME: Relocations! 3484fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar SmallString<256> Code; 3494fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar raw_svector_ostream VecOS(Code); 3504fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar Emitter->EncodeInstruction(Inst, VecOS); 3514fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar EmitBytes(VecOS.str()); 352fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 353fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 354fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarvoid MCMachOStreamer::Finish() { 355fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar Assembler.Finish(); 356fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 357fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 3584fac74950a1ff08b995b366bfb84369c1507faefDaniel DunbarMCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS, 3594fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar MCCodeEmitter *CE) { 3604fac74950a1ff08b995b366bfb84369c1507faefDaniel Dunbar return new MCMachOStreamer(Context, OS, CE); 361fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar} 362