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