MCMachOStreamer.cpp revision 208954
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/MC/MCMachOSymbolFlags.h" 20#include "llvm/Support/ErrorHandling.h" 21#include "llvm/Support/raw_ostream.h" 22#include "llvm/Target/TargetAsmBackend.h" 23 24using namespace llvm; 25 26namespace { 27 28class MCMachOStreamer : public MCStreamer { 29 30private: 31 MCAssembler Assembler; 32 MCSectionData *CurSectionData; 33 34 /// Track the current atom for each section. 35 DenseMap<const MCSectionData*, MCSymbolData*> CurrentAtomMap; 36 37private: 38 MCFragment *getCurrentFragment() const { 39 assert(CurSectionData && "No current section!"); 40 41 if (!CurSectionData->empty()) 42 return &CurSectionData->getFragmentList().back(); 43 44 return 0; 45 } 46 47 /// Get a data fragment to write into, creating a new one if the current 48 /// fragment is not a data fragment. 49 MCDataFragment *getOrCreateDataFragment() const { 50 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 51 if (!F) 52 F = createDataFragment(); 53 return F; 54 } 55 56 /// Create a new data fragment in the current section. 57 MCDataFragment *createDataFragment() const { 58 MCDataFragment *DF = new MCDataFragment(CurSectionData); 59 DF->setAtom(CurrentAtomMap.lookup(CurSectionData)); 60 return DF; 61 } 62 63 void EmitInstToFragment(const MCInst &Inst); 64 void EmitInstToData(const MCInst &Inst); 65 66public: 67 MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 68 raw_ostream &_OS, MCCodeEmitter *_Emitter) 69 : MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS), 70 CurSectionData(0) {} 71 ~MCMachOStreamer() {} 72 73 MCAssembler &getAssembler() { return Assembler; } 74 75 const MCExpr *AddValueSymbols(const MCExpr *Value) { 76 switch (Value->getKind()) { 77 case MCExpr::Target: assert(0 && "Can't handle target exprs yet!"); 78 case MCExpr::Constant: 79 break; 80 81 case MCExpr::Binary: { 82 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 83 AddValueSymbols(BE->getLHS()); 84 AddValueSymbols(BE->getRHS()); 85 break; 86 } 87 88 case MCExpr::SymbolRef: 89 Assembler.getOrCreateSymbolData( 90 cast<MCSymbolRefExpr>(Value)->getSymbol()); 91 break; 92 93 case MCExpr::Unary: 94 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr()); 95 break; 96 } 97 98 return Value; 99 } 100 101 /// @name MCStreamer Interface 102 /// @{ 103 104 virtual void SwitchSection(const MCSection *Section); 105 virtual void EmitLabel(MCSymbol *Symbol); 106 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); 107 virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); 108 virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); 109 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 110 virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 111 unsigned ByteAlignment); 112 virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { 113 assert(0 && "macho doesn't support this directive"); 114 } 115 virtual void EmitCOFFSymbolStorageClass(int StorageClass) { 116 assert(0 && "macho doesn't support this directive"); 117 } 118 virtual void EmitCOFFSymbolType(int Type) { 119 assert(0 && "macho doesn't support this directive"); 120 } 121 virtual void EndCOFFSymbolDef() { 122 assert(0 && "macho doesn't support this directive"); 123 } 124 virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { 125 assert(0 && "macho doesn't support this directive"); 126 } 127 virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { 128 assert(0 && "macho doesn't support this directive"); 129 } 130 virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, 131 unsigned Size = 0, unsigned ByteAlignment = 0); 132 virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 133 uint64_t Size, unsigned ByteAlignment = 0); 134 virtual void EmitBytes(StringRef Data, unsigned AddrSpace); 135 virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace); 136 virtual void EmitGPRel32Value(const MCExpr *Value) { 137 assert(0 && "macho doesn't support this directive"); 138 } 139 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 140 unsigned ValueSize = 1, 141 unsigned MaxBytesToEmit = 0); 142 virtual void EmitCodeAlignment(unsigned ByteAlignment, 143 unsigned MaxBytesToEmit = 0); 144 virtual void EmitValueToOffset(const MCExpr *Offset, 145 unsigned char Value = 0); 146 147 virtual void EmitFileDirective(StringRef Filename) { 148 report_fatal_error("unsupported directive: '.file'"); 149 } 150 virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { 151 report_fatal_error("unsupported directive: '.file'"); 152 } 153 154 virtual void EmitInstruction(const MCInst &Inst); 155 virtual void Finish(); 156 157 /// @} 158}; 159 160} // end anonymous namespace. 161 162void MCMachOStreamer::SwitchSection(const MCSection *Section) { 163 assert(Section && "Cannot switch to a null section!"); 164 165 // If already in this section, then this is a noop. 166 if (Section == CurSection) return; 167 168 CurSection = Section; 169 CurSectionData = &Assembler.getOrCreateSectionData(*Section); 170} 171 172void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { 173 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 174 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 175 assert(CurSection && "Cannot emit before setting section!"); 176 177 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 178 179 // Update the current atom map, if necessary. 180 bool MustCreateFragment = false; 181 if (Assembler.isSymbolLinkerVisible(&SD)) { 182 CurrentAtomMap[CurSectionData] = &SD; 183 184 // We have to create a new fragment, fragments cannot span atoms. 185 MustCreateFragment = true; 186 } 187 188 // FIXME: This is wasteful, we don't necessarily need to create a data 189 // fragment. Instead, we should mark the symbol as pointing into the data 190 // fragment if it exists, otherwise we should just queue the label and set its 191 // fragment pointer when we emit the next fragment. 192 MCDataFragment *F = 193 MustCreateFragment ? createDataFragment() : getOrCreateDataFragment(); 194 assert(!SD.getFragment() && "Unexpected fragment on symbol data!"); 195 SD.setFragment(F); 196 SD.setOffset(F->getContents().size()); 197 198 // This causes the reference type flag to be cleared. Darwin 'as' was "trying" 199 // to clear the weak reference and weak definition bits too, but the 200 // implementation was buggy. For now we just try to match 'as', for 201 // diffability. 202 // 203 // FIXME: Cleanup this code, these bits should be emitted based on semantic 204 // properties, not on the order of definition, etc. 205 SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask); 206 207 Symbol->setSection(*CurSection); 208} 209 210void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 211 switch (Flag) { 212 case MCAF_SubsectionsViaSymbols: 213 Assembler.setSubsectionsViaSymbols(true); 214 return; 215 } 216 217 assert(0 && "invalid assembler flag!"); 218} 219 220void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 221 // FIXME: Lift context changes into super class. 222 Assembler.getOrCreateSymbolData(*Symbol); 223 Symbol->setVariableValue(AddValueSymbols(Value)); 224} 225 226void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 227 MCSymbolAttr Attribute) { 228 // Indirect symbols are handled differently, to match how 'as' handles 229 // them. This makes writing matching .o files easier. 230 if (Attribute == MCSA_IndirectSymbol) { 231 // Note that we intentionally cannot use the symbol data here; this is 232 // important for matching the string table that 'as' generates. 233 IndirectSymbolData ISD; 234 ISD.Symbol = Symbol; 235 ISD.SectionData = CurSectionData; 236 Assembler.getIndirectSymbols().push_back(ISD); 237 return; 238 } 239 240 // Adding a symbol attribute always introduces the symbol, note that an 241 // important side effect of calling getOrCreateSymbolData here is to register 242 // the symbol with the assembler. 243 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 244 245 // The implementation of symbol attributes is designed to match 'as', but it 246 // leaves much to desired. It doesn't really make sense to arbitrarily add and 247 // remove flags, but 'as' allows this (in particular, see .desc). 248 // 249 // In the future it might be worth trying to make these operations more well 250 // defined. 251 switch (Attribute) { 252 case MCSA_Invalid: 253 case MCSA_ELF_TypeFunction: 254 case MCSA_ELF_TypeIndFunction: 255 case MCSA_ELF_TypeObject: 256 case MCSA_ELF_TypeTLS: 257 case MCSA_ELF_TypeCommon: 258 case MCSA_ELF_TypeNoType: 259 case MCSA_IndirectSymbol: 260 case MCSA_Hidden: 261 case MCSA_Internal: 262 case MCSA_Protected: 263 case MCSA_Weak: 264 case MCSA_Local: 265 assert(0 && "Invalid symbol attribute for Mach-O!"); 266 break; 267 268 case MCSA_Global: 269 SD.setExternal(true); 270 // This effectively clears the undefined lazy bit, in Darwin 'as', although 271 // it isn't very consistent because it implements this as part of symbol 272 // lookup. 273 // 274 // FIXME: Cleanup this code, these bits should be emitted based on semantic 275 // properties, not on the order of definition, etc. 276 SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeUndefinedLazy); 277 break; 278 279 case MCSA_LazyReference: 280 // FIXME: This requires -dynamic. 281 SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 282 if (Symbol->isUndefined()) 283 SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy); 284 break; 285 286 // Since .reference sets the no dead strip bit, it is equivalent to 287 // .no_dead_strip in practice. 288 case MCSA_Reference: 289 case MCSA_NoDeadStrip: 290 SD.setFlags(SD.getFlags() | SF_NoDeadStrip); 291 break; 292 293 case MCSA_PrivateExtern: 294 SD.setExternal(true); 295 SD.setPrivateExtern(true); 296 break; 297 298 case MCSA_WeakReference: 299 // FIXME: This requires -dynamic. 300 if (Symbol->isUndefined()) 301 SD.setFlags(SD.getFlags() | SF_WeakReference); 302 break; 303 304 case MCSA_WeakDefinition: 305 // FIXME: 'as' enforces that this is defined and global. The manual claims 306 // it has to be in a coalesced section, but this isn't enforced. 307 SD.setFlags(SD.getFlags() | SF_WeakDefinition); 308 break; 309 } 310} 311 312void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 313 // Encode the 'desc' value into the lowest implementation defined bits. 314 assert(DescValue == (DescValue & SF_DescFlagsMask) && 315 "Invalid .desc value!"); 316 Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); 317} 318 319void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 320 unsigned ByteAlignment) { 321 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. 322 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 323 324 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 325 SD.setExternal(true); 326 SD.setCommon(Size, ByteAlignment); 327} 328 329void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, 330 unsigned Size, unsigned ByteAlignment) { 331 MCSectionData &SectData = Assembler.getOrCreateSectionData(*Section); 332 333 // The symbol may not be present, which only creates the section. 334 if (!Symbol) 335 return; 336 337 // FIXME: Assert that this section has the zerofill type. 338 339 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 340 341 MCSymbolData &SD = Assembler.getOrCreateSymbolData(*Symbol); 342 343 // Emit an align fragment if necessary. 344 if (ByteAlignment != 1) 345 new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData); 346 347 MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 348 SD.setFragment(F); 349 if (Assembler.isSymbolLinkerVisible(&SD)) 350 F->setAtom(&SD); 351 352 Symbol->setSection(*Section); 353 354 // Update the maximum alignment on the zero fill section if necessary. 355 if (ByteAlignment > SectData.getAlignment()) 356 SectData.setAlignment(ByteAlignment); 357} 358 359// This should always be called with the thread local bss section. Like the 360// .zerofill directive this doesn't actually switch sections on us. 361void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, 362 uint64_t Size, unsigned ByteAlignment) { 363 EmitZerofill(Section, Symbol, Size, ByteAlignment); 364 return; 365} 366 367void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 368 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 369} 370 371void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size, 372 unsigned AddrSpace) { 373 MCDataFragment *DF = getOrCreateDataFragment(); 374 375 // Avoid fixups when possible. 376 int64_t AbsValue; 377 if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) { 378 // FIXME: Endianness assumption. 379 for (unsigned i = 0; i != Size; ++i) 380 DF->getContents().push_back(uint8_t(AbsValue >> (i * 8))); 381 } else { 382 DF->addFixup(MCFixup::Create(DF->getContents().size(), 383 AddValueSymbols(Value), 384 MCFixup::getKindForSize(Size))); 385 DF->getContents().resize(DF->getContents().size() + Size, 0); 386 } 387} 388 389void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, 390 int64_t Value, unsigned ValueSize, 391 unsigned MaxBytesToEmit) { 392 if (MaxBytesToEmit == 0) 393 MaxBytesToEmit = ByteAlignment; 394 MCFragment *F = new MCAlignFragment(ByteAlignment, Value, ValueSize, 395 MaxBytesToEmit, CurSectionData); 396 F->setAtom(CurrentAtomMap.lookup(CurSectionData)); 397 398 // Update the maximum alignment on the current section if necessary. 399 if (ByteAlignment > CurSectionData->getAlignment()) 400 CurSectionData->setAlignment(ByteAlignment); 401} 402 403void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment, 404 unsigned MaxBytesToEmit) { 405 if (MaxBytesToEmit == 0) 406 MaxBytesToEmit = ByteAlignment; 407 MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 408 CurSectionData); 409 F->setEmitNops(true); 410 F->setAtom(CurrentAtomMap.lookup(CurSectionData)); 411 412 // Update the maximum alignment on the current section if necessary. 413 if (ByteAlignment > CurSectionData->getAlignment()) 414 CurSectionData->setAlignment(ByteAlignment); 415} 416 417void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset, 418 unsigned char Value) { 419 MCFragment *F = new MCOrgFragment(*Offset, Value, CurSectionData); 420 F->setAtom(CurrentAtomMap.lookup(CurSectionData)); 421} 422 423void MCMachOStreamer::EmitInstToFragment(const MCInst &Inst) { 424 MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); 425 IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); 426 427 // Add the fixups and data. 428 // 429 // FIXME: Revisit this design decision when relaxation is done, we may be 430 // able to get away with not storing any extra data in the MCInst. 431 SmallVector<MCFixup, 4> Fixups; 432 SmallString<256> Code; 433 raw_svector_ostream VecOS(Code); 434 Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 435 VecOS.flush(); 436 437 IF->getCode() = Code; 438 IF->getFixups() = Fixups; 439} 440 441void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { 442 MCDataFragment *DF = getOrCreateDataFragment(); 443 444 SmallVector<MCFixup, 4> Fixups; 445 SmallString<256> Code; 446 raw_svector_ostream VecOS(Code); 447 Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 448 VecOS.flush(); 449 450 // Add the fixups and data. 451 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 452 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 453 DF->addFixup(Fixups[i]); 454 } 455 DF->getContents().append(Code.begin(), Code.end()); 456} 457 458void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { 459 // Scan for values. 460 for (unsigned i = Inst.getNumOperands(); i--; ) 461 if (Inst.getOperand(i).isExpr()) 462 AddValueSymbols(Inst.getOperand(i).getExpr()); 463 464 CurSectionData->setHasInstructions(true); 465 466 // If this instruction doesn't need relaxation, just emit it as data. 467 if (!Assembler.getBackend().MayNeedRelaxation(Inst)) { 468 EmitInstToData(Inst); 469 return; 470 } 471 472 // Otherwise, if we are relaxing everything, relax the instruction as much as 473 // possible and emit it as data. 474 if (Assembler.getRelaxAll()) { 475 MCInst Relaxed; 476 Assembler.getBackend().RelaxInstruction(Inst, Relaxed); 477 while (Assembler.getBackend().MayNeedRelaxation(Relaxed)) 478 Assembler.getBackend().RelaxInstruction(Relaxed, Relaxed); 479 EmitInstToData(Relaxed); 480 return; 481 } 482 483 // Otherwise emit to a separate fragment. 484 EmitInstToFragment(Inst); 485} 486 487void MCMachOStreamer::Finish() { 488 Assembler.Finish(); 489} 490 491MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, 492 raw_ostream &OS, MCCodeEmitter *CE, 493 bool RelaxAll) { 494 MCMachOStreamer *S = new MCMachOStreamer(Context, TAB, OS, CE); 495 if (RelaxAll) 496 S->getAssembler().setRelaxAll(true); 497 return S; 498} 499