File: | lib/MC/MCObjectStreamer.cpp |
Location: | line 384, column 23 |
Description: | Called C++ object pointer is null |
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/MCObjectStreamer.h" | |||
11 | #include "llvm/ADT/STLExtras.h" | |||
12 | #include "llvm/MC/MCAsmBackend.h" | |||
13 | #include "llvm/MC/MCAsmInfo.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/MCObjectWriter.h" | |||
20 | #include "llvm/MC/MCSection.h" | |||
21 | #include "llvm/MC/MCSymbol.h" | |||
22 | #include "llvm/Support/ErrorHandling.h" | |||
23 | #include "llvm/Support/TargetRegistry.h" | |||
24 | using namespace llvm; | |||
25 | ||||
26 | MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, | |||
27 | raw_pwrite_stream &OS, | |||
28 | MCCodeEmitter *Emitter_) | |||
29 | : MCStreamer(Context), | |||
30 | Assembler(new MCAssembler(Context, TAB, *Emitter_, | |||
31 | *TAB.createObjectWriter(OS))), | |||
32 | EmitEHFrame(true), EmitDebugFrame(false) {} | |||
33 | ||||
34 | MCObjectStreamer::~MCObjectStreamer() { | |||
35 | delete &Assembler->getBackend(); | |||
36 | delete &Assembler->getEmitter(); | |||
37 | delete &Assembler->getWriter(); | |||
38 | delete Assembler; | |||
39 | } | |||
40 | ||||
41 | void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { | |||
42 | if (PendingLabels.empty()) | |||
43 | return; | |||
44 | if (!F) { | |||
45 | F = new MCDataFragment(); | |||
46 | MCSection *CurSection = getCurrentSectionOnly(); | |||
47 | CurSection->getFragmentList().insert(CurInsertionPoint, F); | |||
48 | F->setParent(CurSection); | |||
49 | } | |||
50 | for (MCSymbol *Sym : PendingLabels) { | |||
51 | Sym->setFragment(F); | |||
52 | Sym->setOffset(FOffset); | |||
53 | } | |||
54 | PendingLabels.clear(); | |||
55 | } | |||
56 | ||||
57 | void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, | |||
58 | const MCSymbol *Lo, | |||
59 | unsigned Size) { | |||
60 | // If not assigned to the same (valid) fragment, fallback. | |||
61 | if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || | |||
62 | Hi->isVariable() || Lo->isVariable()) { | |||
63 | MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); | |||
64 | return; | |||
65 | } | |||
66 | ||||
67 | assert(Hi->getOffset() >= Lo->getOffset() &&((Hi->getOffset() >= Lo->getOffset() && "Expected Hi to be greater than Lo" ) ? static_cast<void> (0) : __assert_fail ("Hi->getOffset() >= Lo->getOffset() && \"Expected Hi to be greater than Lo\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 68, __PRETTY_FUNCTION__)) | |||
68 | "Expected Hi to be greater than Lo")((Hi->getOffset() >= Lo->getOffset() && "Expected Hi to be greater than Lo" ) ? static_cast<void> (0) : __assert_fail ("Hi->getOffset() >= Lo->getOffset() && \"Expected Hi to be greater than Lo\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 68, __PRETTY_FUNCTION__)); | |||
69 | EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size); | |||
70 | } | |||
71 | ||||
72 | void MCObjectStreamer::reset() { | |||
73 | if (Assembler) | |||
74 | Assembler->reset(); | |||
75 | CurInsertionPoint = MCSection::iterator(); | |||
76 | EmitEHFrame = true; | |||
77 | EmitDebugFrame = false; | |||
78 | PendingLabels.clear(); | |||
79 | MCStreamer::reset(); | |||
80 | } | |||
81 | ||||
82 | void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) { | |||
83 | if (!getNumFrameInfos()) | |||
84 | return; | |||
85 | ||||
86 | if (EmitEHFrame) | |||
87 | MCDwarfFrameEmitter::Emit(*this, MAB, true); | |||
88 | ||||
89 | if (EmitDebugFrame) | |||
90 | MCDwarfFrameEmitter::Emit(*this, MAB, false); | |||
91 | } | |||
92 | ||||
93 | MCFragment *MCObjectStreamer::getCurrentFragment() const { | |||
94 | assert(getCurrentSectionOnly() && "No current section!")((getCurrentSectionOnly() && "No current section!") ? static_cast<void> (0) : __assert_fail ("getCurrentSectionOnly() && \"No current section!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 94, __PRETTY_FUNCTION__)); | |||
95 | ||||
96 | if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin()) | |||
97 | return &*std::prev(CurInsertionPoint); | |||
98 | ||||
99 | return nullptr; | |||
100 | } | |||
101 | ||||
102 | MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() { | |||
103 | MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); | |||
104 | // When bundling is enabled, we don't want to add data to a fragment that | |||
105 | // already has instructions (see MCELFStreamer::EmitInstToData for details) | |||
106 | if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() && | |||
107 | F->hasInstructions())) { | |||
108 | F = new MCDataFragment(); | |||
109 | insert(F); | |||
110 | } | |||
111 | return F; | |||
112 | } | |||
113 | ||||
114 | void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) { | |||
115 | Assembler->registerSymbol(Sym); | |||
116 | } | |||
117 | ||||
118 | void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) { | |||
119 | MCStreamer::EmitCFISections(EH, Debug); | |||
120 | EmitEHFrame = EH; | |||
121 | EmitDebugFrame = Debug; | |||
122 | } | |||
123 | ||||
124 | void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, | |||
125 | SMLoc Loc) { | |||
126 | MCStreamer::EmitValueImpl(Value, Size, Loc); | |||
127 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
128 | flushPendingLabels(DF, DF->getContents().size()); | |||
129 | ||||
130 | MCLineEntry::Make(this, getCurrentSection().first); | |||
131 | ||||
132 | // Avoid fixups when possible. | |||
133 | int64_t AbsValue; | |||
134 | if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) { | |||
135 | EmitIntValue(AbsValue, Size); | |||
136 | return; | |||
137 | } | |||
138 | DF->getFixups().push_back( | |||
139 | MCFixup::create(DF->getContents().size(), Value, | |||
140 | MCFixup::getKindForSize(Size, false), Loc)); | |||
141 | DF->getContents().resize(DF->getContents().size() + Size, 0); | |||
142 | } | |||
143 | ||||
144 | void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { | |||
145 | // We need to create a local symbol to avoid relocations. | |||
146 | Frame.Begin = getContext().createTempSymbol(); | |||
147 | EmitLabel(Frame.Begin); | |||
148 | } | |||
149 | ||||
150 | void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { | |||
151 | Frame.End = getContext().createTempSymbol(); | |||
152 | EmitLabel(Frame.End); | |||
153 | } | |||
154 | ||||
155 | void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { | |||
156 | MCStreamer::EmitLabel(Symbol); | |||
157 | ||||
158 | getAssembler().registerSymbol(*Symbol); | |||
159 | ||||
160 | // If there is a current fragment, mark the symbol as pointing into it. | |||
161 | // Otherwise queue the label and set its fragment pointer when we emit the | |||
162 | // next fragment. | |||
163 | auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); | |||
164 | if (F && !(getAssembler().isBundlingEnabled() && | |||
165 | getAssembler().getRelaxAll())) { | |||
166 | Symbol->setFragment(F); | |||
167 | Symbol->setOffset(F->getContents().size()); | |||
168 | } else { | |||
169 | PendingLabels.push_back(Symbol); | |||
170 | } | |||
171 | } | |||
172 | ||||
173 | void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { | |||
174 | int64_t IntValue; | |||
175 | if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { | |||
176 | EmitULEB128IntValue(IntValue); | |||
177 | return; | |||
178 | } | |||
179 | insert(new MCLEBFragment(*Value, false)); | |||
180 | } | |||
181 | ||||
182 | void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) { | |||
183 | int64_t IntValue; | |||
184 | if (Value->evaluateAsAbsolute(IntValue, getAssembler())) { | |||
185 | EmitSLEB128IntValue(IntValue); | |||
186 | return; | |||
187 | } | |||
188 | insert(new MCLEBFragment(*Value, true)); | |||
189 | } | |||
190 | ||||
191 | void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, | |||
192 | const MCSymbol *Symbol) { | |||
193 | report_fatal_error("This file format doesn't support weak aliases."); | |||
194 | } | |||
195 | ||||
196 | void MCObjectStreamer::ChangeSection(MCSection *Section, | |||
197 | const MCExpr *Subsection) { | |||
198 | changeSectionImpl(Section, Subsection); | |||
199 | } | |||
200 | ||||
201 | bool MCObjectStreamer::changeSectionImpl(MCSection *Section, | |||
202 | const MCExpr *Subsection) { | |||
203 | assert(Section && "Cannot switch to a null section!")((Section && "Cannot switch to a null section!") ? static_cast <void> (0) : __assert_fail ("Section && \"Cannot switch to a null section!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 203, __PRETTY_FUNCTION__)); | |||
204 | flushPendingLabels(nullptr); | |||
205 | ||||
206 | bool Created = getAssembler().registerSection(*Section); | |||
207 | ||||
208 | int64_t IntSubsection = 0; | |||
209 | if (Subsection && | |||
210 | !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler())) | |||
211 | report_fatal_error("Cannot evaluate subsection number"); | |||
212 | if (IntSubsection < 0 || IntSubsection > 8192) | |||
213 | report_fatal_error("Subsection number out of range"); | |||
214 | CurInsertionPoint = | |||
215 | Section->getSubsectionInsertionPoint(unsigned(IntSubsection)); | |||
216 | return Created; | |||
217 | } | |||
218 | ||||
219 | void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { | |||
220 | getAssembler().registerSymbol(*Symbol); | |||
221 | MCStreamer::EmitAssignment(Symbol, Value); | |||
222 | } | |||
223 | ||||
224 | bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { | |||
225 | return Sec.hasInstructions(); | |||
226 | } | |||
227 | ||||
228 | void MCObjectStreamer::EmitInstruction(const MCInst &Inst, | |||
229 | const MCSubtargetInfo &STI) { | |||
230 | MCStreamer::EmitInstruction(Inst, STI); | |||
231 | ||||
232 | MCSection *Sec = getCurrentSectionOnly(); | |||
233 | Sec->setHasInstructions(true); | |||
234 | ||||
235 | // Now that a machine instruction has been assembled into this section, make | |||
236 | // a line entry for any .loc directive that has been seen. | |||
237 | MCLineEntry::Make(this, getCurrentSection().first); | |||
238 | ||||
239 | // If this instruction doesn't need relaxation, just emit it as data. | |||
240 | MCAssembler &Assembler = getAssembler(); | |||
241 | if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { | |||
242 | EmitInstToData(Inst, STI); | |||
243 | return; | |||
244 | } | |||
245 | ||||
246 | // Otherwise, relax and emit it as data if either: | |||
247 | // - The RelaxAll flag was passed | |||
248 | // - Bundling is enabled and this instruction is inside a bundle-locked | |||
249 | // group. We want to emit all such instructions into the same data | |||
250 | // fragment. | |||
251 | if (Assembler.getRelaxAll() || | |||
252 | (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { | |||
253 | MCInst Relaxed; | |||
254 | getAssembler().getBackend().relaxInstruction(Inst, Relaxed); | |||
255 | while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) | |||
256 | getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); | |||
257 | EmitInstToData(Relaxed, STI); | |||
258 | return; | |||
259 | } | |||
260 | ||||
261 | // Otherwise emit to a separate fragment. | |||
262 | EmitInstToFragment(Inst, STI); | |||
263 | } | |||
264 | ||||
265 | void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, | |||
266 | const MCSubtargetInfo &STI) { | |||
267 | if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled()) | |||
268 | llvm_unreachable("All instructions should have already been relaxed")::llvm::llvm_unreachable_internal("All instructions should have already been relaxed" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 268); | |||
269 | ||||
270 | // Always create a new, separate fragment here, because its size can change | |||
271 | // during relaxation. | |||
272 | MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI); | |||
273 | insert(IF); | |||
274 | ||||
275 | SmallString<128> Code; | |||
276 | raw_svector_ostream VecOS(Code); | |||
277 | getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(), | |||
278 | STI); | |||
279 | IF->getContents().append(Code.begin(), Code.end()); | |||
280 | } | |||
281 | ||||
282 | #ifndef NDEBUG | |||
283 | static const char *const BundlingNotImplementedMsg = | |||
284 | "Aligned bundling is not implemented for this object format"; | |||
285 | #endif | |||
286 | ||||
287 | void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) { | |||
288 | llvm_unreachable(BundlingNotImplementedMsg)::llvm::llvm_unreachable_internal(BundlingNotImplementedMsg, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 288); | |||
289 | } | |||
290 | ||||
291 | void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) { | |||
292 | llvm_unreachable(BundlingNotImplementedMsg)::llvm::llvm_unreachable_internal(BundlingNotImplementedMsg, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 292); | |||
293 | } | |||
294 | ||||
295 | void MCObjectStreamer::EmitBundleUnlock() { | |||
296 | llvm_unreachable(BundlingNotImplementedMsg)::llvm::llvm_unreachable_internal(BundlingNotImplementedMsg, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 296); | |||
297 | } | |||
298 | ||||
299 | void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, | |||
300 | unsigned Column, unsigned Flags, | |||
301 | unsigned Isa, | |||
302 | unsigned Discriminator, | |||
303 | StringRef FileName) { | |||
304 | // In case we see two .loc directives in a row, make sure the | |||
305 | // first one gets a line entry. | |||
306 | MCLineEntry::Make(this, getCurrentSection().first); | |||
307 | ||||
308 | this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, | |||
309 | Isa, Discriminator, FileName); | |||
310 | } | |||
311 | ||||
312 | static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A, | |||
313 | const MCSymbol *B) { | |||
314 | MCContext &Context = OS.getContext(); | |||
315 | MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; | |||
316 | const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context); | |||
317 | const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context); | |||
318 | const MCExpr *AddrDelta = | |||
319 | MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context); | |||
320 | return AddrDelta; | |||
321 | } | |||
322 | ||||
323 | static void emitDwarfSetLineAddr(MCObjectStreamer &OS, | |||
324 | MCDwarfLineTableParams Params, | |||
325 | int64_t LineDelta, const MCSymbol *Label, | |||
326 | int PointerSize) { | |||
327 | // emit the sequence to set the address | |||
328 | OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1); | |||
329 | OS.EmitULEB128IntValue(PointerSize + 1); | |||
330 | OS.EmitIntValue(dwarf::DW_LNE_set_address, 1); | |||
331 | OS.EmitSymbolValue(Label, PointerSize); | |||
332 | ||||
333 | // emit the sequence for the LineDelta (from 1) and a zero address delta. | |||
334 | MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); | |||
335 | } | |||
336 | ||||
337 | void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, | |||
338 | const MCSymbol *LastLabel, | |||
339 | const MCSymbol *Label, | |||
340 | unsigned PointerSize) { | |||
341 | if (!LastLabel) { | |||
342 | emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta, | |||
343 | Label, PointerSize); | |||
344 | return; | |||
345 | } | |||
346 | const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); | |||
347 | int64_t Res; | |||
348 | if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { | |||
349 | MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta, | |||
350 | Res); | |||
351 | return; | |||
352 | } | |||
353 | insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta)); | |||
354 | } | |||
355 | ||||
356 | void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, | |||
357 | const MCSymbol *Label) { | |||
358 | const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel); | |||
359 | int64_t Res; | |||
360 | if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) { | |||
361 | MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res); | |||
362 | return; | |||
363 | } | |||
364 | insert(new MCDwarfCallFrameFragment(*AddrDelta)); | |||
365 | } | |||
366 | ||||
367 | void MCObjectStreamer::EmitBytes(StringRef Data) { | |||
368 | MCLineEntry::Make(this, getCurrentSection().first); | |||
369 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
370 | flushPendingLabels(DF, DF->getContents().size()); | |||
371 | DF->getContents().append(Data.begin(), Data.end()); | |||
372 | } | |||
373 | ||||
374 | void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, | |||
375 | int64_t Value, | |||
376 | unsigned ValueSize, | |||
377 | unsigned MaxBytesToEmit) { | |||
378 | if (MaxBytesToEmit == 0) | |||
379 | MaxBytesToEmit = ByteAlignment; | |||
380 | insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); | |||
381 | ||||
382 | // Update the maximum alignment on the current section if necessary. | |||
383 | MCSection *CurSec = getCurrentSection().first; | |||
384 | if (ByteAlignment > CurSec->getAlignment()) | |||
| ||||
385 | CurSec->setAlignment(ByteAlignment); | |||
386 | } | |||
387 | ||||
388 | void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, | |||
389 | unsigned MaxBytesToEmit) { | |||
390 | EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); | |||
| ||||
391 | cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); | |||
392 | } | |||
393 | ||||
394 | bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, | |||
395 | unsigned char Value) { | |||
396 | int64_t Res; | |||
397 | if (Offset->evaluateAsAbsolute(Res, getAssembler())) { | |||
398 | insert(new MCOrgFragment(*Offset, Value)); | |||
399 | return false; | |||
400 | } | |||
401 | ||||
402 | MCSymbol *CurrentPos = getContext().createTempSymbol(); | |||
403 | EmitLabel(CurrentPos); | |||
404 | MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; | |||
405 | const MCExpr *Ref = | |||
406 | MCSymbolRefExpr::create(CurrentPos, Variant, getContext()); | |||
407 | const MCExpr *Delta = | |||
408 | MCBinaryExpr::create(MCBinaryExpr::Sub, Offset, Ref, getContext()); | |||
409 | ||||
410 | if (!Delta->evaluateAsAbsolute(Res, getAssembler())) | |||
411 | return true; | |||
412 | EmitFill(Res, Value); | |||
413 | return false; | |||
414 | } | |||
415 | ||||
416 | // Associate GPRel32 fixup with data and resize data area | |||
417 | void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { | |||
418 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
419 | flushPendingLabels(DF, DF->getContents().size()); | |||
420 | ||||
421 | DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), | |||
422 | Value, FK_GPRel_4)); | |||
423 | DF->getContents().resize(DF->getContents().size() + 4, 0); | |||
424 | } | |||
425 | ||||
426 | // Associate GPRel32 fixup with data and resize data area | |||
427 | void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { | |||
428 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
429 | flushPendingLabels(DF, DF->getContents().size()); | |||
430 | ||||
431 | DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), | |||
432 | Value, FK_GPRel_4)); | |||
433 | DF->getContents().resize(DF->getContents().size() + 8, 0); | |||
434 | } | |||
435 | ||||
436 | void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { | |||
437 | // FIXME: A MCFillFragment would be more memory efficient but MCExpr has | |||
438 | // problems evaluating expressions across multiple fragments. | |||
439 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
440 | flushPendingLabels(DF, DF->getContents().size()); | |||
441 | DF->getContents().append(NumBytes, FillValue); | |||
442 | } | |||
443 | ||||
444 | void MCObjectStreamer::EmitZeros(uint64_t NumBytes) { | |||
445 | const MCSection *Sec = getCurrentSection().first; | |||
446 | assert(Sec && "need a section")((Sec && "need a section") ? static_cast<void> ( 0) : __assert_fail ("Sec && \"need a section\"", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn250153/lib/MC/MCObjectStreamer.cpp" , 446, __PRETTY_FUNCTION__)); | |||
447 | unsigned ItemSize = Sec->isVirtualSection() ? 0 : 1; | |||
448 | insert(new MCFillFragment(0, ItemSize, NumBytes)); | |||
449 | } | |||
450 | ||||
451 | void MCObjectStreamer::FinishImpl() { | |||
452 | // If we are generating dwarf for assembly source files dump out the sections. | |||
453 | if (getContext().getGenDwarfForAssembly()) | |||
454 | MCGenDwarfInfo::Emit(this); | |||
455 | ||||
456 | // Dump out the dwarf file & directory tables and line tables. | |||
457 | MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams()); | |||
458 | ||||
459 | flushPendingLabels(nullptr); | |||
460 | getAssembler().Finish(); | |||
461 | } |