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.