blob: caff1256d3b425b2e5b2c67122a1f4add2136055 [file] [log] [blame]
Daniel Dunbar7760fbe2009-08-21 09:11:24 +00001//===- 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
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000012#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCSection.h"
15#include "llvm/MC/MCSymbol.h"
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000016#include "llvm/Support/ErrorHandling.h"
17using namespace llvm;
18
19namespace {
20
21class MCMachOStreamer : public MCStreamer {
22 MCAssembler Assembler;
23
24 MCSectionData *CurSectionData;
25
26 DenseMap<const MCSection*, MCSectionData*> SectionMap;
Daniel Dunbar197f5632009-08-22 10:13:24 +000027
28 DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
29
30private:
31 MCFragment *getCurrentFragment() const {
32 assert(CurSectionData && "No current section!");
33
34 if (!CurSectionData->empty())
35 return &CurSectionData->getFragmentList().back();
36
37 return 0;
38 }
39
40 MCSymbolData &getSymbolData(MCSymbol &Symbol) {
41 MCSymbolData *&Entry = SymbolMap[&Symbol];
42
43 if (!Entry)
44 Entry = new MCSymbolData(Symbol, 0, 0, &Assembler);
45
46 return *Entry;
47 }
Daniel Dunbar7760fbe2009-08-21 09:11:24 +000048
49public:
50 MCMachOStreamer(MCContext &Context, raw_ostream &_OS)
51 : MCStreamer(Context), Assembler(_OS), CurSectionData(0) {}
52 ~MCMachOStreamer() {}
53
54 /// @name MCStreamer Interface
55 /// @{
56
57 virtual void SwitchSection(const MCSection *Section);
58
59 virtual void EmitLabel(MCSymbol *Symbol);
60
61 virtual void EmitAssemblerFlag(AssemblerFlag Flag);
62
63 virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
64 bool MakeAbsolute = false);
65
66 virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
67
68 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
69
70 virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value);
71
72 virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
73 unsigned Pow2Alignment, bool IsLocal);
74
75 virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = NULL,
76 unsigned Size = 0, unsigned Pow2Alignment = 0);
77
78 virtual void EmitBytes(const StringRef &Data);
79
80 virtual void EmitValue(const MCValue &Value, unsigned Size);
81
82 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
83 unsigned ValueSize = 1,
84 unsigned MaxBytesToEmit = 0);
85
86 virtual void EmitValueToOffset(const MCValue &Offset,
87 unsigned char Value = 0);
88
89 virtual void EmitInstruction(const MCInst &Inst);
90
91 virtual void Finish();
92
93 /// @}
94};
95
96} // end anonymous namespace.
97
98void MCMachOStreamer::SwitchSection(const MCSection *Section) {
99 assert(Section && "Cannot switch to a null section!");
Chris Lattnerbf7a11f2009-08-22 19:35:08 +0000100
101 // If already in this section, then this is a noop.
102 if (Section == CurSection) return;
103
104 CurSection = Section;
105 MCSectionData *&Entry = SectionMap[Section];
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000106
Chris Lattnerbf7a11f2009-08-22 19:35:08 +0000107 if (!Entry)
108 Entry = new MCSectionData(*Section, &Assembler);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000109
Chris Lattnerbf7a11f2009-08-22 19:35:08 +0000110 CurSectionData = Entry;
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000111}
112
113void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
Daniel Dunbar1c2ee9f2009-08-22 07:22:36 +0000114 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000115
Daniel Dunbar197f5632009-08-22 10:13:24 +0000116 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
117 if (!F)
118 F = new MCDataFragment(CurSectionData);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000119
Daniel Dunbar197f5632009-08-22 10:13:24 +0000120 MCSymbolData &SD = getSymbolData(*Symbol);
121 assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
122 SD.setFragment(F);
123 SD.setOffset(F->getContents().size());
124
Daniel Dunbar1c2ee9f2009-08-22 07:22:36 +0000125 Symbol->setSection(*CurSection);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000126}
127
128void MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
129 llvm_unreachable("FIXME: Not yet implemented!");
130}
131
132void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol,
133 const MCValue &Value,
134 bool MakeAbsolute) {
Daniel Dunbar1c2ee9f2009-08-22 07:22:36 +0000135 // Only absolute symbols can be redefined.
136 assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
137 "Cannot define a symbol twice!");
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000138
139 llvm_unreachable("FIXME: Not yet implemented!");
140}
141
142void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
143 SymbolAttr Attribute) {
Daniel Dunbar6fae16d2009-08-22 11:41:10 +0000144 switch (Attribute) {
145 default:
146 llvm_unreachable("FIXME: Not yet implemented!");
147
148 case MCStreamer::Global:
149 getSymbolData(*Symbol).setExternal(true);
150 break;
151 }
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000152}
153
154void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
155 llvm_unreachable("FIXME: Not yet implemented!");
156}
157
158void MCMachOStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) {
159 llvm_unreachable("FIXME: Not yet implemented!");
160}
161
162void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
163 unsigned Pow2Alignment,
164 bool IsLocal) {
165 llvm_unreachable("FIXME: Not yet implemented!");
166}
167
168void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
169 unsigned Size, unsigned Pow2Alignment) {
170 llvm_unreachable("FIXME: Not yet implemented!");
171}
172
173void MCMachOStreamer::EmitBytes(const StringRef &Data) {
Daniel Dunbar197f5632009-08-22 10:13:24 +0000174 MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
175 if (!DF)
176 DF = new MCDataFragment(CurSectionData);
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000177 DF->getContents().append(Data.begin(), Data.end());
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000178}
179
180void MCMachOStreamer::EmitValue(const MCValue &Value, unsigned Size) {
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000181 new MCFillFragment(Value, Size, 1, CurSectionData);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000182}
183
184void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
185 int64_t Value, unsigned ValueSize,
186 unsigned MaxBytesToEmit) {
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000187 if (MaxBytesToEmit == 0)
188 MaxBytesToEmit = ByteAlignment;
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000189 new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
190 CurSectionData);
191
Daniel Dunbar197f5632009-08-22 10:13:24 +0000192 // Update the maximum alignment on the current section if necessary.
Daniel Dunbar8fcefbe2009-08-21 18:29:01 +0000193 if (ByteAlignment > CurSectionData->getAlignment())
194 CurSectionData->setAlignment(ByteAlignment);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000195}
196
197void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset,
198 unsigned char Value) {
Daniel Dunbar3d153ff2009-08-21 23:07:38 +0000199 new MCOrgFragment(Offset, Value, CurSectionData);
Daniel Dunbar7760fbe2009-08-21 09:11:24 +0000200}
201
202void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
203 llvm_unreachable("FIXME: Not yet implemented!");
204}
205
206void MCMachOStreamer::Finish() {
207 Assembler.Finish();
208}
209
210MCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS) {
211 return new MCMachOStreamer(Context, OS);
212}