<html><body><span style="font-family:Verdana; color:#000; font-size:10pt;"><div>llvm-dev,</div><div><br></div><div>There were a couple of issues, but I think I have them fixed.  The lack of all output was related to needing the following at the end of my function:</div><div><br></div><div>  Out->keep();<br>  Str->Finish();</div><div><br></div><div>I was missing the finish call.  Also, while I did make sure to add a .text section, I wasn't adding symbol attributes to make functions global, so when I got around to linking, the linker couldn't find things.  This was solved with a simple call to:</div><div><br></div><div>Str->EmitSymbolAttribute(mcsn,attr);</div><div><br></div><div>Once with attr as llvm::MCSymbolAttr::MCSA_Global and once as llvm::MCSymbolAttr::MCSA_ELF_TypeFunction.  Everything seems to work now.  Thanks if you took a look, but this issue no longer needs attention.</div><div><br></div><div><br></div><div>Thanks much,</div><div>~Aaron Vose<br></div><div><br></div>
<blockquote id="replyBlockquote" webmail="1" style="border-left: 2px solid blue; margin-left: 8px; padding-left: 8px; font-size:10pt; color:black; font-family:verdana;">
<div id="wmQuoteWrapper">
-------- Original Message --------<br>
Subject: [llvm-dev] Using_an_MCStreamer_Directly_to_produce_an_o<br>
bject_file?<br>
From: via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><br>
Date: Fri, May 20, 2016 8:34 pm<br>
To: <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<br>
llvm-dev,<br>
<br>
<br>
Thanks so much in advance for any help, tips, or advice you may be able<br>
to offer me.  I'm going to try to avoid the big-picture description of<br>
the project I'm working on, and only talk about the parts that I have<br>
trouble with / currently need to implement.  --  I've been starting by<br>
taking the source code from the "llvm-mc" tool, and working that down<br>
into a smaller form that does the kinds of things I want to do at the MC<br>
"layer".<br>
<br>
<br>
So, I'd like to be able to use a MCStreamer object directly to make some<br>
output file, and object ".o" would be just fine to start with.<br>
<br>
I seem to be able to create an aarch64 target without too much issue:<br>
<br>
  llvm::InitializeAllTargetInfos();<br>
  llvm::InitializeAllTargetMCs();<br>
  llvm::InitializeAllAsmParsers();<br>
  llvm::InitializeAllDisassemblers();<br>
<br>
  std::string Error;<br>
  std::string TripleName("aarch64-unknown-linux-gnu");<br>
  Triple TheTriple(Triple::normalize(TripleName));<br>
  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName,<br>
Error);<br>
  if (!TheTarget) {<br>
    std::cerr << "llvm_insts_to_binary(): " ><< Error;<br>
    return 1;<br>
  }<br>
<br>
<br>
Then, I move on to creating some of the needed ASM / REG info and an<br>
MCContext, etc.:<br>
<br>
  std::unique_ptr><MCRegisterInfo><br>
MRI(TheTarget->createMCRegInfo(TripleName));<br>
  assert(MRI && "Unable to create target register info!");<br>
  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI,<br>
TripleName));<br>
  assert(MAI && "Unable to create target asm info!");<br>
  std::string MCPU("generic");<br>
  std::string FeaturesStr("");<br>
  MCObjectFileInfo MOFI;<br>
  MCContext Ctx(<a href="http://MAI.get">MAI.get</a>(), MRI.get(), &MOFI);<br>
  MOFI.InitMCObjectFileInfo(TheTriple, llvm::Reloc::Model::PIC_,<br>
llvm::CodeModel::Model::Default, Ctx);<br>
  std::unique_ptr<MCInstrInfo>     MCII(TheTarget->createMCInstrInfo());<br>
  std::unique_ptr<MCSubtargetInfo><br>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));<br>
<br>
<br>
OK, that seems, OK.  Now I want to setup an output buffer:<br>
<br>
  std::string ofile("/home/users/avose/hpcgp/hpcgp_rundir/tmp.o");<br>
  std::unique_ptr<tool_output_file> Out = GetOutputStream(ofile);<br>
  if (!Out) {<br>
    return 1;<br>
  }<br>
  std::unique_ptr<buffer_ostream> BOS;<br>
  raw_pwrite_stream *OS = &Out->os();<br>
  if (!Out->os().supportsSeeking()) {<br>
    BOS = make_unique<buffer_ostream>(Out->os());<br>
    OS = <a href="http://BOS.get">BOS.get</a>();<br>
  }<br>
<br>
<br>
This also seems to do OK.  Now I would think I can finally get around to<br>
making the code emitter and the MCStreamer:<br>
<br>
  MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);<br>
  MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName,<br>
MCPU);<br>
  MCStreamer   *Str = TheTarget->createMCObjectStreamer(TheTriple, Ctx,<br>
*MAB, *OS, CE, *STI, true, false);<br>
<br>
<br>
So, like, wow, I would think I should be good to go here!  I should be<br>
able to just use functions like:<br>
<br>
  Str->EmitInstruction();<br>
  Str->EmitLabel();<br>
<br>
<br>
These should then result in everything I've tried to emit coming out in<br>
my output object file "tmp.o", you know, as long as I'm careful to be<br>
sure to make a call to keep my output file from being deleted.  So, when<br>
I'm done making "emit" calls like the above, I be sure to do the keep<br>
call:<br>
<br>
Out->keep();<br>
<br>
<br>
I'm aware that the calls to EmitInstruction(); and EmitLabel(); need to<br>
have their arguments properly constructed first, and I do try to do that<br>
using the context I had set up before, so, something like:<br>
<br>
  const llvm::Twine tname("my_label_name");<br>
  llvm::MCSymbol* mcs = Ctx.getOrCreateSymbol(tname);<br>
  Str->EmitLabel(mcs);<br>
<br>
<br>
Or even something more complicated like setting up an MCInst and all<br>
it's operands:<br>
<br>
  llvm::MCInst *llinst = new MCInst();<br>
  llinst->setOpcode(input_opcode);<br>
  llinst->addOperand(llvm::MCOperand::createReg(input_reg0));<br>
  llinst->addOperand(llvm::MCOperand::createReg(input_reg1));<br>
  const llvm::Twine tname("label_name");<br>
  const llvm::MCSymbol* mcs = Ctx.getOrCreateSymbol(tname);<br>
  const llvm::MCSymbolRefExpr *msre = llvm::MCSymbolRefExpr::create(mcs,<br>
Ctx);<br>
  llinst->addOperand(llvm::MCOperand::createExpr(msre));<br>
<br>
<br>
However, while I don't get any compiler errors, and everything runs to<br>
completion without printing any errors, my output file "tmp.o" is always<br>
created, but just empty with zero bytes.  I must be doing something<br>
silly here..  Does anyone have any ideas about what I'm doing wrong, or<br>
perhaps have example code that directly uses the MCStreamer object to<br>
write out object binary files?  Some examples showing how to make this<br>
work would _really_ make my week.<br>
<br>
This has been hard to debug, as I don't get any errors, just an empty<br>
output .o file...<br>
<br>
I was thinking it may be because of section issues, so I did add some<br>
initial sections, hoping that might help:<br>
<br>
  Str->InitSections(false);<br>
  MCSection *textsect = Ctx.getELFSection(".text", ELF::SHT_PROGBITS,<br>
ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);<br>
  Str->SwitchSection(textsect);<br>
<br>
<br>
This did not seem to help at all.  I'm running out of ideas.  Anyone<br>
know how to use an MCStreamer object directly to make and object file?<br>
<br>
<br>
Thanks so much for your time,<br>
~Aaron Vose<br>
<br>
<br>
(Software Engineer)<br>
(Cray Inc.)<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>

</div>
</blockquote></span></body></html>