via llvm-dev
2016-May-21 04:22 UTC
[llvm-dev] Using_an_MCStreamer_Directly_to_produce_an_o bject_file?
<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>