add code to emit the .text section to the section header.
Add a *VERY INITIAL* machine code emitter class. This is enough to take
this C function:
int foo(int X) { return X +1; }
and make objdump produce the following:
$ objdump -d t-llvm.o
t-llvm.o: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: b8 01 00 00 00 mov $0x1,%eax
5: 03 44 24 04 add 0x4(%esp,1),%eax
9: c3 ret
Anything using branches or refering to the constant pool or requiring
relocations will not work yet.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22375 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index bdf38fe..96668e2 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -34,16 +34,92 @@
#include "llvm/CodeGen/ELFWriter.h"
#include "llvm/Module.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
using namespace llvm;
+namespace llvm {
+ class ELFCodeEmitter : public MachineCodeEmitter {
+ ELFWriter &EW;
+ std::vector<unsigned char> &OutputBuffer;
+ size_t FnStart;
+ public:
+ ELFCodeEmitter(ELFWriter &ew) : EW(ew), OutputBuffer(EW.OutputBuffer) {}
+
+ void startFunction(MachineFunction &F) {
+ // Align the output buffer to the appropriate alignment.
+ unsigned Align = 16; // FIXME: GENERICIZE!!
+ ELFWriter::ELFSection &TextSection = EW.SectionList.back();
+
+ // Upgrade the section alignment if required.
+ if (TextSection.Align < Align) TextSection.Align = Align;
+
+ // Add padding zeros to the end of the buffer to make sure that the
+ // function will start on the correct byte alignment within the section.
+ size_t SectionOff = OutputBuffer.size()-TextSection.Offset;
+ if (SectionOff & (Align-1)) {
+ // Add padding to get alignment to the correct place.
+ size_t Pad = Align-(SectionOff & (Align-1));
+ OutputBuffer.resize(OutputBuffer.size()+Pad);
+ }
+
+ FnStart = OutputBuffer.size();
+ }
+ void finishFunction(MachineFunction &F) {}
+ void emitConstantPool(MachineConstantPool *MCP) {
+ if (MCP->isEmpty()) return;
+ assert(0 && "unimp");
+ }
+ virtual void emitByte(unsigned char B) {
+ OutputBuffer.push_back(B);
+ }
+ virtual void emitWordAt(unsigned W, unsigned *Ptr) {
+ assert(0 && "ni");
+ }
+ virtual void emitWord(unsigned W) {
+ assert(0 && "ni");
+ }
+ virtual uint64_t getCurrentPCValue() {
+ return OutputBuffer.size();
+ }
+ virtual uint64_t getCurrentPCOffset() {
+ return OutputBuffer.size()-FnStart;
+ }
+ void addRelocation(const MachineRelocation &MR) {
+ assert(0 && "relo not handled yet!");
+ }
+ virtual uint64_t getConstantPoolEntryAddress(unsigned Index) {
+ assert(0 && "CP not implementated yet!");
+ }
+ /// JIT SPECIFIC FUNCTIONS
+ void startFunctionStub(unsigned StubSize) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ }
+ void *finishFunctionStub(const Function *F) {
+ assert(0 && "JIT specific function called!");
+ abort();
+ return 0;
+ }
+ };
+}
+
+
ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) {
e_machine = 0; // e_machine defaults to 'No Machine'
e_flags = 0; // e_flags defaults to 0, no flags.
is64Bit = TM.getTargetData().getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData().isLittleEndian();
+
+ // Create the machine code emitter object for this target.
+ MCE = new ELFCodeEmitter(*this);
+}
+
+ELFWriter::~ELFWriter() {
+ delete MCE;
}
// doInitialization - Emit the file header and all of the global variables for
@@ -91,9 +167,8 @@
// entry.
SymbolTable.push_back(ELFSym(0));
+ SectionList.push_back(ELFSection(".text", OutputBuffer.size()));
-
- // FIXME: Should start the .text section.
return false;
}
@@ -180,14 +255,24 @@
bool ELFWriter::runOnMachineFunction(MachineFunction &MF) {
+ // Nothing to do here, this is all done through the MCE object above.
return false;
}
/// doFinalization - Now that the module has been completely processed, emit
/// the ELF file to 'O'.
bool ELFWriter::doFinalization(Module &M) {
- // Okay, the .text section has now been finalized.
- // FIXME: finalize the .text section.
+ // Okay, the .text section has now been finalized. If it contains nothing, do
+ // not emit it.
+ uint64_t TextSize = OutputBuffer.size() - SectionList.back().Offset;
+ if (TextSize == 0) {
+ SectionList.pop_back();
+ } else {
+ ELFSection &Text = SectionList.back();
+ Text.Size = TextSize;
+ Text.Type = ELFSection::SHT_PROGBITS;
+ Text.Flags = ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC;
+ }
// Okay, the ELF header and .text sections have been completed, build the
// .data, .bss, and "common" sections next.