Relax address updates in the eh_frame section.
[oota-llvm.git] / lib / MC / MCObjectStreamer.cpp
1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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/MCAsmInfo.h"
11 #include "llvm/MC/MCObjectStreamer.h"
12
13 #include "llvm/Support/ErrorHandling.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCCodeEmitter.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDwarf.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Target/TargetAsmBackend.h"
21 #include "llvm/Target/TargetAsmInfo.h"
22 using namespace llvm;
23
24 MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
25                                    raw_ostream &OS, MCCodeEmitter *Emitter_)
26   : MCStreamer(Context),
27     Assembler(new MCAssembler(Context, TAB,
28                               *Emitter_, *TAB.createObjectWriter(OS),
29                               OS)),
30     CurSectionData(0)
31 {
32 }
33
34 MCObjectStreamer::~MCObjectStreamer() {
35   delete &Assembler->getBackend();
36   delete &Assembler->getEmitter();
37   delete &Assembler->getWriter();
38   delete Assembler;
39 }
40
41 MCFragment *MCObjectStreamer::getCurrentFragment() const {
42   assert(getCurrentSectionData() && "No current section!");
43
44   if (!getCurrentSectionData()->empty())
45     return &getCurrentSectionData()->getFragmentList().back();
46
47   return 0;
48 }
49
50 MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
51   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
52   if (!F)
53     F = new MCDataFragment(getCurrentSectionData());
54   return F;
55 }
56
57 const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
58   switch (Value->getKind()) {
59   case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
60   case MCExpr::Constant:
61     break;
62
63   case MCExpr::Binary: {
64     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
65     AddValueSymbols(BE->getLHS());
66     AddValueSymbols(BE->getRHS());
67     break;
68   }
69
70   case MCExpr::SymbolRef:
71     Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
72     break;
73
74   case MCExpr::Unary:
75     AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
76     break;
77   }
78
79   return Value;
80 }
81
82 void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
83                                      bool isPCRel, unsigned AddrSpace) {
84   assert(AddrSpace == 0 && "Address space must be 0!");
85   MCDataFragment *DF = getOrCreateDataFragment();
86
87   // Avoid fixups when possible.
88   int64_t AbsValue;
89   if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
90     EmitIntValue(AbsValue, Size, AddrSpace);
91     return;
92   }
93   DF->addFixup(MCFixup::Create(DF->getContents().size(),
94                                Value,
95                                MCFixup::getKindForSize(Size, isPCRel)));
96   DF->getContents().resize(DF->getContents().size() + Size, 0);
97 }
98
99 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
100   assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
101   assert(CurSection && "Cannot emit before setting section!");
102
103   Symbol->setSection(*CurSection);
104
105   MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
106
107   // FIXME: This is wasteful, we don't necessarily need to create a data
108   // fragment. Instead, we should mark the symbol as pointing into the data
109   // fragment if it exists, otherwise we should just queue the label and set its
110   // fragment pointer when we emit the next fragment.
111   MCDataFragment *F = getOrCreateDataFragment();
112   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
113   SD.setFragment(F);
114   SD.setOffset(F->getContents().size());
115 }
116
117 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
118                                         unsigned AddrSpace) {
119   int64_t IntValue;
120   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
121     EmitULEB128IntValue(IntValue, AddrSpace);
122     return;
123   }
124   new MCLEBFragment(*Value, false, getCurrentSectionData());
125 }
126
127 void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
128                                         unsigned AddrSpace) {
129   int64_t IntValue;
130   if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
131     EmitSLEB128IntValue(IntValue, AddrSpace);
132     return;
133   }
134   new MCLEBFragment(*Value, true, getCurrentSectionData());
135 }
136
137 void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
138                                          const MCSymbol *Symbol) {
139   report_fatal_error("This file format doesn't support weak aliases.");
140 }
141
142 void MCObjectStreamer::SwitchSection(const MCSection *Section) {
143   assert(Section && "Cannot switch to a null section!");
144
145   // If already in this section, then this is a noop.
146   if (Section == CurSection) return;
147
148   PrevSection = CurSection;
149   CurSection = Section;
150   CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
151 }
152
153 void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
154   // Scan for values.
155   for (unsigned i = Inst.getNumOperands(); i--; )
156     if (Inst.getOperand(i).isExpr())
157       AddValueSymbols(Inst.getOperand(i).getExpr());
158
159   getCurrentSectionData()->setHasInstructions(true);
160
161   // Now that a machine instruction has been assembled into this section, make
162   // a line entry for any .loc directive that has been seen.
163   MCLineEntry::Make(this, getCurrentSection());
164
165   // If this instruction doesn't need relaxation, just emit it as data.
166   if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
167     EmitInstToData(Inst);
168     return;
169   }
170
171   // Otherwise, if we are relaxing everything, relax the instruction as much as
172   // possible and emit it as data.
173   if (getAssembler().getRelaxAll()) {
174     MCInst Relaxed;
175     getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
176     while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
177       getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
178     EmitInstToData(Relaxed);
179     return;
180   }
181
182   // Otherwise emit to a separate fragment.
183   EmitInstToFragment(Inst);
184 }
185
186 void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
187   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
188
189   raw_svector_ostream VecOS(IF->getCode());
190   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
191 }
192
193 static const MCExpr *BuildSymbolDiff(MCContext &Context,
194                                      const MCSymbol *A, const MCSymbol *B) {
195   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
196   const MCExpr *ARef =
197     MCSymbolRefExpr::Create(A, Variant, Context);
198   const MCExpr *BRef =
199     MCSymbolRefExpr::Create(B, Variant, Context);
200   const MCExpr *AddrDelta =
201     MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
202   return AddrDelta;
203 }
204
205 static const MCExpr *ForceExpAbs(MCObjectStreamer *Streamer,
206                                   MCContext &Context, const MCExpr* Expr) {
207  if (Context.getAsmInfo().hasAggressiveSymbolFolding())
208    return Expr;
209
210  MCSymbol *ABS = Context.CreateTempSymbol();
211  Streamer->EmitAssignment(ABS, Expr);
212  return MCSymbolRefExpr::Create(ABS, Context);
213 }
214
215 void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
216                                                 const MCSymbol *LastLabel,
217                                                 const MCSymbol *Label) {
218   if (!LastLabel) {
219     int PointerSize = getContext().getTargetAsmInfo().getPointerSize();
220     EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
221     return;
222   }
223   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
224   int64_t Res;
225   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
226     MCDwarfLineAddr::Emit(this, LineDelta, Res);
227     return;
228   }
229   AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
230   new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
231 }
232
233 void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
234                                                  const MCSymbol *Label) {
235   const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
236   int64_t Res;
237   if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
238     MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
239     return;
240   }
241   AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
242   new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
243 }
244
245 void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
246                                         unsigned char Value) {
247   new MCOrgFragment(*Offset, Value, getCurrentSectionData());
248 }
249
250 void MCObjectStreamer::Finish() {
251   // Dump out the dwarf file & directory tables and line tables.
252   if (getContext().hasDwarfFiles())
253     MCDwarfFileTable::Emit(this);
254
255   getAssembler().Finish();
256 }