1 //===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCStreamer.h"
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/MCValue.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/raw_ostream.h"
26 class MCMachOStreamer
: public MCStreamer
{
27 /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
28 /// 16 bits of the implementation defined flags.
29 enum SymbolFlags
{ // See <mach-o/nlist.h>.
30 SF_DescFlagsMask
= 0xFFFF,
32 // Reference type flags.
33 SF_ReferenceTypeMask
= 0x0007,
34 SF_ReferenceTypeUndefinedNonLazy
= 0x0000,
35 SF_ReferenceTypeUndefinedLazy
= 0x0001,
36 SF_ReferenceTypeDefined
= 0x0002,
37 SF_ReferenceTypePrivateDefined
= 0x0003,
38 SF_ReferenceTypePrivateUndefinedNonLazy
= 0x0004,
39 SF_ReferenceTypePrivateUndefinedLazy
= 0x0005,
41 // Other 'desc' flags.
42 SF_NoDeadStrip
= 0x0020,
43 SF_WeakReference
= 0x0040,
44 SF_WeakDefinition
= 0x0080
48 MCAssembler Assembler
;
50 MCCodeEmitter
*Emitter
;
52 MCSectionData
*CurSectionData
;
54 DenseMap
<const MCSection
*, MCSectionData
*> SectionMap
;
56 DenseMap
<const MCSymbol
*, MCSymbolData
*> SymbolMap
;
59 MCFragment
*getCurrentFragment() const {
60 assert(CurSectionData
&& "No current section!");
62 if (!CurSectionData
->empty())
63 return &CurSectionData
->getFragmentList().back();
68 MCSectionData
&getSectionData(const MCSection
&Section
) {
69 MCSectionData
*&Entry
= SectionMap
[&Section
];
72 Entry
= new MCSectionData(Section
, &Assembler
);
77 MCSymbolData
&getSymbolData(const MCSymbol
&Symbol
) {
78 MCSymbolData
*&Entry
= SymbolMap
[&Symbol
];
81 Entry
= new MCSymbolData(Symbol
, 0, 0, &Assembler
);
87 MCMachOStreamer(MCContext
&Context
, raw_ostream
&_OS
, MCCodeEmitter
*_Emitter
)
88 : MCStreamer(Context
), Assembler(Context
, _OS
), Emitter(_Emitter
),
92 const MCExpr
*AddValueSymbols(const MCExpr
*Value
) {
93 switch (Value
->getKind()) {
94 case MCExpr::Constant
:
97 case MCExpr::Binary
: {
98 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Value
);
99 AddValueSymbols(BE
->getLHS());
100 AddValueSymbols(BE
->getRHS());
104 case MCExpr::SymbolRef
:
105 getSymbolData(cast
<MCSymbolRefExpr
>(Value
)->getSymbol());
109 AddValueSymbols(cast
<MCUnaryExpr
>(Value
)->getSubExpr());
116 /// @name MCStreamer Interface
119 virtual void SwitchSection(const MCSection
*Section
);
121 virtual void EmitLabel(MCSymbol
*Symbol
);
123 virtual void EmitAssemblerFlag(AssemblerFlag Flag
);
125 virtual void EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
);
127 virtual void EmitSymbolAttribute(MCSymbol
*Symbol
, SymbolAttr Attribute
);
129 virtual void EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
);
131 virtual void EmitCommonSymbol(MCSymbol
*Symbol
, unsigned Size
,
132 unsigned ByteAlignment
);
134 virtual void EmitZerofill(const MCSection
*Section
, MCSymbol
*Symbol
= 0,
135 unsigned Size
= 0, unsigned ByteAlignment
= 0);
137 virtual void EmitBytes(const StringRef
&Data
);
139 virtual void EmitValue(const MCExpr
*Value
, unsigned Size
);
141 virtual void EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
= 0,
142 unsigned ValueSize
= 1,
143 unsigned MaxBytesToEmit
= 0);
145 virtual void EmitValueToOffset(const MCExpr
*Offset
,
146 unsigned char Value
= 0);
148 virtual void EmitInstruction(const MCInst
&Inst
);
150 virtual void Finish();
155 } // end anonymous namespace.
157 void MCMachOStreamer::SwitchSection(const MCSection
*Section
) {
158 assert(Section
&& "Cannot switch to a null section!");
160 // If already in this section, then this is a noop.
161 if (Section
== CurSection
) return;
163 CurSection
= Section
;
164 CurSectionData
= &getSectionData(*Section
);
167 void MCMachOStreamer::EmitLabel(MCSymbol
*Symbol
) {
168 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
170 // FIXME: We should also use offsets into Fill fragments.
171 MCDataFragment
*F
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
173 F
= new MCDataFragment(CurSectionData
);
175 MCSymbolData
&SD
= getSymbolData(*Symbol
);
176 assert(!SD
.getFragment() && "Unexpected fragment on symbol data!");
178 SD
.setOffset(F
->getContents().size());
180 // This causes the reference type and weak reference flags to be cleared.
181 SD
.setFlags(SD
.getFlags() & ~(SF_WeakReference
| SF_ReferenceTypeMask
));
183 Symbol
->setSection(*CurSection
);
186 void MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag
) {
188 case SubsectionsViaSymbols
:
189 Assembler
.setSubsectionsViaSymbols(true);
193 assert(0 && "invalid assembler flag!");
196 void MCMachOStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
197 // Only absolute symbols can be redefined.
198 assert((Symbol
->isUndefined() || Symbol
->isAbsolute()) &&
199 "Cannot define a symbol twice!");
201 llvm_unreachable("FIXME: Not yet implemented!");
204 void MCMachOStreamer::EmitSymbolAttribute(MCSymbol
*Symbol
,
205 SymbolAttr Attribute
) {
206 // Indirect symbols are handled differently, to match how 'as' handles
207 // them. This makes writing matching .o files easier.
208 if (Attribute
== MCStreamer::IndirectSymbol
) {
209 // Note that we intentionally cannot use the symbol data here; this is
210 // important for matching the string table that 'as' generates.
211 IndirectSymbolData ISD
;
213 ISD
.SectionData
= CurSectionData
;
214 Assembler
.getIndirectSymbols().push_back(ISD
);
218 // Adding a symbol attribute always introduces the symbol, note that an
219 // important side effect of calling getSymbolData here is to register the
220 // symbol with the assembler.
221 MCSymbolData
&SD
= getSymbolData(*Symbol
);
223 // The implementation of symbol attributes is designed to match 'as', but it
224 // leaves much to desired. It doesn't really make sense to arbitrarily add and
225 // remove flags, but 'as' allows this (in particular, see .desc).
227 // In the future it might be worth trying to make these operations more well
230 case MCStreamer::IndirectSymbol
:
231 case MCStreamer::Hidden
:
232 case MCStreamer::Internal
:
233 case MCStreamer::Protected
:
234 case MCStreamer::Weak
:
235 assert(0 && "Invalid symbol attribute for Mach-O!");
238 case MCStreamer::Global
:
239 SD
.setExternal(true);
242 case MCStreamer::LazyReference
:
243 // FIXME: This requires -dynamic.
244 SD
.setFlags(SD
.getFlags() | SF_NoDeadStrip
);
245 if (Symbol
->isUndefined())
246 SD
.setFlags(SD
.getFlags() | SF_ReferenceTypeUndefinedLazy
);
249 // Since .reference sets the no dead strip bit, it is equivalent to
250 // .no_dead_strip in practice.
251 case MCStreamer::Reference
:
252 case MCStreamer::NoDeadStrip
:
253 SD
.setFlags(SD
.getFlags() | SF_NoDeadStrip
);
256 case MCStreamer::PrivateExtern
:
257 SD
.setExternal(true);
258 SD
.setPrivateExtern(true);
261 case MCStreamer::WeakReference
:
262 // FIXME: This requires -dynamic.
263 if (Symbol
->isUndefined())
264 SD
.setFlags(SD
.getFlags() | SF_WeakReference
);
267 case MCStreamer::WeakDefinition
:
268 // FIXME: 'as' enforces that this is defined and global. The manual claims
269 // it has to be in a coalesced section, but this isn't enforced.
270 SD
.setFlags(SD
.getFlags() | SF_WeakDefinition
);
275 void MCMachOStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {
276 // Encode the 'desc' value into the lowest implementation defined bits.
277 assert(DescValue
== (DescValue
& SF_DescFlagsMask
) &&
278 "Invalid .desc value!");
279 getSymbolData(*Symbol
).setFlags(DescValue
& SF_DescFlagsMask
);
282 void MCMachOStreamer::EmitCommonSymbol(MCSymbol
*Symbol
, unsigned Size
,
283 unsigned ByteAlignment
) {
284 // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
285 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
287 MCSymbolData
&SD
= getSymbolData(*Symbol
);
288 SD
.setExternal(true);
289 SD
.setCommon(Size
, ByteAlignment
);
292 void MCMachOStreamer::EmitZerofill(const MCSection
*Section
, MCSymbol
*Symbol
,
293 unsigned Size
, unsigned ByteAlignment
) {
294 MCSectionData
&SectData
= getSectionData(*Section
);
296 // The symbol may not be present, which only creates the section.
300 // FIXME: Assert that this section has the zerofill type.
302 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
304 MCSymbolData
&SD
= getSymbolData(*Symbol
);
306 MCFragment
*F
= new MCZeroFillFragment(Size
, ByteAlignment
, &SectData
);
309 Symbol
->setSection(*Section
);
311 // Update the maximum alignment on the zero fill section if necessary.
312 if (ByteAlignment
> SectData
.getAlignment())
313 SectData
.setAlignment(ByteAlignment
);
316 void MCMachOStreamer::EmitBytes(const StringRef
&Data
) {
317 MCDataFragment
*DF
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
319 DF
= new MCDataFragment(CurSectionData
);
320 DF
->getContents().append(Data
.begin(), Data
.end());
323 void MCMachOStreamer::EmitValue(const MCExpr
*Value
, unsigned Size
) {
326 if (!AddValueSymbols(Value
)->EvaluateAsRelocatable(getContext(), RelocValue
))
327 return llvm_report_error("expected relocatable expression");
329 new MCFillFragment(RelocValue
, Size
, 1, CurSectionData
);
332 void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment
,
333 int64_t Value
, unsigned ValueSize
,
334 unsigned MaxBytesToEmit
) {
335 if (MaxBytesToEmit
== 0)
336 MaxBytesToEmit
= ByteAlignment
;
337 new MCAlignFragment(ByteAlignment
, Value
, ValueSize
, MaxBytesToEmit
,
340 // Update the maximum alignment on the current section if necessary.
341 if (ByteAlignment
> CurSectionData
->getAlignment())
342 CurSectionData
->setAlignment(ByteAlignment
);
345 void MCMachOStreamer::EmitValueToOffset(const MCExpr
*Offset
,
346 unsigned char Value
) {
349 if (!AddValueSymbols(Offset
)->EvaluateAsRelocatable(getContext(),
351 return llvm_report_error("expected relocatable expression");
353 new MCOrgFragment(RelocOffset
, Value
, CurSectionData
);
356 void MCMachOStreamer::EmitInstruction(const MCInst
&Inst
) {
358 for (unsigned i
= 0; i
!= Inst
.getNumOperands(); ++i
)
359 if (Inst
.getOperand(i
).isExpr())
360 AddValueSymbols(Inst
.getOperand(i
).getExpr());
363 llvm_unreachable("no code emitter available!");
365 // FIXME: Relocations!
366 SmallString
<256> Code
;
367 raw_svector_ostream
VecOS(Code
);
368 Emitter
->EncodeInstruction(Inst
, VecOS
);
369 EmitBytes(VecOS
.str());
372 void MCMachOStreamer::Finish() {
376 MCStreamer
*llvm::createMachOStreamer(MCContext
&Context
, raw_ostream
&OS
,
378 return new MCMachOStreamer(Context
, OS
, CE
);