Directly generating binary file

Hi!

I'm looking for a way to make the the "llc" tool (or any other tool),
directly produce a binary file for some target.

The TargetMachine class has a method 'addPassesToEmitMachineCode', that's
suitable for that, but that method also requires an instance of
MachineCodeEmitter.

The existing MachineCodeEmitter derived classes are either debug-only
(writing to std::cerr), or for JIT, or for ELF (which is not used anywhere,
BTW).

Ideally, I'd like to create my own MachineCodeEmitter derived class, load it
into llc with the -load option, and then have new option for 'llc' that
will use MachineCodeEmitter, not AssemblyWriter, to generate the file.

The reason I'm trying to do this is that the target does not have an
assembler, and does not need it, and so designing an assembler syntax just
for the sake of code generation does not seem right.

Any suggestions how I should proceed?

Thanks,
Volodya

I'm looking for a way to make the the "llc" tool (or any other tool),
directly produce a binary file for some target.

ok

The TargetMachine class has a method 'addPassesToEmitMachineCode', that's
suitable for that, but that method also requires an instance of
MachineCodeEmitter.

Actually, you probably want to plug into the addPassesToEmitFile API, when FileType is set to ObjectFile. X86TargetMachine::addPassesToEmitFile demonstrates how to do this.

The existing MachineCodeEmitter derived classes are either debug-only
(writing to std::cerr), or for JIT, or for ELF (which is not used anywhere,
BTW).
Ideally, I'd like to create my own MachineCodeEmitter derived class, load it
into llc with the -load option, and then have new option for 'llc' that
will use MachineCodeEmitter, not AssemblyWriter, to generate the file.

Yup, the ELFWriter.cpp file should be a reasonable template to base your work on, but note that it is not complete at this point.

The reason I'm trying to do this is that the target does not have an
assembler, and does not need it, and so designing an assembler syntax just
for the sake of code generation does not seem right.

Ok.

Any suggestions how I should proceed?

I'd suggest following the pattern of the ElfWriter. Basically, the elf writer knows about the object file format (ELF in this case, obviously) but doesn't know anything specific about the target. The target handles translation of MachineInstr's to relocatable machine code and relocations, sending the result to the MachineCodeEmitter. You can then format it according to the requirements of the object file format.

Alternatively, you could side step all of this and write your own .o file writer that doesn't use the MachineCodeEmitter interfaces at all. If this is easiest, go for it.

Note that *some* assembler format is useful for debugging, writting regression tests, etc.

-Chris

Chris Lattner wrote:

The TargetMachine class has a method 'addPassesToEmitMachineCode', that's
suitable for that, but that method also requires an instance of
MachineCodeEmitter.

Actually, you probably want to plug into the addPassesToEmitFile API, when
FileType is set to ObjectFile. X86TargetMachine::addPassesToEmitFile
demonstrates how to do this.

Ok. Note, however, that online HTML docs for "llc", as well as "llc.pod" in
the current CVS don't mention the "filetype" option that is used to control
file format.

And, should 'addPassesToEmitMachineCode' method be declared deprecated?

Any suggestions how I should proceed?

I'd suggest following the pattern of the ElfWriter. Basically, the elf
writer knows about the object file format (ELF in this case, obviously)
but doesn't know anything specific about the target. The target handles
translation of MachineInstr's to relocatable machine code and relocations,
sending the result to the MachineCodeEmitter. You can then format it
according to the requirements of the object file format.

Alternatively, you could side step all of this and write your own .o file
writer that doesn't use the MachineCodeEmitter interfaces at all. If this
is easiest, go for it.

So far this looks the simplest approach. Especially sincelooking at
ELFCodeEmitter, I see quite a bunch of unimplemented methods.

Note that *some* assembler format is useful for debugging, writting
regression tests, etc.

Sure, I plan to have some format that will be output by disassembler, but
don't plan to ever read that format :wink:

- Volodya

The TargetMachine class has a method 'addPassesToEmitMachineCode', that's
suitable for that, but that method also requires an instance of
MachineCodeEmitter.

Actually, you probably want to plug into the addPassesToEmitFile API, when
FileType is set to ObjectFile. X86TargetMachine::addPassesToEmitFile
demonstrates how to do this.

Ok. Note, however, that online HTML docs for "llc", as well as "llc.pod" in
the current CVS don't mention the "filetype" option that is used to control
file format.

Currently, no targets support that option, so it's basically an internal interface still.

And, should 'addPassesToEmitMachineCode' method be declared deprecated?

It is used for the JIT.

Alternatively, you could side step all of this and write your own .o file
writer that doesn't use the MachineCodeEmitter interfaces at all. If this
is easiest, go for it.

So far this looks the simplest approach. Especially sincelooking at
ELFCodeEmitter, I see quite a bunch of unimplemented methods.

ok

Note that *some* assembler format is useful for debugging, writting
regression tests, etc.

Sure, I plan to have some format that will be output by disassembler, but
don't plan to ever read that format :wink:

Makes sense! :slight_smile:

-Chris