[llvm-dev] Using an MCStreamer Directly to produce an object file?

David Blaikie via llvm-dev llvm-dev at lists.llvm.org
Sun May 22 11:07:01 PDT 2016


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?

Did you call "Finish" on your MCStreamer?

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.

On Fri, May 20, 2016 at 5:34 PM, via llvm-dev <llvm-dev at lists.llvm.org>
wrote:

> llvm-dev,
>
>
> Thanks so much in advance for any help, tips, or advice you may be able
> to offer me.  I'm going to try to avoid the big-picture description of
> the project I'm working on, and only talk about the parts that I have
> trouble with / currently need to implement.  --  I've been starting by
> taking the source code from the "llvm-mc" tool, and working that down
> into a smaller form that does the kinds of things I want to do at the MC
> "layer".
>
>
> So, I'd like to be able to use a MCStreamer object directly to make some
> output file, and object ".o" would be just fine to start with.
>
> I seem to be able to create an aarch64 target without too much issue:
>
>   llvm::InitializeAllTargetInfos();
>   llvm::InitializeAllTargetMCs();
>   llvm::InitializeAllAsmParsers();
>   llvm::InitializeAllDisassemblers();
>
>   std::string Error;
>   std::string TripleName("aarch64-unknown-linux-gnu");
>   Triple TheTriple(Triple::normalize(TripleName));
>   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName,
> Error);
>   if (!TheTarget) {
>     std::cerr << "llvm_insts_to_binary(): " << Error;
>     return 1;
>   }
>
>
> Then, I move on to creating some of the needed ASM / REG info and an
> MCContext, etc.:
>
>   std::unique_ptr<MCRegisterInfo>
> MRI(TheTarget->createMCRegInfo(TripleName));
>   assert(MRI && "Unable to create target register info!");
>   std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI,
> TripleName));
>   assert(MAI && "Unable to create target asm info!");
>   std::string MCPU("generic");
>   std::string FeaturesStr("");
>   MCObjectFileInfo MOFI;
>   MCContext Ctx(MAI.get(), MRI.get(), &MOFI);
>   MOFI.InitMCObjectFileInfo(TheTriple, llvm::Reloc::Model::PIC_,
> llvm::CodeModel::Model::Default, Ctx);
>   std::unique_ptr<MCInstrInfo>     MCII(TheTarget->createMCInstrInfo());
>   std::unique_ptr<MCSubtargetInfo>
> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
>
>
> OK, that seems, OK.  Now I want to setup an output buffer:
>
>   std::string ofile("/home/users/avose/hpcgp/hpcgp_rundir/tmp.o");
>   std::unique_ptr<tool_output_file> Out = GetOutputStream(ofile);
>   if (!Out) {
>     return 1;
>   }
>   std::unique_ptr<buffer_ostream> BOS;
>   raw_pwrite_stream *OS = &Out->os();
>   if (!Out->os().supportsSeeking()) {
>     BOS = make_unique<buffer_ostream>(Out->os());
>     OS = BOS.get();
>   }
>
>
> This also seems to do OK.  Now I would think I can finally get around to
> making the code emitter and the MCStreamer:
>
>   MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
>   MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName,
> MCPU);
>   MCStreamer   *Str = TheTarget->createMCObjectStreamer(TheTriple, Ctx,
> *MAB, *OS, CE, *STI, true, false);
>
>
> So, like, wow, I would think I should be good to go here!  I should be
> able to just use functions like:
>
>   Str->EmitInstruction();
>   Str->EmitLabel();
>
>
> These should then result in everything I've tried to emit coming out in
> my output object file "tmp.o", you know, as long as I'm careful to be
> sure to make a call to keep my output file from being deleted.  So, when
> I'm done making "emit" calls like the above, I be sure to do the keep
> call:
>
> Out->keep();
>
>
> I'm aware that the calls to EmitInstruction(); and EmitLabel(); need to
> have their arguments properly constructed first, and I do try to do that
> using the context I had set up before, so, something like:
>
>   const llvm::Twine tname("my_label_name");
>   llvm::MCSymbol* mcs = Ctx.getOrCreateSymbol(tname);
>   Str->EmitLabel(mcs);
>
>
> Or even something more complicated like setting up an MCInst and all
> it's operands:
>
>   llvm::MCInst *llinst = new MCInst();
>   llinst->setOpcode(input_opcode);
>   llinst->addOperand(llvm::MCOperand::createReg(input_reg0));
>   llinst->addOperand(llvm::MCOperand::createReg(input_reg1));
>   const llvm::Twine tname("label_name");
>   const llvm::MCSymbol* mcs = Ctx.getOrCreateSymbol(tname);
>   const llvm::MCSymbolRefExpr *msre = llvm::MCSymbolRefExpr::create(mcs,
> Ctx);
>   llinst->addOperand(llvm::MCOperand::createExpr(msre));
>
>
> However, while I don't get any compiler errors, and everything runs to
> completion without printing any errors, my output file "tmp.o" is always
> created, but just empty with zero bytes.  I must be doing something
> silly here..  Does anyone have any ideas about what I'm doing wrong, or
> perhaps have example code that directly uses the MCStreamer object to
> write out object binary files?  Some examples showing how to make this
> work would _really_ make my week.
>
> This has been hard to debug, as I don't get any errors, just an empty
> output .o file...
>
> I was thinking it may be because of section issues, so I did add some
> initial sections, hoping that might help:
>
>   Str->InitSections(false);
>   MCSection *textsect = Ctx.getELFSection(".text", ELF::SHT_PROGBITS,
> ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
>   Str->SwitchSection(textsect);
>
>
> This did not seem to help at all.  I'm running out of ideas.  Anyone
> know how to use an MCStreamer object directly to make and object file?
>
>
> Thanks so much for your time,
> ~Aaron Vose
>
>
> (Software Engineer)
> (Cray Inc.)
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160522/4a5b8210/attachment.html>


More information about the llvm-dev mailing list