MCMachOStreamer.cpp revision 198396
1234353Sdim//===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
2206083Srdivacky//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7206083Srdivacky//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed
10193323Sed#include "llvm/MC/MCStreamer.h"
11193323Sed
12193323Sed#include "llvm/MC/MCAssembler.h"
13193323Sed#include "llvm/MC/MCContext.h"
14193323Sed#include "llvm/MC/MCCodeEmitter.h"
15193323Sed#include "llvm/MC/MCExpr.h"
16193323Sed#include "llvm/MC/MCInst.h"
17193323Sed#include "llvm/MC/MCSection.h"
18205407Srdivacky#include "llvm/MC/MCSymbol.h"
19205407Srdivacky#include "llvm/MC/MCValue.h"
20193323Sed#include "llvm/Support/ErrorHandling.h"
21193323Sed#include "llvm/Support/raw_ostream.h"
22193323Sedusing namespace llvm;
23193323Sed
24193323Sednamespace {
25193323Sed
26193323Sedclass MCMachOStreamer : public MCStreamer {
27193323Sed  /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
28226633Sdim  /// 16 bits of the implementation defined flags.
29193323Sed  enum SymbolFlags { // See <mach-o/nlist.h>.
30193323Sed    SF_DescFlagsMask                        = 0xFFFF,
31193323Sed
32193323Sed    // Reference type flags.
33193323Sed    SF_ReferenceTypeMask                    = 0x0007,
34193323Sed    SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
35193323Sed    SF_ReferenceTypeUndefinedLazy           = 0x0001,
36205407Srdivacky    SF_ReferenceTypeDefined                 = 0x0002,
37200581Srdivacky    SF_ReferenceTypePrivateDefined          = 0x0003,
38205407Srdivacky    SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
39212904Sdim    SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
40212904Sdim
41193323Sed    // Other 'desc' flags.
42212904Sdim    SF_NoDeadStrip                          = 0x0020,
43212904Sdim    SF_WeakReference                        = 0x0040,
44212904Sdim    SF_WeakDefinition                       = 0x0080
45212904Sdim  };
46212904Sdim
47212904Sdimprivate:
48212904Sdim  MCAssembler Assembler;
49212904Sdim
50212904Sdim  MCCodeEmitter *Emitter;
51212904Sdim
52193323Sed  MCSectionData *CurSectionData;
53212904Sdim
54212904Sdim  DenseMap<const MCSection*, MCSectionData*> SectionMap;
55193323Sed
56212904Sdim  DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
57212904Sdim
58212904Sdimprivate:
59212904Sdim  MCFragment *getCurrentFragment() const {
60212904Sdim    assert(CurSectionData && "No current section!");
61212904Sdim
62212904Sdim    if (!CurSectionData->empty())
63212904Sdim      return &CurSectionData->getFragmentList().back();
64212904Sdim
65212904Sdim    return 0;
66212904Sdim  }
67212904Sdim
68212904Sdim  MCSectionData &getSectionData(const MCSection &Section) {
69212904Sdim    MCSectionData *&Entry = SectionMap[&Section];
70212904Sdim
71226633Sdim    if (!Entry)
72194710Sed      Entry = new MCSectionData(Section, &Assembler);
73198090Srdivacky
74198090Srdivacky    return *Entry;
75218893Sdim  }
76198090Srdivacky
77198090Srdivacky  MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
78198090Srdivacky    MCSymbolData *&Entry = SymbolMap[&Symbol];
79193323Sed
80198090Srdivacky    if (!Entry)
81198090Srdivacky      Entry = new MCSymbolData(Symbol, 0, 0, &Assembler);
82198090Srdivacky
83198090Srdivacky    return *Entry;
84193323Sed  }
85205407Srdivacky
86195340Sedpublic:
87193323Sed  MCMachOStreamer(MCContext &Context, raw_ostream &_OS, MCCodeEmitter *_Emitter)
88218893Sdim    : MCStreamer(Context), Assembler(Context, _OS), Emitter(_Emitter),
89195340Sed      CurSectionData(0) {}
90218893Sdim  ~MCMachOStreamer() {}
91218893Sdim
92195340Sed  const MCExpr *AddValueSymbols(const MCExpr *Value) {
93212904Sdim    switch (Value->getKind()) {
94212904Sdim    case MCExpr::Constant:
95212904Sdim      break;
96212904Sdim
97212904Sdim    case MCExpr::Binary: {
98212904Sdim      const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
99212904Sdim      AddValueSymbols(BE->getLHS());
100212904Sdim      AddValueSymbols(BE->getRHS());
101212904Sdim      break;
102212904Sdim    }
103212904Sdim
104212904Sdim    case MCExpr::SymbolRef:
105212904Sdim      getSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
106212904Sdim      break;
107212904Sdim
108195340Sed    case MCExpr::Unary:
109218893Sdim      AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
110195340Sed      break;
111195340Sed    }
112195340Sed
113195340Sed    return Value;
114195340Sed  }
115195340Sed
116195340Sed  /// @name MCStreamer Interface
117195340Sed  /// @{
118205218Srdivacky
119195340Sed  virtual void SwitchSection(const MCSection *Section);
120198892Srdivacky
121219077Sdim  virtual void EmitLabel(MCSymbol *Symbol);
122219077Sdim
123198892Srdivacky  virtual void EmitAssemblerFlag(AssemblerFlag Flag);
124198892Srdivacky
125198892Srdivacky  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
126198892Srdivacky
127198892Srdivacky  virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
128219077Sdim
129198892Srdivacky  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
130195340Sed
131198090Srdivacky  virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
132198090Srdivacky                                unsigned ByteAlignment);
133198090Srdivacky
134226633Sdim  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
135226633Sdim                            unsigned Size = 0, unsigned ByteAlignment = 0);
136226633Sdim
137212904Sdim  virtual void EmitBytes(const StringRef &Data);
138212904Sdim
139218893Sdim  virtual void EmitValue(const MCExpr *Value, unsigned Size);
140218893Sdim
141226633Sdim  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
142218893Sdim                                    unsigned ValueSize = 1,
143218893Sdim                                    unsigned MaxBytesToEmit = 0);
144218893Sdim
145218893Sdim  virtual void EmitValueToOffset(const MCExpr *Offset,
146218893Sdim                                 unsigned char Value = 0);
147218893Sdim
148198090Srdivacky  virtual void EmitInstruction(const MCInst &Inst);
149198090Srdivacky
150226633Sdim  virtual void Finish();
151226633Sdim
152198090Srdivacky  /// @}
153198090Srdivacky};
154212904Sdim
155226633Sdim} // end anonymous namespace.
156198090Srdivacky
157198090Srdivackyvoid MCMachOStreamer::SwitchSection(const MCSection *Section) {
158263508Sdim  assert(Section && "Cannot switch to a null section!");
159263508Sdim
160263508Sdim  // If already in this section, then this is a noop.
161263508Sdim  if (Section == CurSection) return;
162263508Sdim
163263508Sdim  CurSection = Section;
164263508Sdim  CurSectionData = &getSectionData(*Section);
165263508Sdim}
166263508Sdim
167263508Sdimvoid MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
168198090Srdivacky  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
169226633Sdim
170198090Srdivacky  // FIXME: We should also use offsets into Fill fragments.
171218893Sdim  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
172198090Srdivacky  if (!F)
173218893Sdim    F = new MCDataFragment(CurSectionData);
174226633Sdim
175198090Srdivacky  MCSymbolData &SD = getSymbolData(*Symbol);
176198090Srdivacky  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
177198090Srdivacky  SD.setFragment(F);
178198090Srdivacky  SD.setOffset(F->getContents().size());
179218893Sdim
180198090Srdivacky  // This causes the reference type and weak reference flags to be cleared.
181218893Sdim  SD.setFlags(SD.getFlags() & ~(SF_WeakReference | SF_ReferenceTypeMask));
182226633Sdim
183198090Srdivacky  Symbol->setSection(*CurSection);
184198090Srdivacky}
185205218Srdivacky
186205218Srdivackyvoid MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
187234353Sdim  switch (Flag) {
188226633Sdim  case SubsectionsViaSymbols:
189226633Sdim    Assembler.setSubsectionsViaSymbols(true);
190226633Sdim    return;
191218893Sdim  }
192218893Sdim
193226633Sdim  assert(0 && "invalid assembler flag!");
194218893Sdim}
195205218Srdivacky
196226633Sdimvoid MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
197226633Sdim  // Only absolute symbols can be redefined.
198226633Sdim  assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
199226633Sdim         "Cannot define a symbol twice!");
200205218Srdivacky
201205218Srdivacky  // FIXME: Lift context changes into super class.
202226633Sdim  // FIXME: Set associated section.
203218893Sdim  Symbol->setValue(Value);
204205218Srdivacky}
205205218Srdivacky
206221345Sdimvoid MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
207221345Sdim                                          SymbolAttr Attribute) {
208221345Sdim  // Indirect symbols are handled differently, to match how 'as' handles
209221345Sdim  // them. This makes writing matching .o files easier.
210221345Sdim  if (Attribute == MCStreamer::IndirectSymbol) {
211221345Sdim    // Note that we intentionally cannot use the symbol data here; this is
212221345Sdim    // important for matching the string table that 'as' generates.
213221345Sdim    IndirectSymbolData ISD;
214234353Sdim    ISD.Symbol = Symbol;
215221345Sdim    ISD.SectionData = CurSectionData;
216221345Sdim    Assembler.getIndirectSymbols().push_back(ISD);
217226633Sdim    return;
218234353Sdim  }
219205218Srdivacky
220234353Sdim  // Adding a symbol attribute always introduces the symbol, note that an
221221345Sdim  // important side effect of calling getSymbolData here is to register the
222221345Sdim  // symbol with the assembler.
223226633Sdim  MCSymbolData &SD = getSymbolData(*Symbol);
224234353Sdim
225221345Sdim  // The implementation of symbol attributes is designed to match 'as', but it
226234353Sdim  // leaves much to desired. It doesn't really make sense to arbitrarily add and
227221345Sdim  // remove flags, but 'as' allows this (in particular, see .desc).
228221345Sdim  //
229226633Sdim  // In the future it might be worth trying to make these operations more well
230234353Sdim  // defined.
231221345Sdim  switch (Attribute) {
232234353Sdim  case MCStreamer::IndirectSymbol:
233221345Sdim  case MCStreamer::Hidden:
234221345Sdim  case MCStreamer::Internal:
235226633Sdim  case MCStreamer::Protected:
236234353Sdim  case MCStreamer::Weak:
237221345Sdim    assert(0 && "Invalid symbol attribute for Mach-O!");
238205218Srdivacky    break;
239198090Srdivacky
240226633Sdim  case MCStreamer::Global:
241226633Sdim    SD.setExternal(true);
242226633Sdim    break;
243226633Sdim
244226633Sdim  case MCStreamer::LazyReference:
245226633Sdim    // FIXME: This requires -dynamic.
246226633Sdim    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
247226633Sdim    if (Symbol->isUndefined())
248226633Sdim      SD.setFlags(SD.getFlags() | SF_ReferenceTypeUndefinedLazy);
249226633Sdim    break;
250263508Sdim
251263508Sdim    // Since .reference sets the no dead strip bit, it is equivalent to
252226633Sdim    // .no_dead_strip in practice.
253226633Sdim  case MCStreamer::Reference:
254234353Sdim  case MCStreamer::NoDeadStrip:
255234353Sdim    SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
256226633Sdim    break;
257234353Sdim
258234353Sdim  case MCStreamer::PrivateExtern:
259234353Sdim    SD.setExternal(true);
260234353Sdim    SD.setPrivateExtern(true);
261234353Sdim    break;
262234353Sdim
263226633Sdim  case MCStreamer::WeakReference:
264193323Sed    // FIXME: This requires -dynamic.
265193323Sed    if (Symbol->isUndefined())
266193323Sed      SD.setFlags(SD.getFlags() | SF_WeakReference);
267226633Sdim    break;
268224145Sdim
269201360Srdivacky  case MCStreamer::WeakDefinition:
270193323Sed    // FIXME: 'as' enforces that this is defined and global. The manual claims
271193323Sed    // it has to be in a coalesced section, but this isn't enforced.
272193323Sed    SD.setFlags(SD.getFlags() | SF_WeakDefinition);
273193323Sed    break;
274224145Sdim  }
275193323Sed}
276193323Sed
277193323Sedvoid MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
278205407Srdivacky  // Encode the 'desc' value into the lowest implementation defined bits.
279198892Srdivacky  assert(DescValue == (DescValue & SF_DescFlagsMask) &&
280193323Sed         "Invalid .desc value!");
281198090Srdivacky  getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask);
282226633Sdim}
283226633Sdim
284226633Sdimvoid MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
285226633Sdim                                       unsigned ByteAlignment) {
286206083Srdivacky  // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
287218893Sdim  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
288218893Sdim
289218893Sdim  MCSymbolData &SD = getSymbolData(*Symbol);
290226633Sdim  SD.setExternal(true);
291218893Sdim  SD.setCommon(Size, ByteAlignment);
292224145Sdim}
293224145Sdim
294224145Sdimvoid MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
295224145Sdim                                   unsigned Size, unsigned ByteAlignment) {
296224145Sdim  MCSectionData &SectData = getSectionData(*Section);
297226633Sdim
298206274Srdivacky  // The symbol may not be present, which only creates the section.
299193323Sed  if (!Symbol)
300198090Srdivacky    return;
301193323Sed
302193323Sed  // FIXME: Assert that this section has the zerofill type.
303201360Srdivacky
304201360Srdivacky  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
305234353Sdim
306234353Sdim  MCSymbolData &SD = getSymbolData(*Symbol);
307234353Sdim
308234353Sdim  MCFragment *F = new MCZeroFillFragment(Size, ByteAlignment, &SectData);
309234353Sdim  SD.setFragment(F);
310234353Sdim
311234353Sdim  Symbol->setSection(*Section);
312234353Sdim
313201360Srdivacky  // Update the maximum alignment on the zero fill section if necessary.
314201360Srdivacky  if (ByteAlignment > SectData.getAlignment())
315224145Sdim    SectData.setAlignment(ByteAlignment);
316201360Srdivacky}
317226633Sdim
318226633Sdimvoid MCMachOStreamer::EmitBytes(const StringRef &Data) {
319226633Sdim  MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
320201360Srdivacky  if (!DF)
321201360Srdivacky    DF = new MCDataFragment(CurSectionData);
322201360Srdivacky  DF->getContents().append(Data.begin(), Data.end());
323224145Sdim}
324201360Srdivacky
325226633Sdimvoid MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
326226633Sdim  new MCFillFragment(*AddValueSymbols(Value), Size, 1, CurSectionData);
327226633Sdim}
328201360Srdivacky
329234353Sdimvoid MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
330234353Sdim                                           int64_t Value, unsigned ValueSize,
331234353Sdim                                           unsigned MaxBytesToEmit) {
332234353Sdim  if (MaxBytesToEmit == 0)
333234353Sdim    MaxBytesToEmit = ByteAlignment;
334234353Sdim  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
335234353Sdim                      CurSectionData);
336234353Sdim
337234353Sdim  // Update the maximum alignment on the current section if necessary.
338234353Sdim  if (ByteAlignment > CurSectionData->getAlignment())
339234353Sdim    CurSectionData->setAlignment(ByteAlignment);
340234353Sdim}
341234353Sdim
342234353Sdimvoid MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset,
343234353Sdim                                        unsigned char Value) {
344234353Sdim  new MCOrgFragment(*Offset, Value, CurSectionData);
345234353Sdim}
346234353Sdim
347234353Sdimvoid MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
348234353Sdim  // Scan for values.
349234353Sdim  for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
350234353Sdim    if (Inst.getOperand(i).isExpr())
351234353Sdim      AddValueSymbols(Inst.getOperand(i).getExpr());
352234353Sdim
353234353Sdim  if (!Emitter)
354234353Sdim    llvm_unreachable("no code emitter available!");
355218893Sdim
356224145Sdim  // FIXME: Relocations!
357224145Sdim  SmallString<256> Code;
358193323Sed  raw_svector_ostream VecOS(Code);
359193323Sed  Emitter->EncodeInstruction(Inst, VecOS);
360193323Sed  EmitBytes(VecOS.str());
361221345Sdim}
362224145Sdim
363193323Sedvoid MCMachOStreamer::Finish() {
364193323Sed  Assembler.Finish();
365218893Sdim}
366224145Sdim
367218893SdimMCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS,
368218893Sdim                                      MCCodeEmitter *CE) {
369224145Sdim  return new MCMachOStreamer(Context, OS, CE);
370218893Sdim}
371218893Sdim