[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