MCELFStreamer.cpp revision a0c17a495b12debcb7f206993bbc6020e2e6e8df
1//===- lib/MC/MCELFStreamer.cpp - ELF 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// This file assembles .s files and emits ELF .o object files. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MCELFStreamer.h" 15#include "MCELF.h" 16#include "llvm/MC/MCStreamer.h" 17#include "llvm/MC/MCCodeEmitter.h" 18#include "llvm/MC/MCELFSymbolFlags.h" 19#include "llvm/MC/MCExpr.h" 20#include "llvm/MC/MCInst.h" 21#include "llvm/MC/MCSection.h" 22#include "llvm/MC/MCSymbol.h" 23#include "llvm/MC/MCValue.h" 24#include "llvm/MC/MCAsmBackend.h" 25#include "llvm/Support/Debug.h" 26#include "llvm/Support/ELF.h" 27#include "llvm/Support/ErrorHandling.h" 28#include "llvm/Support/raw_ostream.h" 29 30using namespace llvm; 31 32void MCELFStreamer::InitSections() { 33 // This emulates the same behavior of GNU as. This makes it easier 34 // to compare the output as the major sections are in the same order. 35 SetSectionText(); 36 SetSectionData(); 37 SetSectionBss(); 38 SetSectionText(); 39} 40 41void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { 42 assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); 43 44 MCObjectStreamer::EmitLabel(Symbol); 45 46 const MCSectionELF &Section = 47 static_cast<const MCSectionELF&>(Symbol->getSection()); 48 MCSymbolData &SD = getAssembler().getSymbolData(*Symbol); 49 if (Section.getFlags() & ELF::SHF_TLS) 50 MCELF::SetType(SD, ELF::STT_TLS); 51} 52 53void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { 54 switch (Flag) { 55 case MCAF_SyntaxUnified: return; // no-op here. 56 case MCAF_Code16: return; // Change parsing mode; no-op here. 57 case MCAF_Code32: return; // Change parsing mode; no-op here. 58 case MCAF_Code64: return; // Change parsing mode; no-op here. 59 case MCAF_SubsectionsViaSymbols: 60 getAssembler().setSubsectionsViaSymbols(true); 61 return; 62 } 63 64 assert(0 && "invalid assembler flag!"); 65} 66 67void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { 68 // FIXME: Anything needed here to flag the function as thumb? 69 70 getAssembler().setIsThumbFunc(Func); 71 72 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); 73 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); 74} 75 76void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { 77 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 78 // MCObjectStreamer. 79 // FIXME: Lift context changes into super class. 80 getAssembler().getOrCreateSymbolData(*Symbol); 81 Symbol->setVariableValue(AddValueSymbols(Value)); 82} 83 84void MCELFStreamer::ChangeSection(const MCSection *Section) { 85 const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); 86 if (Grp) 87 getAssembler().getOrCreateSymbolData(*Grp); 88 this->MCObjectStreamer::ChangeSection(Section); 89} 90 91void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { 92 getAssembler().getOrCreateSymbolData(*Symbol); 93 MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias); 94 AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref); 95 const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext()); 96 Alias->setVariableValue(Value); 97} 98 99void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 100 MCSymbolAttr Attribute) { 101 // Indirect symbols are handled differently, to match how 'as' handles 102 // them. This makes writing matching .o files easier. 103 if (Attribute == MCSA_IndirectSymbol) { 104 // Note that we intentionally cannot use the symbol data here; this is 105 // important for matching the string table that 'as' generates. 106 IndirectSymbolData ISD; 107 ISD.Symbol = Symbol; 108 ISD.SectionData = getCurrentSectionData(); 109 getAssembler().getIndirectSymbols().push_back(ISD); 110 return; 111 } 112 113 // Adding a symbol attribute always introduces the symbol, note that an 114 // important side effect of calling getOrCreateSymbolData here is to register 115 // the symbol with the assembler. 116 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 117 118 // The implementation of symbol attributes is designed to match 'as', but it 119 // leaves much to desired. It doesn't really make sense to arbitrarily add and 120 // remove flags, but 'as' allows this (in particular, see .desc). 121 // 122 // In the future it might be worth trying to make these operations more well 123 // defined. 124 switch (Attribute) { 125 case MCSA_LazyReference: 126 case MCSA_Reference: 127 case MCSA_NoDeadStrip: 128 case MCSA_SymbolResolver: 129 case MCSA_PrivateExtern: 130 case MCSA_WeakDefinition: 131 case MCSA_WeakDefAutoPrivate: 132 case MCSA_Invalid: 133 case MCSA_IndirectSymbol: 134 assert(0 && "Invalid symbol attribute for ELF!"); 135 break; 136 137 case MCSA_ELF_TypeGnuUniqueObject: 138 // Ignore for now. 139 break; 140 141 case MCSA_Global: 142 MCELF::SetBinding(SD, ELF::STB_GLOBAL); 143 SD.setExternal(true); 144 BindingExplicitlySet.insert(Symbol); 145 break; 146 147 case MCSA_WeakReference: 148 case MCSA_Weak: 149 MCELF::SetBinding(SD, ELF::STB_WEAK); 150 SD.setExternal(true); 151 BindingExplicitlySet.insert(Symbol); 152 break; 153 154 case MCSA_Local: 155 MCELF::SetBinding(SD, ELF::STB_LOCAL); 156 SD.setExternal(false); 157 BindingExplicitlySet.insert(Symbol); 158 break; 159 160 case MCSA_ELF_TypeFunction: 161 MCELF::SetType(SD, ELF::STT_FUNC); 162 break; 163 164 case MCSA_ELF_TypeIndFunction: 165 MCELF::SetType(SD, ELF::STT_GNU_IFUNC); 166 break; 167 168 case MCSA_ELF_TypeObject: 169 MCELF::SetType(SD, ELF::STT_OBJECT); 170 break; 171 172 case MCSA_ELF_TypeTLS: 173 MCELF::SetType(SD, ELF::STT_TLS); 174 break; 175 176 case MCSA_ELF_TypeCommon: 177 MCELF::SetType(SD, ELF::STT_COMMON); 178 break; 179 180 case MCSA_ELF_TypeNoType: 181 MCELF::SetType(SD, ELF::STT_NOTYPE); 182 break; 183 184 case MCSA_Protected: 185 MCELF::SetVisibility(SD, ELF::STV_PROTECTED); 186 break; 187 188 case MCSA_Hidden: 189 MCELF::SetVisibility(SD, ELF::STV_HIDDEN); 190 break; 191 192 case MCSA_Internal: 193 MCELF::SetVisibility(SD, ELF::STV_INTERNAL); 194 break; 195 } 196} 197 198void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, 199 unsigned ByteAlignment) { 200 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 201 202 if (!BindingExplicitlySet.count(Symbol)) { 203 MCELF::SetBinding(SD, ELF::STB_GLOBAL); 204 SD.setExternal(true); 205 } 206 207 MCELF::SetType(SD, ELF::STT_OBJECT); 208 209 if (MCELF::GetBinding(SD) == ELF_STB_Local) { 210 const MCSection *Section = getAssembler().getContext().getELFSection(".bss", 211 ELF::SHT_NOBITS, 212 ELF::SHF_WRITE | 213 ELF::SHF_ALLOC, 214 SectionKind::getBSS()); 215 Symbol->setSection(*Section); 216 217 struct LocalCommon L = {&SD, Size, ByteAlignment}; 218 LocalCommons.push_back(L); 219 } else { 220 SD.setCommon(Size, ByteAlignment); 221 } 222 223 SD.setSize(MCConstantExpr::Create(Size, getContext())); 224} 225 226void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, 227 unsigned ByteAlignment) { 228 // FIXME: Should this be caught and done earlier? 229 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 230 MCELF::SetBinding(SD, ELF::STB_LOCAL); 231 SD.setExternal(false); 232 BindingExplicitlySet.insert(Symbol); 233 EmitCommonSymbol(Symbol, Size, ByteAlignment); 234} 235 236void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { 237 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 238 // MCObjectStreamer. 239 getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); 240} 241 242void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, 243 int64_t Value, unsigned ValueSize, 244 unsigned MaxBytesToEmit) { 245 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 246 // MCObjectStreamer. 247 if (MaxBytesToEmit == 0) 248 MaxBytesToEmit = ByteAlignment; 249 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, 250 getCurrentSectionData()); 251 252 // Update the maximum alignment on the current section if necessary. 253 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 254 getCurrentSectionData()->setAlignment(ByteAlignment); 255} 256 257void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, 258 unsigned MaxBytesToEmit) { 259 // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into 260 // MCObjectStreamer. 261 if (MaxBytesToEmit == 0) 262 MaxBytesToEmit = ByteAlignment; 263 MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, 264 getCurrentSectionData()); 265 F->setEmitNops(true); 266 267 // Update the maximum alignment on the current section if necessary. 268 if (ByteAlignment > getCurrentSectionData()->getAlignment()) 269 getCurrentSectionData()->setAlignment(ByteAlignment); 270} 271 272// Add a symbol for the file name of this module. This is the second 273// entry in the module's symbol table (the first being the null symbol). 274void MCELFStreamer::EmitFileDirective(StringRef Filename) { 275 MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); 276 Symbol->setSection(*getCurrentSection()); 277 Symbol->setAbsolute(); 278 279 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 280 281 SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); 282} 283 284void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { 285 switch (expr->getKind()) { 286 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); 287 case MCExpr::Constant: 288 break; 289 290 case MCExpr::Binary: { 291 const MCBinaryExpr *be = cast<MCBinaryExpr>(expr); 292 fixSymbolsInTLSFixups(be->getLHS()); 293 fixSymbolsInTLSFixups(be->getRHS()); 294 break; 295 } 296 297 case MCExpr::SymbolRef: { 298 const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr); 299 switch (symRef.getKind()) { 300 default: 301 return; 302 case MCSymbolRefExpr::VK_GOTTPOFF: 303 case MCSymbolRefExpr::VK_INDNTPOFF: 304 case MCSymbolRefExpr::VK_NTPOFF: 305 case MCSymbolRefExpr::VK_GOTNTPOFF: 306 case MCSymbolRefExpr::VK_TLSGD: 307 case MCSymbolRefExpr::VK_TLSLD: 308 case MCSymbolRefExpr::VK_TLSLDM: 309 case MCSymbolRefExpr::VK_TPOFF: 310 case MCSymbolRefExpr::VK_DTPOFF: 311 case MCSymbolRefExpr::VK_ARM_TLSGD: 312 case MCSymbolRefExpr::VK_ARM_TPOFF: 313 case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 314 case MCSymbolRefExpr::VK_Mips_TLSGD: 315 case MCSymbolRefExpr::VK_Mips_GOTTPREL: 316 case MCSymbolRefExpr::VK_Mips_TPREL_HI: 317 case MCSymbolRefExpr::VK_Mips_TPREL_LO: 318 break; 319 } 320 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol()); 321 MCELF::SetType(SD, ELF::STT_TLS); 322 break; 323 } 324 325 case MCExpr::Unary: 326 fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr()); 327 break; 328 } 329} 330 331void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { 332 this->MCObjectStreamer::EmitInstToFragment(Inst); 333 MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment()); 334 335 for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) 336 fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); 337} 338 339void MCELFStreamer::EmitInstToData(const MCInst &Inst) { 340 MCDataFragment *DF = getOrCreateDataFragment(); 341 342 SmallVector<MCFixup, 4> Fixups; 343 SmallString<256> Code; 344 raw_svector_ostream VecOS(Code); 345 getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); 346 VecOS.flush(); 347 348 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) 349 fixSymbolsInTLSFixups(Fixups[i].getValue()); 350 351 // Add the fixups and data. 352 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { 353 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); 354 DF->addFixup(Fixups[i]); 355 } 356 DF->getContents().append(Code.begin(), Code.end()); 357} 358 359void MCELFStreamer::Finish() { 360 EmitFrames(true); 361 362 for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), 363 e = LocalCommons.end(); 364 i != e; ++i) { 365 MCSymbolData *SD = i->SD; 366 uint64_t Size = i->Size; 367 unsigned ByteAlignment = i->ByteAlignment; 368 const MCSymbol &Symbol = SD->getSymbol(); 369 const MCSection &Section = Symbol.getSection(); 370 371 MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); 372 new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); 373 374 MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); 375 SD->setFragment(F); 376 377 // Update the maximum alignment of the section if necessary. 378 if (ByteAlignment > SectData.getAlignment()) 379 SectData.setAlignment(ByteAlignment); 380 } 381 382 this->MCObjectStreamer::Finish(); 383} 384 385MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, 386 raw_ostream &OS, MCCodeEmitter *CE, 387 bool RelaxAll, bool NoExecStack) { 388 MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); 389 if (RelaxAll) 390 S->getAssembler().setRelaxAll(true); 391 if (NoExecStack) 392 S->getAssembler().setNoExecStack(true); 393 return S; 394} 395