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