MCObjectStreamer.cpp revision b02f1e9a6bc332ebd77571fdffcdc44d77e76b31
18dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
28dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
38dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//                     The LLVM Compiler Infrastructure
48dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
58dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// This file is distributed under the University of Illinois Open Source
68dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar// License. See LICENSE.TXT for details.
78dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//
88dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar//===----------------------------------------------------------------------===//
98dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
108dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCObjectStreamer.h"
11df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne#include "llvm/ADT/STLExtras.h"
12f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmBackend.h"
13f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCAsmInfo.h"
148dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar#include "llvm/MC/MCAssembler.h"
151abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer#include "llvm/MC/MCCodeEmitter.h"
1689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/MC/MCContext.h"
17f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola#include "llvm/MC/MCDwarf.h"
188067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer#include "llvm/MC/MCExpr.h"
19f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h"
20ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola#include "llvm/MC/MCSymbol.h"
21b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov#include "llvm/MC/MCSection.h"
22f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/Support/ErrorHandling.h"
238dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbarusing namespace llvm;
248dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
255da3665cc501ed8928e63678254357214ec0b9ebChandler CarruthMCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
265da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth                                   MCAsmBackend &TAB, raw_ostream &OS,
275da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth                                   MCCodeEmitter *Emitter_)
285da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth    : MCStreamer(Kind, Context),
295da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth      Assembler(new MCAssembler(Context, TAB, *Emitter_,
305da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth                                *TAB.createObjectWriter(OS), OS)),
315da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth      CurSectionData(0) {}
328dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar
335da3665cc501ed8928e63678254357214ec0b9ebChandler CarruthMCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
345da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth                                   MCAsmBackend &TAB, raw_ostream &OS,
355da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth                                   MCCodeEmitter *Emitter_,
3601dff9646173fea0c38df4471f41272557ca831aJan Sjödin                                   MCAssembler *_Assembler)
375da3665cc501ed8928e63678254357214ec0b9ebChandler Carruth    : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
3801dff9646173fea0c38df4471f41272557ca831aJan Sjödin
398dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel DunbarMCObjectStreamer::~MCObjectStreamer() {
401abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  delete &Assembler->getBackend();
411abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  delete &Assembler->getEmitter();
42feb7ba3d9abfa1eb89f6da93c51649baaa931ab8Daniel Dunbar  delete &Assembler->getWriter();
438dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar  delete Assembler;
448dc68ab931e0f0a7c5caf9cd341b2ec855733863Daniel Dunbar}
4583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
465399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigasvoid MCObjectStreamer::reset() {
4799cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas  if (Assembler)
4899cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas    Assembler->reset();
49b9d1005e96681b5c8cc1ed959fa129de62933020Pedro Artigas  CurSectionData = 0;
50df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  CurInsertionPoint = MCSectionData::iterator();
515399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas  MCStreamer::reset();
525399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas}
535399d2502acaf96fe8420e61913e77f0b23650ffPedro Artigas
548067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCFragment *MCObjectStreamer::getCurrentFragment() const {
558067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  assert(getCurrentSectionData() && "No current section!");
568067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
57df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin())
58df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    return prior(CurInsertionPoint);
598067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
608067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return 0;
618067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
628067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
638067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. SpencerMCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
648067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
6567144e37ba5cd35ee917daac631e03963b05a674Derek Schuff  // When bundling is enabled, we don't want to add data to a fragment that
6667144e37ba5cd35ee917daac631e03963b05a674Derek Schuff  // already has instructions (see MCELFStreamer::EmitInstToData for details)
67df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) {
68df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    F = new MCDataFragment();
69df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    insert(F);
70df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  }
718067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return F;
728067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
738067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
748067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencerconst MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
758067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  switch (Value->getKind()) {
767597212abced110723f2fee985a7d60557c092ecEvan Cheng  case MCExpr::Target:
777597212abced110723f2fee985a7d60557c092ecEvan Cheng    cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
787597212abced110723f2fee985a7d60557c092ecEvan Cheng    break;
797597212abced110723f2fee985a7d60557c092ecEvan Cheng
808067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Constant:
818067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
828067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
838067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Binary: {
848067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
858067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(BE->getLHS());
868067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(BE->getRHS());
878067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
888067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  }
898067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
908067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::SymbolRef:
918067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
928067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
938067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
948067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  case MCExpr::Unary:
958067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
968067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer    break;
978067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  }
988067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
998067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer  return Value;
1008067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer}
1018067adc271d7ccfcd28a238d73942b21a5e2bc62Michael J. Spencer
10289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolavoid MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
103debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola                                     unsigned AddrSpace) {
1046f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  assert(AddrSpace == 0 && "Address space must be 0!");
1056f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  MCDataFragment *DF = getOrCreateDataFragment();
1066f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola
10741b646c127300c6e3b83f1a0bfc49c812110ebf4Cameron Zwarich  MCLineEntry::Make(this, getCurrentSection().first);
10841b646c127300c6e3b83f1a0bfc49c812110ebf4Cameron Zwarich
1096f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  // Avoid fixups when possible.
1106f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  int64_t AbsValue;
111d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
1122df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola    EmitIntValue(AbsValue, Size, AddrSpace);
1132df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola    return;
1146f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola  }
11564d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky  DF->getFixups().push_back(
11664d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky      MCFixup::Create(DF->getContents().size(), Value,
11764d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky                      MCFixup::getKindForSize(Size, false)));
1182df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola  DF->getContents().resize(DF->getContents().size() + Size, 0);
1196f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola}
1206f95023a7f27075011a6eb7b84e03732b00a785bRafael Espindola
121547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindolavoid MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
122547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola  RecordProcStart(Frame);
123547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola}
124547be2699c547b79a7735858a64921d8ccf180f7Rafael Espindola
1251fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindolavoid MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1261fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola  RecordProcEnd(Frame);
1271fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola}
1281fe9737eb49ecb80fbb547f0e16e10a726cd53cfRafael Espindola
129ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindolavoid MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
130ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola  MCStreamer::EmitLabel(Symbol);
131ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
132ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
133ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
134ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // FIXME: This is wasteful, we don't necessarily need to create a data
135ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment. Instead, we should mark the symbol as pointing into the data
136ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment if it exists, otherwise we should just queue the label and set its
137ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  // fragment pointer when we emit the next fragment.
138ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  MCDataFragment *F = getOrCreateDataFragment();
139ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
140ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  SD.setFragment(F);
141ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola  SD.setOffset(F->getContents().size());
142ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola}
143ea4afa91eb453323948588ad1e1706d842fb9007Rafael Espindola
1442c3a4641a7785da78839caf574277df9cd93b52cReed Kotlervoid MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
1452c3a4641a7785da78839caf574277df9cd93b52cReed Kotler  EmitLabel(Symbol);
1462c3a4641a7785da78839caf574277df9cd93b52cReed Kotler}
1472c3a4641a7785da78839caf574277df9cd93b52cReed Kotler
148e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
149660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  int64_t IntValue;
150d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
151e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    EmitULEB128IntValue(IntValue);
152660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola    return;
153660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  }
154a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola  Value = ForceExpAbs(Value);
155df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(new MCLEBFragment(*Value, false));
1563ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola}
1573ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
158e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindolavoid MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
159660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  int64_t IntValue;
160d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
161e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    EmitSLEB128IntValue(IntValue);
162660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola    return;
163660b5fc4d019bf22fbe14dfb81c5b59444fa3506Rafael Espindola  }
164a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola  Value = ForceExpAbs(Value);
165df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(new MCLEBFragment(*Value, true));
1663ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola}
1673ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
168484291c27319668ad99cb87def000254357736fbRafael Espindolavoid MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
169484291c27319668ad99cb87def000254357736fbRafael Espindola                                         const MCSymbol *Symbol) {
170484291c27319668ad99cb87def000254357736fbRafael Espindola  report_fatal_error("This file format doesn't support weak aliases.");
171484291c27319668ad99cb87def000254357736fbRafael Espindola}
172484291c27319668ad99cb87def000254357736fbRafael Espindola
173df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbournevoid MCObjectStreamer::ChangeSection(const MCSection *Section,
174df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne                                     const MCExpr *Subsection) {
17583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  assert(Section && "Cannot switch to a null section!");
17683b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
17783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
178df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne
179df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  int64_t IntSubsection = 0;
180df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  if (Subsection &&
181df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne      !Subsection->EvaluateAsAbsolute(IntSubsection, getAssembler()))
182df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    report_fatal_error("Cannot evaluate subsection number");
183df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  if (IntSubsection < 0 || IntSubsection > 8192)
184df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    report_fatal_error("Subsection number out of range");
185df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  CurInsertionPoint =
186df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection));
18783b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar}
18883b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar
189ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Benderskyvoid MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
190ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky  getAssembler().getOrCreateSymbolData(*Symbol);
191ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky  Symbol->setVariableValue(AddValueSymbols(Value));
192ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky}
193ef76b273f96d99a4a260f3dcadde8fbb96256cf3Eli Bendersky
194f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindolavoid MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
195f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Scan for values.
196f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  for (unsigned i = Inst.getNumOperands(); i--; )
197f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    if (Inst.getOperand(i).isExpr())
198f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola      AddValueSymbols(Inst.getOperand(i).getExpr());
199f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
2004766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  MCSectionData *SD = getCurrentSectionData();
2014766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  SD->setHasInstructions(true);
202f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
203f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Now that a machine instruction has been assembled into this section, make
204f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // a line entry for any .loc directive that has been seen.
205df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  MCLineEntry::Make(this, getCurrentSection().first);
206f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
207f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // If this instruction doesn't need relaxation, just emit it as data.
2084766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  MCAssembler &Assembler = getAssembler();
2094766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
210f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    EmitInstToData(Inst);
211f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    return;
212f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  }
213f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
2144766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  // Otherwise, relax and emit it as data if either:
2154766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  // - The RelaxAll flag was passed
2164766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  // - Bundling is enabled and this instruction is inside a bundle-locked
2174766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  //   group. We want to emit all such instructions into the same data
2184766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  //   fragment.
2194766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  if (Assembler.getRelaxAll() ||
2204766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky      (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
221f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    MCInst Relaxed;
222ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach    getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
223ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach    while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
224ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach      getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
225f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    EmitInstToData(Relaxed);
226f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola    return;
227f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  }
228f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
229f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  // Otherwise emit to a separate fragment.
230f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola  EmitInstToFragment(Inst);
231f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola}
232f89671d994ba27e2816a7e49eb8bbc1b43d2a147Rafael Espindola
233dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindolavoid MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
2344766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  // Always create a new, separate fragment here, because its size can change
2354766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  // during relaxation.
236df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  MCRelaxableFragment *IF = new MCRelaxableFragment(Inst);
237df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(IF);
238dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola
23950ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  SmallString<128> Code;
24050ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  raw_svector_ostream VecOS(Code);
241dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola  getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
24250ebe53353f6870e913f7715d6d4fc5a1f5bedd6Eli Friedman  VecOS.flush();
24364d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky  IF->getContents().append(Code.begin(), Code.end());
244dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola}
245dedb045c3296c831962c4ae101531c38c273ba89Rafael Espindola
246f78708593407286de34506e699da25a56b65a20dMatt Beaumont-Gay#ifndef NDEBUG
24774b3c8da4800c7e8ba8f019879db29738ecc5f74Benjamin Kramerstatic const char *BundlingNotImplementedMsg =
2484766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  "Aligned bundling is not implemented for this object format";
249f78708593407286de34506e699da25a56b65a20dMatt Beaumont-Gay#endif
2504766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky
2514766ef41b31e4f97bce1179c3b0398303bf65356Eli Benderskyvoid MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
2524766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  llvm_unreachable(BundlingNotImplementedMsg);
2534766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky}
2544766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky
2556c1d4972cf1cd6b6072e31c05f97abb1ed7a8497Eli Benderskyvoid MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
2564766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  llvm_unreachable(BundlingNotImplementedMsg);
2574766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky}
2584766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky
2594766ef41b31e4f97bce1179c3b0398303bf65356Eli Benderskyvoid MCObjectStreamer::EmitBundleUnlock() {
2604766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky  llvm_unreachable(BundlingNotImplementedMsg);
2614766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky}
2624766ef41b31e4f97bce1179c3b0398303bf65356Eli Bendersky
2634df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigandvoid MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
2644df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand                                             unsigned Column, unsigned Flags,
2654df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand                                             unsigned Isa,
2664df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand                                             unsigned Discriminator,
2674df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand                                             StringRef FileName) {
2684df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand  // In case we see two .loc directives in a row, make sure the
2694df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand  // first one gets a line entry.
2704df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand  MCLineEntry::Make(this, getCurrentSection().first);
2714df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand
2724df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand  this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
2734df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand                                          Isa, Discriminator, FileName);
2744df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand}
2754df4bccc71ea0477836db9a417d3da202c2baa09Ulrich Weigand
27632a006e606742b1c5401e49607e33717bb5441f0Rafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
27732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                                                const MCSymbol *LastLabel,
278672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng                                                const MCSymbol *Label,
279672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng                                                unsigned PointerSize) {
28032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  if (!LastLabel) {
28132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
28232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    return;
28332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  }
284245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
28532a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  int64_t Res;
286d076482ab7e672d1d65a43809695e8d0d3995203Rafael Espindola  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
28732a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    MCDwarfLineAddr::Emit(this, LineDelta, Res);
28832a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    return;
28932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola  }
290a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola  AddrDelta = ForceExpAbs(AddrDelta);
291df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
29232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola}
29332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola
294245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindolavoid MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
295245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola                                                 const MCSymbol *Label) {
296245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
297245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  int64_t Res;
298245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
299245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
300245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    return;
301245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola  }
302a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola  AddrDelta = ForceExpAbs(AddrDelta);
303df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(new MCDwarfCallFrameFragment(*AddrDelta));
304245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola}
305245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola
306e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
307e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  assert(AddrSpace == 0 && "Address space must be 0!");
308e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
309e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer}
310e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer
311e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
312e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer                                            int64_t Value,
313e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer                                            unsigned ValueSize,
314e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer                                            unsigned MaxBytesToEmit) {
315e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  if (MaxBytesToEmit == 0)
316e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer    MaxBytesToEmit = ByteAlignment;
317df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne  insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
318e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer
319e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  // Update the maximum alignment on the current section if necessary.
320e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  if (ByteAlignment > getCurrentSectionData()->getAlignment())
321e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer    getCurrentSectionData()->setAlignment(ByteAlignment);
322e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer}
323e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer
324e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramervoid MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
325e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer                                         unsigned MaxBytesToEmit) {
326e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
327e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer  cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
328e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer}
329e660fc15fe1f1b8a19488f39d0ec09acc79bed0dBenjamin Kramer
330ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbachbool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
331660a4d9e0a15ad25db10d25a1a8caeafc0ebad5eJim Grosbach                                         unsigned char Value) {
332f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  int64_t Res;
333f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
334df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    insert(new MCOrgFragment(*Offset, Value));
335ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach    return false;
336f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  }
337f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola
338f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  MCSymbol *CurrentPos = getContext().CreateTempSymbol();
339f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  EmitLabel(CurrentPos);
340f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
341f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  const MCExpr *Ref =
342f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
343f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  const MCExpr *Delta =
344f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola    MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
345f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola
346f7ad048f1e122ee4f735398786f4859392f74144Rafael Espindola  if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
347ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach    return true;
348ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher  EmitFill(Res, Value);
349ebd4c05c3cbd61215366d4d16f1c1a2e57e7156dJim Grosbach  return false;
350e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola}
351e23930543c0de0adcfec00cd18e9243ad812a167Rafael Espindola
35284bfc2f090639f933df06cc675c4385511516befAkira Hatanaka// Associate GPRel32 fixup with data and resize data area
35384bfc2f090639f933df06cc675c4385511516befAkira Hatanakavoid MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
35484bfc2f090639f933df06cc675c4385511516befAkira Hatanaka  MCDataFragment *DF = getOrCreateDataFragment();
35584bfc2f090639f933df06cc675c4385511516befAkira Hatanaka
35664d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
35764d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky                                            Value, FK_GPRel_4));
35884bfc2f090639f933df06cc675c4385511516befAkira Hatanaka  DF->getContents().resize(DF->getContents().size() + 4, 0);
35984bfc2f090639f933df06cc675c4385511516befAkira Hatanaka}
36084bfc2f090639f933df06cc675c4385511516befAkira Hatanaka
361101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter// Associate GPRel32 fixup with data and resize data area
362101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Cartervoid MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
363101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter  MCDataFragment *DF = getOrCreateDataFragment();
364101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter
36564d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
36664d9a3233476553fc950f0f2fc6a2cdd2a4c05cfEli Bendersky                                            Value, FK_GPRel_4));
367101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter  DF->getContents().resize(DF->getContents().size() + 8, 0);
368101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter}
369101771ba4d9c2421f836069fcedf9ddc8a0c9dc7Jack Carter
370f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramervoid MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
371f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer                                unsigned AddrSpace) {
372f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer  assert(AddrSpace == 0 && "Address space must be 0!");
373f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer  // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
374f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer  //        problems evaluating expressions across multiple fragments.
375f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer  getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
376f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer}
377f0070f2a973ff046ee63de827ab32ff215b369b2Benjamin Kramer
378b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlovvoid MCObjectStreamer::EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
379b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov  assert(AddrSpace == 0 && "Address space must be 0!");
380b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov  unsigned ItemSize = getCurrentSection().first->isVirtualSection() ? 0 : 1;
381b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov  insert(new MCFillFragment(0, ItemSize, NumBytes));
382b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov}
383b02f1e9a6bc332ebd77571fdffcdc44d77e76b31Serge Pavlov
38499b4237c1647156f0e1d3d7e03efdab23ed79778Rafael Espindolavoid MCObjectStreamer::FinishImpl() {
38589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  // Dump out the dwarf file & directory tables and line tables.
386e6ec02e8afe1bec8f9de5c907a50a6efdee261a0Rafael Espindola  const MCSymbol *LineSectionSymbol = NULL;
38789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  if (getContext().hasDwarfFiles())
388489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola    LineSectionSymbol = MCDwarfFileTable::Emit(this);
38989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
39094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  // If we are generating dwarf for assembly source files dump out the sections.
39194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  if (getContext().getGenDwarfForAssembly())
392489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola    MCGenDwarfInfo::Emit(this, LineSectionSymbol);
39394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
39483b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar  getAssembler().Finish();
39583b467178a8295048f3ee7b44ff9c7ea244a96ccDaniel Dunbar}
396