<html><body><span style="font-family:Verdana; color:#000; font-size:10pt;"><div>David,</div><div><br></div><div>I had a couple of issues, but the lack of a call to "Finish" was really the big one.  I had actually replied that  I had things working, but I don't see my mail in the mailing list.. maybe I sent it out wrong.  Anyway, working now, and you were pretty much spot-on about what the issue was.</div><div><br></div><div>Thanks so much!</div><div>~Aaron Vose<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: Re: [llvm-dev] Using an MCStreamer Directly to produce an<br>
object file?<br>
From: David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>><br>
Date: Sun, May 22, 2016 2:07 pm<br>
To: <a href="mailto:avose@aaronvose.net">avose@aaronvose.net</a><br>
Cc: llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><br>
<br>
<div dir="ltr">Personally I looked at llvm-dsymutil as an example of writing a basic object file with MCStreamer when I created llvm-dwp to do a similar task. Perhaps you could model things off either of those?<br><br>Did you call "Finish" on your MCStreamer?<br><br>Also, I don't think I needed to use tool_output_file - not sure where that's from. there's simple raw_ostreams that go straight to files.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 20, 2016 at 5:34 PM, via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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(MAI.get(), 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 = BOS.get();<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 target="_blank" 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" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br> </blockquote></div><br></div> 
</div>
</blockquote></span></body></html>