via llvm-dev
2016-May-23 01:13 UTC
[llvm-dev] Using an MCStreamer Directly to produce an object file?
<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>
Reasonably Related Threads
- Using an MCStreamer Directly to produce an object file?
- Problems using LLVM as a disassembler.
- [LLVMdev] Looking for ideas on how to make llvm-objdump handle both arm and thumb disassembly from the same object file
- [LLVMdev] How to output a .S *and* a .OBJ file?
- [LLVMdev] MC: Object file specific parsing