<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 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>