Changed ELFCodeEmitter to inherit from ObjectCodeEmitter
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 6 Jul 2009 09:26:48 +0000 (09:26 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 6 Jul 2009 09:26:48 +0000 (09:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74821 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ELFCodeEmitter.cpp
lib/CodeGen/ELFCodeEmitter.h
lib/CodeGen/ELFWriter.cpp
lib/CodeGen/ELFWriter.h

index 691f19408d47877e2e9023e4ed82a6f9d5ef7856..78f0dae51c0a9f9fa95836a4f1b21b1425fb4786 100644 (file)
@@ -33,47 +33,30 @@ namespace llvm {
 /// startFunction - This callback is invoked when a new machine function is
 /// about to be emitted.
 void ELFCodeEmitter::startFunction(MachineFunction &MF) {
+  DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
+
   // Get the ELF Section that this function belongs in.
   ES = &EW.getTextSection();
 
-  DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
-
-  // FIXME: better memory management, this will be replaced by BinaryObjects
-  BinaryData &BD = ES->getData();
-  BD.reserve(4096);
-  BufferBegin = &BD[0];
-  BufferEnd = BufferBegin + BD.capacity();
+  // Set the desired binary object to be used by the code emitters
+  setBinaryObject(ES);
 
   // Get the function alignment in bytes
   unsigned Align = (1 << MF.getAlignment());
 
-  // Align the section size with the function alignment, so the function can
-  // start in a aligned offset, also update the section alignment if needed.
+  // The function must start on its required alignment
+  ES->emitAlignment(Align);
+
+  // Update the section alignment if needed.
   if (ES->Align < Align) ES->Align = Align;
-  ES->Size = (ES->Size + (Align-1)) & (-Align);
-
-  // Snaity check on allocated space for text section
-  assert( ES->Size < 4096 && "no more space in TextSection" );
-
-  // FIXME: Using ES->Size directly here instead of calculating it from the
-  // output buffer size (impossible because the code emitter deals only in raw
-  // bytes) forces us to manually synchronize size and write padding zero bytes
-  // to the output buffer for all non-text sections.  For text sections, we do
-  // not synchonize the output buffer, and we just blow up if anyone tries to
-  // write non-code to it.  An assert should probably be added to
-  // AddSymbolToSection to prevent calling it on the text section.
-  CurBufferPtr = BufferBegin + ES->Size;
-
-  // Record function start address relative to BufferBegin
-  FnStartPtr = CurBufferPtr;
+
+  // Record the function start offset
+  FnStartOff = ES->getCurrentPCOffset();
 }
 
 /// finishFunction - This callback is invoked after the function is completely
 /// finished.
 bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
-  // Update Section Size
-  ES->Size = CurBufferPtr - BufferBegin;
-
   // Add a symbol to represent the function.
   const Function *F = MF.getFunction();
   ELFSym FnSym(F);
@@ -81,10 +64,10 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
   FnSym.setBind(EW.getGlobalELFLinkage(F));
   FnSym.setVisibility(EW.getGlobalELFVisibility(F));
   FnSym.SectionIdx = ES->SectionIdx;
-  FnSym.Size = CurBufferPtr-FnStartPtr;
+  FnSym.Size = ES->getCurrentPCOffset()-FnStartOff;
 
   // Offset from start of Section
-  FnSym.Value = FnStartPtr-BufferBegin;
+  FnSym.Value = FnStartOff;
 
   // Locals should go on the symbol list front
   if (!F->hasPrivateLinkage()) {
index 982aebf8fcc022ce1ec172c50591be8026539fd0..d7f178d8bfb9392def5b8e4ce474148bbb72b4e1 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef ELFCODEEMITTER_H
 #define ELFCODEEMITTER_H
 
-#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/CodeGen/ObjectCodeEmitter.h"
 #include <vector>
 
 namespace llvm {
@@ -19,7 +19,7 @@ namespace llvm {
 
   /// ELFCodeEmitter - This class is used by the ELFWriter to 
   /// emit the code for functions to the ELF file.
-  class ELFCodeEmitter : public MachineCodeEmitter {
+  class ELFCodeEmitter : public ObjectCodeEmitter {
     ELFWriter &EW;
 
     /// Target machine description
@@ -28,30 +28,11 @@ namespace llvm {
     /// Section containing code for functions
     ELFSection *ES;
 
-    /// Relocations - These are the relocations that the function needs, as
-    /// emitted.
+    /// Relocations - Record relocations needed by the current function 
     std::vector<MachineRelocation> Relocations;
 
-    /// CPLocations - This is a map of constant pool indices to offsets from the
-    /// start of the section for that constant pool index.
-    std::vector<uintptr_t> CPLocations;
-
-    /// CPSections - This is a map of constant pool indices to the MachOSection
-    /// containing the constant pool entry for that index.
-    std::vector<unsigned> CPSections;
-
-    /// JTLocations - This is a map of jump table indices to offsets from the
-    /// start of the section for that jump table index.
-    std::vector<uintptr_t> JTLocations;
-
-    /// MBBLocations - This vector is a mapping from MBB ID's to their address.
-    /// It is filled in by the StartMachineBasicBlock callback and queried by
-    /// the getMachineBasicBlockAddress callback.
-    std::vector<uintptr_t> MBBLocations;
-
-    /// FnStartPtr - Pointer to the start location of the current function
-    /// in the buffer
-    uint8_t *FnStartPtr;
+    /// FnStartPtr - Function offset from the beginning of ELFSection 'ES'
+    uintptr_t FnStartOff;
 
     /// JumpTableSectionIdx - Holds the index of the Jump Table Section 
     unsigned JumpTableSectionIdx;
@@ -59,71 +40,36 @@ namespace llvm {
     explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM),
                                              JumpTableSectionIdx(0) {}
 
-    void startFunction(MachineFunction &F);
-    bool finishFunction(MachineFunction &F);
-
+    /// addRelocation - Register new relocations for this function
     void addRelocation(const MachineRelocation &MR) {
       Relocations.push_back(MR);
     }
 
-    virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
-      if (MBBLocations.size() <= (unsigned)MBB->getNumber())
-        MBBLocations.resize((MBB->getNumber()+1)*2);
-      MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
-    }
+    /// emitConstantPool - For each constant pool entry, figure out which
+    /// section the constant should live in and emit data to it
+    void emitConstantPool(MachineConstantPool *MCP);
 
-    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
-      assert(CPLocations.size() > Index && "CP not emitted!");
-      return CPLocations[Index];
-    }
+    /// emitJumpTables - Emit all the jump tables for a given jump table
+    /// info and record them to the appropriate section.
+    void emitJumpTables(MachineJumpTableInfo *MJTI);
 
-    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
-      assert(JTLocations.size() > Index && "JT not emitted!");
-      return JTLocations[Index];
-    }
+    void startFunction(MachineFunction &F);
+    bool finishFunction(MachineFunction &F);
 
-    virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
-      assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 
-             MBBLocations[MBB->getNumber()] && "MBB not emitted!");
-      return MBBLocations[MBB->getNumber()];
+    /// emitLabel - Emits a label
+    virtual void emitLabel(uint64_t LabelID) {
+      assert("emitLabel not implemented");
     }
 
+    /// getLabelAddress - Return the address of the specified LabelID, 
+    /// only usable after the LabelID has been emitted.
     virtual uintptr_t getLabelAddress(uint64_t Label) const {
-      assert(0 && "Label address not implementated yet!");
-      abort();
+      assert("getLabelAddress not implemented");
       return 0;
     }
 
-    virtual void emitLabel(uint64_t LabelID) {
-      assert(0 && "emit Label not implementated yet!");
-      abort();
-    }
-
-    /// emitConstantPool - For each constant pool entry, figure out which section
-    /// the constant should live in and emit the constant.
-    void emitConstantPool(MachineConstantPool *MCP);
-
-    /// emitJumpTables - Emit all the jump tables for a given jump table info
-    /// record to the appropriate section.
-    void emitJumpTables(MachineJumpTableInfo *MJTI);
-
     virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) {}
 
-    /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
-    void startGVStub(const GlobalValue* F, unsigned StubSize,
-                     unsigned Alignment = 1) {
-      assert(0 && "JIT specific function called!");
-      abort();
-    }
-    void startGVStub(const GlobalValue* F,  void *Buffer, unsigned StubSize) {
-      assert(0 && "JIT specific function called!");
-      abort();
-    }
-    void *finishGVStub(const GlobalValue *F) {
-      assert(0 && "JIT specific function called!");
-      abort();
-      return 0;
-    }
 };  // end class ELFCodeEmitter
 
 } // end namespace llvm
index 53e4da584592504f4dfd8229e381a42f3860794e..ddc3670665d69a96b9c2a3d2f67c645ac22154b2 100644 (file)
 #include "llvm/Support/Streams.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Debug.h"
+
 using namespace llvm;
 
 char ELFWriter::ID = 0;
-/// AddELFWriter - Concrete function to add the ELF writer to the function pass
-/// manager.
+
+/// AddELFWriter - Add the ELF writer to the function pass manager
 ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
-                                       raw_ostream &O,
-                                       TargetMachine &TM) {
+                                      raw_ostream &O,
+                                      TargetMachine &TM) {
   ELFWriter *EW = new ELFWriter(O, TM);
   PM.add(EW);
-  return (ObjectCodeEmitter*) &EW->getMachineCodeEmitter();
+  return EW->getObjectCodeEmitter();
 }
 
 //===----------------------------------------------------------------------===//
@@ -77,15 +78,15 @@ ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
   TAI = TM.getTargetAsmInfo();
   TEW = TM.getELFWriterInfo();
 
-  // Create the machine code emitter object for this target.
-  MCE = new ELFCodeEmitter(*this);
+  // Create the object code emitter object for this target.
+  ElfCE = new ELFCodeEmitter(*this);
 
   // Inital number of sections
   NumSections = 0;
 }
 
 ELFWriter::~ELFWriter() {
-  delete MCE;
+  delete ElfCE;
 }
 
 // doInitialization - Emit the file header and all of the global variables for
@@ -361,23 +362,13 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) {
 
 
 bool ELFWriter::runOnMachineFunction(MachineFunction &MF) {
-  // Nothing to do here, this is all done through the MCE object above.
+  // Nothing to do here, this is all done through the ElfCE object above.
   return false;
 }
 
 /// doFinalization - Now that the module has been completely processed, emit
 /// the ELF file to 'O'.
 bool ELFWriter::doFinalization(Module &M) {
-  /// FIXME: This should be removed when moving to ObjectCodeEmiter. Since the
-  /// current ELFCodeEmiter uses CurrBuff, ... it doesn't update S.Data
-  /// vector size for .text sections, so this is a quick dirty fix
-  ELFSection &TS = getTextSection();
-  if (TS.Size) {
-    BinaryData &BD = TS.getData();
-    for (unsigned e=0; e<TS.Size; ++e)
-      BD.push_back(BD[e]);
-  }
-
   // Emit .data section placeholder
   getDataSection();
 
index bab118c6e356820c40763f37cd6abb2145e7e4b5..b257cfb9ee4a116dcc057ec92b8569e11fdd2e01 100644 (file)
@@ -24,15 +24,16 @@ namespace llvm {
   class Constant;
   class ConstantStruct;
   class ELFCodeEmitter;
+  class ELFRelocation;
+  class ELFSection;
+  class ELFSym;
   class GlobalVariable;
   class Mangler;
   class MachineCodeEmitter;
+  class ObjectCodeEmitter;
   class TargetAsmInfo;
   class TargetELFWriterInfo;
   class raw_ostream;
-  class ELFSection;
-  class ELFSym;
-  class ELFRelocation;
 
   /// ELFWriter - This class implements the common target-independent code for
   /// writing ELF files.  Targets should derive a class from this to
@@ -43,15 +44,14 @@ namespace llvm {
   public:
     static char ID;
 
-    MachineCodeEmitter &getMachineCodeEmitter() const {
-      return *(MachineCodeEmitter*)MCE;
+    /// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter
+    ObjectCodeEmitter *getObjectCodeEmitter() {
+      return reinterpret_cast<ObjectCodeEmitter*>(ElfCE);
     }
 
     ELFWriter(raw_ostream &O, TargetMachine &TM);
     ~ELFWriter();
 
-    typedef std::vector<unsigned char> DataBuffer;
-
   protected:
     /// Output stream to send the resultant object file to.
     raw_ostream &O;
@@ -67,7 +67,7 @@ namespace llvm {
 
     /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
     /// code for functions to the .o file.
-    ELFCodeEmitter *MCE;
+    ELFCodeEmitter *ElfCE;
 
     /// TAI - Target Asm Info, provide information about section names for
     /// globals and other target specific stuff.