MCMachOStreamer.cpp revision f70f477024a23408d3a535920e6d4750478ac9ae
1//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "llvm/MC/MCStreamer.h" 11 12#include "llvm/MC/MCAssembler.h" 13#include "llvm/MC/MCContext.h" 14#include "llvm/MC/MCCodeEmitter.h" 15#include "llvm/MC/MCExpr.h" 16#include "llvm/MC/MCInst.h" 17#include "llvm/MC/MCSection.h" 18#include "llvm/MC/MCSymbol.h" 19#include "llvm/Support/ErrorHandling.h" 20#include "llvm/Support/raw_ostream.h" 21using namespace llvm; 22 23namespace { 24 25class MCMachOStreamer : public MCStreamer { 26 /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest 27 /// 16 bits of the implementation defined flags. 28 enum SymbolFlags { // See <mach-o/nlist.h>. 29 SF_DescFlagsMask = 0xFFFF, 30 31 // Reference type flags. 32 SF_ReferenceTypeMask = 0x0007, 33 SF_ReferenceTypeUndefinedNonLazy = 0x0000, 34 SF_ReferenceTypeUndefinedLazy = 0x0001, 35 SF_ReferenceTypeDefined = 0x0002, 36 SF_ReferenceTypePrivateDefined = 0x0003, 37 SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004, 38 SF_ReferenceTypePrivateUndefinedLazy = 0x0005, 39 40 // Other 'desc' flags. 41 SF_NoDeadStrip = 0x0020, 42 SF_WeakReference = 0x0040, 43 SF_WeakDefinition = 0x0080 44 }; 45 46private: 47 MCAssembler Assembler; 48 MCSectionData *CurSectionData; 49 50private: 51 MCFragment *getCurrentFragment() const { 52 assert(CurSectionData && "No current section!"); 53 54 if (!CurSectionData->empty()) 55 return &CurSectionData->getFragmentList().back(); 56 57 return 0; 58 } 59 60 /// Get a data fragment to write into, creating a new one if the current 61 /// fragment is not a data fragment. 62 MCDataFragment *getOrCreateDataFragment() const { 63 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 64 if (!F) 65 F = new MCDataFragment(CurSectionData); 66 return F; 67 } 68 69public: 70 MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 71 raw_ostream &_OS, MCCodeEmitter *_Emitter) 72 : MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS), 73 CurSectionData(0) {} 74 ~MCMachOStreamer() {} 75 76 const MCExpr *AddValueSymbols(const MCExpr *Value) { 77 switch (Value->getKind()) { 78 case MCExpr::Target: assert(0 && "Can't handle target exprs yet!"); 79 case MCExpr::Constant: 80 break; 81 82 case MCExpr::Binary: { 83 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 84 AddValueSymbols(BE->getLHS()); 85 AddValueSymbols(BE->getRHS()); 86 break; 87 } 88 89 case MCExpr::SymbolRef: 90 Assembler.getOrCreateSymbolData( 91 cast<MCSymbolRefExpr>(Value)->getSymbol()); 92 break; 93 94 case MCExpr::Unary: 95 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 96 break; 97 } 98 99 return Value; 100 } 101 102 /// @name MCStreamer Interface 103 /// @{ 104 105 virtual void SwitchSection(const MCSection *Section); 106 virtual void EmitLabel(MCSymbol *Symbol); 107 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 108 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 109 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 110 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 111 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 112 unsigned ByteAlignment); 113 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 114 assert(0 && "macho doesn't support this directive"); 115 } 116 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 117 assert(0 && "macho doesn't support this directive"); 118 } 119 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 120 unsigned Size = 0, unsigned ByteAlignment = 0); 121 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 122 virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 123 virtual void EmitGPRel32Value(const MCExpr *Value) { 124 assert(0 && "macho doesn't support this directive"); 125 } 126 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 127 unsigned ValueSize = 1, 128 unsigned MaxBytesToEmit = 0); 129 virtual void EmitCodeAlignment(unsigned ByteAlignment, 130 unsigned MaxBytesToEmit = 0); 131 virtual void EmitValueToOffset(const MCExpr *Offset, 132 unsigned char Value = 0); 133 134 virtual void EmitFileDirective(StringRef Filename) { 135 errs() << "FIXME: MCMachoStreamer:EmitFileDirective not implemented\n"; 136 } 137 virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { 138 errs() << "FIXME: MCMachoStreamer:EmitDwarfFileDirective not implemented\n"; 139 } 140 141 virtual void EmitInstruction(const MCInst &Inst); 142 virtual void Finish(); 143 144 /// @} 145}; 146 147} // end anonymous namespace. 148 149void MCMachOStreamer::SwitchSection(const MCSection *Section) { 150 assert(Section && "Cannot switch to a null section!"); 151 152 // If already in this section, then this is a noop. 153 if (Section == CurSection) return; 154 155 CurSection = Section; 156 CurSectionData = &Assembler.getOrCreateSectionData(*Section); 157} 158 159void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { 160 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 161 162 // FIXME: This is wasteful, we don't necessarily need to create a data 163 // fragment. Instead, we should mark the symbol as pointing into the data 164 // fragment if it exists, otherwise we should just queue the label and set its 165 // fragment pointer when we emit the next fragment. 166 MCDataFragment *F = getOrCreateDataFragment(); 167 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 168 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 169 SD.setFragment(F); 170 SD.setOffset(F->getContents().size()); 171 172 // This causes the reference type and weak reference flags to be cleared. 173 SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask)); 174 175 Symbol->setSection(*CurSection); 176} 177 178void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 179 switch (Flag) { 180 case MCAF_SubsectionsViaSymbols: 181 Assembler.setSubsectionsViaSymbols(true); 182 return; 183 } 184 185 assert(0 && "invalid assembler flag!"); 186} 187 188void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 189 // Only absolute symbols can be redefined. 190 assert((Symbol->isUndefined() || Symbol->isAbsolute()) && 191 "Cannot define a symbol twice!"); 192 193 // FIXME: Lift context changes into super class. 194 // FIXME: Set associated section. 195 Symbol->setValue(AddValueSymbols(Value)); 196} 197 198void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 199 MCSymbolAttr Attribute) { 200 // Indirect symbols are handled differently, to match how 'as' handles 201 // them. This makes writing matching .o files easier. 202 if (Attribute == MCSA_IndirectSymbol) { 203 // Note that we intentionally cannot use the symbol data here; this is 204 // important for matching the string table that 'as' generates. 205 IndirectSymbolData ISD; 206 ISD.Symbol = Symbol; 207 ISD.SectionData = CurSectionData; 208 Assembler.getIndirectSymbols().push_back(ISD); 209 return; 210 } 211 212 // Adding a symbol attribute always introduces the symbol, note that an 213 // important side effect of calling getOrCreateSymbolData here is to register 214 // the symbol with the assembler. 215 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 216 217 // The implementation of symbol attributes is designed to match 'as', but it 218 // leaves much to desired. It doesn't really make sense to arbitrarily add and 219 // remove flags, but 'as' allows this (in particular, see .desc). 220 // 221 // In the future it might be worth trying to make these operations more well 222 // defined. 223 switch (Attribute) { 224 case MCSA_Invalid: 225 case MCSA_ELF_TypeFunction: 226 case MCSA_ELF_TypeIndFunction: 227 case MCSA_ELF_TypeObject: 228 case MCSA_ELF_TypeTLS: 229 case MCSA_ELF_TypeCommon: 230 case MCSA_ELF_TypeNoType: 231 case MCSA_IndirectSymbol: 232 case MCSA_Hidden: 233 case MCSA_Internal: 234 case MCSA_Protected: 235 case MCSA_Weak: 236 case MCSA_Local: 237 assert(0 && "Invalid symbol attribute for Mach-O!"); 238 break; 239 240 case MCSA_Global: 241 SD.setExternal(true); 242 break; 243 244 case MCSA_LazyReference: 245 // FIXME: This requires -dynamic. 246 SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 247 if (Symbol->isUndefined()) 248 SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy); 249 break; 250 251 // Since .reference sets the no dead strip bit, it is equivalent to 252 // .no_dead_strip in practice. 253 case MCSA_Reference: 254 case MCSA_NoDeadStrip: 255 SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 256 break; 257 258 case MCSA_PrivateExtern: 259 SD.setExternal(true); 260 SD.setPrivateExtern(true); 261 break; 262 263 case MCSA_WeakReference: 264 // FIXME: This requires -dynamic. 265 if (Symbol->isUndefined()) 266 SD.setFlags(SD.getFlags() | SF_WeakReference); 267 break; 268 269 case MCSA_WeakDefinition: 270 // FIXME: 'as' enforces that this is defined and global. The manual claims 271 // it has to be in a coalesced section, but this isn't enforced. 272 SD.setFlags(SD.getFlags() | SF_WeakDefinition); 273 break; 274 } 275} 276 277void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 278 // Encode the 'desc' value into the lowest implementation defined bits. 279 assert(DescValue == (DescValue & SF_DescFlagsMask) && 280 "Invalid .desc value!"); 281 Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); 282} 283 284void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 285 unsigned ByteAlignment) { 286 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 287 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 288 289 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 290 SD.setExternal(true); 291 SD.setCommon(Size, ByteAlignment); 292} 293 294void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 295 unsigned Size, unsigned ByteAlignment) { 296 MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section); 297 298 // The symbol may not be present, which only creates the section. 299 if (!Symbol) 300 return; 301 302 // FIXME: Assert that this section has the zerofill type. 303 304 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 305 306 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 307 308 MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData); 309 SD.setFragment(F); 310 311 Symbol->setSection(*Section); 312 313 // Update the maximum alignment on the zero fill section if necessary. 314 if (ByteAlignment > SectData.getAlignment()) 315 SectData.setAlignment(ByteAlignment); 316} 317 318void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 319 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 320} 321 322void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size, 323 unsigned AddrSpace) { 324 MCDataFragment *DF = getOrCreateDataFragment(); 325 326 // Avoid fixups when possible. 327 int64_t AbsValue; 328 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 329 // FIXME: Endianness assumption. 330 for (unsigned i = 0; i != Size; ++i) 331 DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 332 } else { 333 DF->addFixup(MCAsmFixup(DF->getContents().size(), *AddValueSymbols(Value), 334 MCFixup::getKindForSize(Size))); 335 DF->getContents().resize(DF->getContents().size() + Size, 0); 336 } 337} 338 339void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, 340 int64_t Value, unsigned ValueSize, 341 unsigned MaxBytesToEmit) { 342 if (MaxBytesToEmit == 0) 343 MaxBytesToEmit = ByteAlignment; 344 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 345 false /* EmitNops */, CurSectionData); 346 347 // Update the maximum alignment on the current section if necessary. 348 if (ByteAlignment > CurSectionData->getAlignment()) 349 CurSectionData->setAlignment(ByteAlignment); 350} 351 352void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment, 353 unsigned MaxBytesToEmit) { 354 if (MaxBytesToEmit == 0) 355 MaxBytesToEmit = ByteAlignment; 356 // FIXME: The 0x90 is the default x86 1 byte nop opcode. 357 new MCAlignFragment(ByteAlignment, 0x90, 1, MaxBytesToEmit, 358 true /* EmitNops */, CurSectionData); 359 360 // Update the maximum alignment on the current section if necessary. 361 if (ByteAlignment > CurSectionData->getAlignment()) 362 CurSectionData->setAlignment(ByteAlignment); 363} 364 365void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset, 366 unsigned char Value) { 367 new MCOrgFragment(*Offset, Value, CurSectionData); 368} 369 370void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { 371 // Scan for values. 372 for (unsigned i = 0; i != Inst.getNumOperands(); ++i) 373 if (Inst.getOperand(i).isExpr()) 374 AddValueSymbols(Inst.getOperand(i).getExpr()); 375 376 CurSectionData->setHasInstructions(true); 377 378 SmallVector<MCFixup, 4> Fixups; 379 SmallString<256> Code; 380 raw_svector_ostream VecOS(Code); 381 Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 382 VecOS.flush(); 383 384 // Add the fixups and data. 385 MCDataFragment *DF = getOrCreateDataFragment(); 386 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 387 MCFixup &F = Fixups[i]; 388 DF->addFixup(MCAsmFixup(DF->getContents().size()+F.getOffset(), 389 *F.getValue(), F.getKind())); 390 } 391 DF->getContents().append(Code.begin(), Code.end()); 392} 393 394void MCMachOStreamer::Finish() { 395 Assembler.Finish(); 396} 397 398MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 399 raw_ostream &OS, MCCodeEmitter *CE) { 400 return new MCMachOStreamer(Context, TAB, OS, CE); 401} 402