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
