Fix a sub-register indice propagation bug.
[oota-llvm.git] / lib / CodeGen / ELFWriter.cpp
index e43346897d9ab74bace73a80123eee587788423b..baba0551dd44838e939f940b8b303f75b4678474 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/ELFWriter.h"
+#include "ELFWriter.h"
 #include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/CodeGen/FileWriters.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetELFWriterInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/OutputBuffer.h"
 #include "llvm/Support/Streams.h"
+#include <list>
 using namespace llvm;
 
+char ELFWriter::ID = 0;
+/// AddELFWriter - Concrete function to add the ELF writer to the function pass
+/// manager.
+MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
+                                       std::ostream &O,
+                                       TargetMachine &TM) {
+  ELFWriter *EW = new ELFWriter(O, TM);
+  PM.add(EW);
+  return &EW->getMachineCodeEmitter();
+}
+
 //===----------------------------------------------------------------------===//
 //                       ELFCodeEmitter Implementation
 //===----------------------------------------------------------------------===//
@@ -56,7 +72,7 @@ namespace llvm {
     std::vector<unsigned char> *OutBuffer;
     size_t FnStart;
   public:
-    ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
+    explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
 
     void startFunction(MachineFunction &F);
     bool finishFunction(MachineFunction &F);
@@ -82,12 +98,28 @@ namespace llvm {
       return 0;
     }
 
+    virtual intptr_t getLabelAddress(uint64_t Label) const {
+      assert(0 && "Label address not implementated yet!");
+      abort();
+      return 0;
+    }
+
+    virtual void emitLabel(uint64_t LabelID) {
+      assert(0 && "emit Label not implementated yet!");
+      abort();
+    }
+
+
+    virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
+
     /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
-    void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+    void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                           unsigned Alignment = 1) {
       assert(0 && "JIT specific function called!");
       abort();
     }
-    void *finishFunctionStub(const Function *F) {
+    void *finishFunctionStub(const GlobalValue *F) {
       assert(0 && "JIT specific function called!");
       abort();
       return 0;
@@ -115,7 +147,9 @@ void ELFCodeEmitter::startFunction(MachineFunction &F) {
 
   // 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.
-  OutputBuffer OB(TM, *OutBuffer);
+  OutputBuffer OB(*OutBuffer,
+                  TM.getTargetData()->getPointerSizeInBits() == 64,
+                  TM.getTargetData()->isLittleEndian());
   OB.align(Align);
   FnStart = OutBuffer->size();
 }
@@ -159,8 +193,8 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
 //                          ELFWriter Implementation
 //===----------------------------------------------------------------------===//
 
-ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) {
-  e_machine = 0;  // e_machine defaults to 'No Machine'
+ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) 
+  : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm) {
   e_flags = 0;    // e_flags defaults to 0, no flags.
 
   is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
@@ -182,7 +216,7 @@ bool ELFWriter::doInitialization(Module &M) {
 
   // Local alias to shortenify coming code.
   std::vector<unsigned char> &FH = FileHeader;
-  OutputBuffer FHOut(TM, FH);
+  OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
 
   FHOut.outbyte(0x7F);                     // EI_MAG0
   FHOut.outbyte('E');                      // EI_MAG1
@@ -195,7 +229,7 @@ bool ELFWriter::doInitialization(Module &M) {
 
   // This should change for shared objects.
   FHOut.outhalf(1);                 // e_type = ET_REL
-  FHOut.outhalf(e_machine);         // e_machine = whatever the target wants
+  FHOut.outword(TM.getELFWriterInfo()->getEMachine()); // target-defined
   FHOut.outword(1);                 // e_version = 1
   FHOut.outaddr(0);                 // e_entry = 0 -> no entry point in .o file
   FHOut.outaddr(0);                 // e_phoff = 0 -> no program header for .o
@@ -239,8 +273,8 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
   }
 
   const Type *GVType = (const Type*)GV->getType();
-  unsigned Align = TM.getTargetData()->getTypeAlignment(GVType);
-  unsigned Size  = TM.getTargetData()->getTypeSize(GVType);
+  unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
+  unsigned Size  = TM.getTargetData()->getABITypeSize(GVType);
 
   // If this global has a zero initializer, it is part of the .bss or common
   // section.
@@ -353,7 +387,7 @@ void ELFWriter::EmitSymbolTable() {
   StrTab.Align = 1;
 
   DataBuffer &StrTabBuf = StrTab.SectionData;
-  OutputBuffer StrTabOut(TM, StrTabBuf);
+  OutputBuffer StrTabOut(StrTabBuf, is64Bit, isLittleEndian);
 
   // Set the zero'th symbol to a null byte, as required.
   StrTabOut.outbyte(0);
@@ -389,7 +423,7 @@ void ELFWriter::EmitSymbolTable() {
   SymTab.Info = FirstNonLocalSymbol;   // First non-STB_LOCAL symbol.
   SymTab.EntSize = 16; // Size of each symtab entry. FIXME: wrong for ELF64
   DataBuffer &SymTabBuf = SymTab.SectionData;
-  OutputBuffer SymTabOut(TM, SymTabBuf);
+  OutputBuffer SymTabOut(SymTabBuf, is64Bit, isLittleEndian);
 
   if (!is64Bit) {   // 32-bit and 64-bit formats are shuffled a bit.
     for (unsigned i = 0, e = SymbolTable.size(); i != e; ++i) {
@@ -425,7 +459,7 @@ void ELFWriter::EmitSectionTableStringTable() {
 
   // Now that we know which section number is the .shstrtab section, update the
   // e_shstrndx entry in the ELF header.
-  OutputBuffer FHOut(TM, FileHeader);
+  OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
   FHOut.fixhalf(SHStrTab.SectionIdx, ELFHeader_e_shstrndx_Offset);
 
   // Set the NameIdx of each section in the string table and emit the bytes for
@@ -477,7 +511,7 @@ void ELFWriter::OutputSectionsAndSectionTable() {
 
   // Now that we know where all of the sections will be emitted, set the e_shnum
   // entry in the ELF header.
-  OutputBuffer FHOut(TM, FileHeader);
+  OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
   FHOut.fixhalf(NumSections, ELFHeader_e_shnum_Offset);
 
   // Now that we know the offset in the file of the section table, update the
@@ -491,7 +525,7 @@ void ELFWriter::OutputSectionsAndSectionTable() {
   DataBuffer().swap(FileHeader);
 
   DataBuffer Table;
-  OutputBuffer TableOut(TM, Table);
+  OutputBuffer TableOut(Table, is64Bit, isLittleEndian);
 
   // Emit all of the section data and build the section table itself.
   while (!SectionList.empty()) {