diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-07-11 05:17:18 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-07-11 05:17:18 +0000 | 
| commit | 2244f73437db1532f1d1c389734fa2c4acbc85d9 (patch) | |
| tree | b991af1b67d3f7789740439a932a126ef060125a /llvm/lib/CodeGen | |
| parent | 6801f4f2911180c425785f99ab4c052376664ff2 (diff) | |
| download | bcm5719-llvm-2244f73437db1532f1d1c389734fa2c4acbc85d9.tar.gz bcm5719-llvm-2244f73437db1532f1d1c389734fa2c4acbc85d9.zip | |
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.
llvm-svn: 22375
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/ELFWriter.cpp | 93 | 
1 files changed, 89 insertions, 4 deletions
| diff --git a/llvm/lib/CodeGen/ELFWriter.cpp b/llvm/lib/CodeGen/ELFWriter.cpp index bdf38fe6433..96668e29ecb 100644 --- a/llvm/lib/CodeGen/ELFWriter.cpp +++ b/llvm/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 @@ bool ELFWriter::doInitialization(Module &M) {    // 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 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV, ELFSection &DataSection,  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. | 

