[llvm-commits] [llvm] r73333 - in /llvm/trunk: include/llvm/CodeGen/BinaryObject.h include/llvm/Target/TargetELFWriterInfo.h lib/CodeGen/ELF.h lib/CodeGen/ELFCodeEmitter.cpp lib/CodeGen/ELFWriter.cpp lib/CodeGen/ELFWriter.h lib/Target/TargetELFWriterInfo.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Sun Jun 14 00:53:21 PDT 2009


Author: bruno
Date: Sun Jun 14 02:53:21 2009
New Revision: 73333

URL: http://llvm.org/viewvc/llvm-project?rev=73333&view=rev
Log:
Introduce new BinaryObject (blob) class, ELF Writer modified to use it. BinaryObject.h by Aaron Gray

Added:
    llvm/trunk/include/llvm/CodeGen/BinaryObject.h
Modified:
    llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h
    llvm/trunk/lib/CodeGen/ELF.h
    llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
    llvm/trunk/lib/CodeGen/ELFWriter.cpp
    llvm/trunk/lib/CodeGen/ELFWriter.h
    llvm/trunk/lib/Target/TargetELFWriterInfo.cpp

Added: llvm/trunk/include/llvm/CodeGen/BinaryObject.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/BinaryObject.h?rev=73333&view=auto

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/BinaryObject.h (added)
+++ llvm/trunk/include/llvm/CodeGen/BinaryObject.h Sun Jun 14 02:53:21 2009
@@ -0,0 +1,325 @@
+//===-- llvm/CodeGen/BinaryObject.h - Binary Object. -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a Binary Object Aka. "blob" for holding data from code
+// generators, ready for data to the object module code writters.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_BINARYOBJECT_H
+#define LLVM_CODEGEN_BINARYOBJECT_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class MachineRelocation;
+typedef std::vector<uint8_t> BinaryData;
+
+class BinaryObject {
+protected:
+  std::string Name;
+  bool IsLittleEndian;
+  bool Is64Bit;
+  BinaryData Data;
+  std::vector<MachineRelocation> Relocations;
+
+public:
+  /// Constructors and destructor
+  BinaryObject() {}
+
+  BinaryObject(bool isLittleEndian, bool is64Bit)
+    : IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
+
+  BinaryObject(const std::string &name, bool isLittleEndian, bool is64Bit)
+    : Name(name), IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
+
+  ~BinaryObject() {}
+
+  /// getName - get name of BinaryObject
+  inline std::string getName() const { return Name; }
+
+  /// get size of binary data
+  size_t size() const {
+    return Data.size();
+  }
+
+  /// get binary data
+  BinaryData& getData() {
+    return Data;
+  }
+
+  /// get machine relocations
+  const std::vector<MachineRelocation>& getRelocations() const {
+    return Relocations;
+  }
+
+  /// emitByte - This callback is invoked when a byte needs to be
+  /// written to the data stream.
+  inline void emitByte(uint8_t B) {
+    Data.push_back(B);
+  }
+
+  /// emitWord16 - This callback is invoked when a 16-bit word needs to be
+  /// written to the data stream in correct endian format and correct size.
+  inline void emitWord16(uint16_t W) {
+    if (IsLittleEndian)
+      emitWord16LE(W);
+    else
+      emitWord16BE(W);
+  }
+
+  /// emitWord16LE - This callback is invoked when a 16-bit word needs to be
+  /// written to the data stream in correct endian format and correct size.
+  inline void emitWord16LE(uint16_t W) {
+    Data.push_back((W >> 0) & 255);
+    Data.push_back((W >> 8) & 255);
+  }
+
+  /// emitWord16BE - This callback is invoked when a 16-bit word needs to be
+  /// written to the data stream in correct endian format and correct size.
+  inline void emitWord16BE(uint16_t W) {
+    Data.push_back((W >> 8) & 255);
+    Data.push_back((W >> 0) & 255);
+  }
+
+  /// emitWord - This callback is invoked when a word needs to be
+  /// written to the data stream in correct endian format and correct size.
+  inline void emitWord(uint64_t W) {
+    if (!Is64Bit)
+      emitWord32(W);
+    else
+      emitWord64(W);
+  }
+
+  /// emitWord32 - This callback is invoked when a 32-bit word needs to be
+  /// written to the data stream in correct endian format.
+  inline void emitWord32(uint32_t W) {
+    if (IsLittleEndian)
+      emitWordLE(W);
+    else
+      emitWordBE(W);
+  }
+
+  /// emitWord64 - This callback is invoked when a 32-bit word needs to be
+  /// written to the data stream in correct endian format.
+  inline void emitWord64(uint64_t W) {
+    if (IsLittleEndian)
+      emitDWordLE(W);
+    else
+      emitDWordBE(W);
+  }
+
+  /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+  /// written to the data stream in little-endian format.
+  inline void emitWordLE(uint32_t W) {
+    Data.push_back((W >>  0) & 255);
+    Data.push_back((W >>  8) & 255);
+    Data.push_back((W >> 16) & 255);
+    Data.push_back((W >> 24) & 255);
+  }
+
+  /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+  /// written to the data stream in big-endian format.
+  ///
+  inline void emitWordBE(uint32_t W) {
+    Data.push_back((W >> 24) & 255);
+    Data.push_back((W >> 16) & 255);
+    Data.push_back((W >>  8) & 255);
+    Data.push_back((W >>  0) & 255);
+  }
+
+  /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+  /// written to the data stream in little-endian format.
+  inline void emitDWordLE(uint64_t W) {
+    Data.push_back(unsigned(W >>  0) & 255);
+    Data.push_back(unsigned(W >>  8) & 255);
+    Data.push_back(unsigned(W >> 16) & 255);
+    Data.push_back(unsigned(W >> 24) & 255);
+    Data.push_back(unsigned(W >> 32) & 255);
+    Data.push_back(unsigned(W >> 40) & 255);
+    Data.push_back(unsigned(W >> 48) & 255);
+    Data.push_back(unsigned(W >> 56) & 255);
+  }
+
+  /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+  /// written to the data stream in big-endian format.
+  inline void emitDWordBE(uint64_t W) {
+    Data.push_back(unsigned(W >> 56) & 255);
+    Data.push_back(unsigned(W >> 48) & 255);
+    Data.push_back(unsigned(W >> 40) & 255);
+    Data.push_back(unsigned(W >> 32) & 255);
+    Data.push_back(unsigned(W >> 24) & 255);
+    Data.push_back(unsigned(W >> 16) & 255);
+    Data.push_back(unsigned(W >>  8) & 255);
+    Data.push_back(unsigned(W >>  0) & 255);
+  }
+
+  /// fixByte - This callback is invoked when a byte needs to be
+  /// fixup the buffer.
+  inline void fixByte(uint8_t B, uint32_t offset) {
+    Data[offset] = B;
+  }
+
+  /// fixWord16 - This callback is invoked when a 16-bit word needs to
+  /// fixup the data stream in correct endian format.
+  inline void fixWord16(uint16_t W, uint32_t offset) {
+    if (IsLittleEndian)
+      fixWord16LE(W, offset);
+    else
+      fixWord16BE(W, offset);
+  }
+
+  /// emitWord16LE - This callback is invoked when a 16-bit word needs to
+  /// fixup the data stream in little endian format.
+  inline void fixWord16LE(uint16_t W, uint32_t offset) {
+    Data[offset++] = W & 255;
+    Data[offset] = (W >> 8) & 255;
+  }
+
+  /// fixWord16BE - This callback is invoked when a 16-bit word needs to
+  /// fixup data stream in big endian format.
+  inline void fixWord16BE(uint16_t W, uint32_t offset) {
+    Data[offset++] = (W >> 8) & 255;
+    Data[offset] = W & 255;
+  }
+
+  /// emitWord - This callback is invoked when a word needs to
+  /// fixup the data in correct endian format and correct size.
+  inline void fixWord(uint64_t W, uint32_t offset) {
+    if (!Is64Bit)
+      fixWord32(W, offset);
+    else
+      fixWord64(W, offset);
+  }
+
+  /// fixWord32 - This callback is invoked when a 32-bit word needs to
+  /// fixup the data in correct endian format.
+  inline void fixWord32(uint32_t W, uint32_t offset) {
+    if (IsLittleEndian)
+      fixWord32LE(W, offset);
+    else
+      fixWord32BE(W, offset);
+  }
+
+  /// fixWord32LE - This callback is invoked when a 32-bit word needs to
+  /// fixup the data in little endian format.
+  inline void fixWord32LE(uint32_t W, uint32_t offset) {
+    Data[offset++] = W & 255;
+    Data[offset++] = (W >> 8) & 255;
+    Data[offset++] = (W >> 16) & 255;
+    Data[offset] = (W >> 24) & 255;
+  }
+
+  /// fixWord32BE - This callback is invoked when a 32-bit word needs to
+  /// fixup the data in big endian format.
+  inline void fixWord32BE(uint32_t W, uint32_t offset) {
+    Data[offset++] = (W >> 24) & 255;
+    Data[offset++] = (W >> 16) & 255;
+    Data[offset++] = (W >> 8) & 255;
+    Data[offset] = W & 255;
+  }
+
+  /// fixWord64 - This callback is invoked when a 64-bit word needs to
+  /// fixup the data in correct endian format.
+  inline void fixWord64(uint64_t W, uint32_t offset) {
+    if (IsLittleEndian)
+      fixWord64LE(W, offset);
+    else
+      fixWord64BE(W, offset);
+  }
+
+  /// fixWord64BE - This callback is invoked when a 64-bit word needs to
+  /// fixup the data in little endian format.
+  inline void fixWord64LE(uint64_t W, uint32_t offset) {
+    Data[offset++] = W & 255;
+    Data[offset++] = (W >> 8) & 255;
+    Data[offset++] = (W >> 16) & 255;
+    Data[offset++] = (W >> 24) & 255;
+    Data[offset++] = (W >> 32) & 255;
+    Data[offset++] = (W >> 40) & 255;
+    Data[offset++] = (W >> 48) & 255;
+    Data[offset] = (W >> 56) & 255;
+  }
+
+  /// fixWord64BE - This callback is invoked when a 64-bit word needs to
+  /// fixup the data in big endian format.
+  inline void fixWord64BE(uint64_t W, uint32_t offset) {
+    Data[offset++] = (W >> 56) & 255;
+    Data[offset++] = (W >> 48) & 255;
+    Data[offset++] = (W >> 40) & 255;
+    Data[offset++] = (W >> 32) & 255;
+    Data[offset++] = (W >> 24) & 255;
+    Data[offset++] = (W >> 16) & 255;
+    Data[offset++] = (W >> 8) & 255;
+    Data[offset] = W & 255;
+  }
+
+  /// emitAlignment - Pad the data to the specified alignment.
+  void emitAlignment(unsigned Alignment) {
+    if (Alignment <= 1) return;
+    unsigned PadSize = -Data.size() & (Alignment-1);
+    for (unsigned i = 0; i<PadSize; ++i)
+      Data.push_back(0);
+  }
+
+  /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+  /// written to the data stream.
+  void emitULEB128Bytes(uint64_t Value) {
+    do {
+      unsigned char Byte = Value & 0x7f;
+      Value >>= 7;
+      if (Value) Byte |= 0x80;
+      emitByte(Byte);
+    } while (Value);
+  }
+
+  /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+  /// written to the data stream.
+  void emitSLEB128Bytes(int64_t Value) {
+    int Sign = Value >> (8 * sizeof(Value) - 1);
+    bool IsMore;
+
+    do {
+      unsigned char Byte = Value & 0x7f;
+      Value >>= 7;
+      IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+      if (IsMore) Byte |= 0x80;
+      emitByte(Byte);
+    } while (IsMore);
+  }
+
+  /// emitString - This callback is invoked when a String needs to be
+  /// written to the data stream.
+  void emitString(const std::string &String) {
+    for (unsigned i = 0, N = static_cast<unsigned>(String.size()); i<N; ++i) {
+      unsigned char C = String[i];
+      emitByte(C);
+    }
+    emitByte(0);
+  }
+
+  /// getCurrentPCOffset - Return the offset from the start of the emitted
+  /// buffer that we are currently writing to.
+  uintptr_t getCurrentPCOffset() const {
+    return Data.size();
+  }
+
+  /// addRelocation - Whenever a relocatable address is needed, it should be
+  /// noted with this interface.
+  void addRelocation(const MachineRelocation& relocation) {
+    Relocations.push_back(relocation);
+  }
+};
+
+} // end namespace llvm
+
+#endif
+

Modified: llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h Sun Jun 14 02:53:21 2009
@@ -29,6 +29,7 @@
     // e_machine member of the ELF header.
     unsigned short EMachine;
     TargetMachine &TM;
+    bool is64Bit, isLittleEndian;
   public:
 
     // Machine architectures
@@ -49,10 +50,35 @@
       EM_X86_64 = 62   // AMD64
     };
 
+    // ELF File classes
+    enum {
+      ELFCLASS32 = 1, // 32-bit object file
+      ELFCLASS64 = 2  // 64-bit object file
+    };
+
+    // ELF Endianess
+    enum {
+      ELFDATA2LSB = 1, // Little-endian object file
+      ELFDATA2MSB = 2  // Big-endian object file
+    };
+
     explicit TargetELFWriterInfo(TargetMachine &tm);
     virtual ~TargetELFWriterInfo();
 
     unsigned short getEMachine() const { return EMachine; }
+    unsigned getEFlags() const { return 0; }
+    unsigned getEIClass() const { return is64Bit ? ELFCLASS64 : ELFCLASS32; }
+    unsigned getEIData() const {
+      return isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
+    }
+
+    /// ELF Header and ELF Section Header Info
+    unsigned getHdrSize() const { return is64Bit ? 64 : 52; }
+    unsigned getSHdrSize() const { return is64Bit ? 64 : 40; }
+
+    /// Symbol Table Info
+    unsigned getSymTabEntrySize() const { return is64Bit ? 24 : 16; }
+    unsigned getSymTabAlignment() const { return is64Bit ? 8 : 4; }
 
     /// getFunctionAlignment - Returns the alignment for function 'F', targets
     /// with different alignment constraints should overload this method

Modified: llvm/trunk/lib/CodeGen/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELF.h?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELF.h (original)
+++ llvm/trunk/lib/CodeGen/ELF.h Sun Jun 14 02:53:21 2009
@@ -10,11 +10,10 @@
 // This header contains common, non-processor-specific data structures and
 // constants for the ELF file format.
 //
-// The details of the ELF32 bits in this file are largely based on
-// the Tool Interface Standard (TIS) Executable and Linking Format
-// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
-// standardized, as far as I can tell. It was largely based on information
-// I found in OpenBSD header files.
+// The details of the ELF32 bits in this file are largely based on the Tool
+// Interface Standard (TIS) Executable and Linking Format (ELF) Specification
+// Version 1.2, May 1995. The ELF64 is based on HP/Intel definition of the
+// ELF-64 object file format document, Version 1.5 Draft 2 May 27, 1998
 //
 //===----------------------------------------------------------------------===//
 
@@ -22,11 +21,13 @@
 #define CODEGEN_ELF_H
 
 #include "llvm/GlobalVariable.h"
+#include "llvm/CodeGen/BinaryObject.h"
 #include "llvm/CodeGen/MachineRelocation.h"
 #include "llvm/Support/DataTypes.h"
 #include <cstring>
 
 namespace llvm {
+  class BinaryObject;
 
   // Identification Indexes
   enum {
@@ -47,62 +48,17 @@
     ET_HIPROC = 0xffff  // Processor-specific
   };
 
-  // Object file classes.
-  enum {
-    ELFCLASS32 = 1, // 32-bit object file
-    ELFCLASS64 = 2  // 64-bit object file
-  };
-
-  // Object file byte orderings.
-  enum {
-    ELFDATA2LSB = 1, // Little-endian object file
-    ELFDATA2MSB = 2  // Big-endian object file
-  };
-
   // Versioning
   enum {
     EV_NONE = 0,
     EV_CURRENT = 1
   };
 
-  struct ELFHeader {
-    // e_machine - This field is the target specific value to emit as the
-    // e_machine member of the ELF header.
-    unsigned short e_machine;
-
-    // e_flags - The machine flags for the target.  This defaults to zero.
-    unsigned e_flags;
-
-    // e_size - Holds the ELF header's size in bytes
-    unsigned e_ehsize;
-
-    // Endianess and ELF Class (64 or 32 bits)
-    unsigned ByteOrder;
-    unsigned ElfClass;
-
-    unsigned getByteOrder() const { return ByteOrder; }
-    unsigned getElfClass() const { return ElfClass; }
-    unsigned getSize() const { return e_ehsize; }
-    unsigned getMachine() const { return e_machine; }
-    unsigned getFlags() const { return e_flags; }
-
-    ELFHeader(unsigned short machine, unsigned flags,
-              bool is64Bit, bool isLittleEndian)
-      : e_machine(machine), e_flags(flags) {
-        ElfClass  = is64Bit ? ELFCLASS64 : ELFCLASS32;
-        ByteOrder = isLittleEndian ? ELFDATA2LSB : ELFDATA2MSB;
-        e_ehsize  = is64Bit ? 64 : 52;
-      }
-  };
-
   /// ELFSection - This struct contains information about each section that is
   /// emitted to the file.  This is eventually turned into the section header
   /// table at the end of the file.
-  struct ELFSection {
-
-    // Name of the section
-    std::string Name;
-
+  class ELFSection : public BinaryObject {
+    public:
     // ELF specific fields
     unsigned NameIdx;   // sh_name - .shstrtab idx of name, once emitted.
     unsigned Type;      // sh_type - Section contents & semantics 
@@ -143,8 +99,8 @@
       SHT_REL      = 9,  // Relocation entries; no explicit addends.
       SHT_SHLIB    = 10, // Reserved.
       SHT_DYNSYM   = 11, // Symbol table.
-      SHT_LOPROC   = 0x70000000, // Lowest processor architecture-specific type.
-      SHT_HIPROC   = 0x7fffffff, // Highest processor architecture-specific type.
+      SHT_LOPROC   = 0x70000000, // Lowest processor arch-specific type.
+      SHT_HIPROC   = 0x7fffffff, // Highest processor arch-specific type.
       SHT_LOUSER   = 0x80000000, // Lowest type reserved for applications.
       SHT_HIUSER   = 0xffffffff  // Highest type reserved for applications.
     };
@@ -163,22 +119,9 @@
     /// SectionIdx - The number of the section in the Section Table.
     unsigned short SectionIdx;
 
-    /// SectionData - The actual data for this section which we are building
-    /// up for emission to the file.
-    std::vector<unsigned char> SectionData;
-
-    /// Relocations - The relocations that we have encountered so far in this 
-    /// section that we will need to convert to Elf relocation entries when
-    /// the file is written.
-    std::vector<MachineRelocation> Relocations;
-
-    /// Section Header Size 
-    static unsigned getSectionHdrSize(bool is64Bit)
-      { return is64Bit ? 64 : 40; }
-
-    ELFSection(const std::string &name)
-      : Name(name), Type(0), Flags(0), Addr(0), Offset(0), Size(0),
-        Link(0), Info(0), Align(0), EntSize(0) {}
+    ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit)
+      : BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0),
+        Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0) {}
   };
 
   /// ELFSym - This struct contains information about each symbol that is
@@ -245,9 +188,6 @@
       assert(X == (X & 0xF) && "Type value out of range!");
       Info = (Info & 0xF0) | X;
     }
-
-    static unsigned getEntrySize(bool is64Bit)
-      { return is64Bit ? 24 : 16; }
   };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp Sun Jun 14 02:53:21 2009
@@ -13,6 +13,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/CodeGen/BinaryObject.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/Target/TargetMachine.h"
@@ -33,9 +34,10 @@
   DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
 
   // FIXME: better memory management, this will be replaced by BinaryObjects
-  ES->SectionData.reserve(4096);
-  BufferBegin = &ES->SectionData[0];
-  BufferEnd = BufferBegin + ES->SectionData.capacity();
+  BinaryData &BD = ES->getData();
+  BD.reserve(4096);
+  BufferBegin = &BD[0];
+  BufferEnd = BufferBegin + BD.capacity();
 
   // Align the output buffer with function alignment, and
   // upgrade the section alignment if required
@@ -100,7 +102,7 @@
   FnSym.Value = FnStartPtr-BufferBegin;
 
   // Finally, add it to the symtab.
-  EW.SymbolTable.push_back(FnSym);
+  EW.SymbolList.push_back(FnSym);
 
   // Relocations
   // -----------
@@ -121,7 +123,7 @@
     } else {
       assert(0 && "Unhandled relocation type");
     }
-    ES->Relocations.push_back(MR);
+    ES->addRelocation(MR);
   }
   Relocations.clear();
 

Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Sun Jun 14 02:53:21 2009
@@ -37,6 +37,7 @@
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/CodeGen/BinaryObject.h"
 #include "llvm/CodeGen/FileWriters.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
@@ -66,22 +67,23 @@
 //===----------------------------------------------------------------------===//
 
 ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
-  : MachineFunctionPass(&ID), O(o), TM(tm), ElfHdr() {
-  is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
-  isLittleEndian = TM.getTargetData()->isLittleEndian();
+  : MachineFunctionPass(&ID), O(o), TM(tm),
+    is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64),
+    isLittleEndian(TM.getTargetData()->isLittleEndian()),
+    ElfHdr(isLittleEndian, is64Bit) {
 
-  ElfHdr = new ELFHeader(TM.getELFWriterInfo()->getEMachine(), 0,
-                         is64Bit, isLittleEndian);
   TAI = TM.getTargetAsmInfo();
+  TEW = TM.getELFWriterInfo();
 
   // Create the machine code emitter object for this target.
   MCE = new ELFCodeEmitter(*this);
+
+  // Inital number of sections
   NumSections = 0;
 }
 
 ELFWriter::~ELFWriter() {
   delete MCE;
-  delete ElfHdr;
 }
 
 // doInitialization - Emit the file header and all of the global variables for
@@ -89,10 +91,6 @@
 bool ELFWriter::doInitialization(Module &M) {
   Mang = new Mangler(M);
 
-  // Local alias to shortenify coming code.
-  std::vector<unsigned char> &FH = FileHeader;
-  OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
-
   // ELF Header
   // ----------
   // Fields e_shnum e_shstrndx are only known after all section have
@@ -101,49 +99,48 @@
   //
   // Note
   // ----
-  // FHOut.outaddr method behaves differently for ELF32 and ELF64 writing
+  // emitWord method behaves differently for ELF32 and ELF64, writing
   // 4 bytes in the former and 8 in the last for *_off and *_addr elf types
 
-  FHOut.outbyte(0x7f); // e_ident[EI_MAG0]
-  FHOut.outbyte('E');  // e_ident[EI_MAG1]
-  FHOut.outbyte('L');  // e_ident[EI_MAG2]
-  FHOut.outbyte('F');  // e_ident[EI_MAG3]
-
-  FHOut.outbyte(ElfHdr->getElfClass());   // e_ident[EI_CLASS]
-  FHOut.outbyte(ElfHdr->getByteOrder());  // e_ident[EI_DATA]
-  FHOut.outbyte(EV_CURRENT);  // e_ident[EI_VERSION]
-
-  FH.resize(16);  // e_ident[EI_NIDENT-EI_PAD]
-
-  FHOut.outhalf(ET_REL);               // e_type
-  FHOut.outhalf(ElfHdr->getMachine()); // e_machine = target
-  FHOut.outword(EV_CURRENT);           // e_version
-  FHOut.outaddr(0);                    // e_entry = 0, no entry point in .o file
-  FHOut.outaddr(0);                    // e_phoff = 0, no program header for .o
-  ELFHdr_e_shoff_Offset = FH.size();
-  FHOut.outaddr(0);                    // e_shoff = sec hdr table off in bytes
-  FHOut.outword(ElfHdr->getFlags());   // e_flags = whatever the target wants
-  FHOut.outhalf(ElfHdr->getSize());    // e_ehsize = ELF header size
-  FHOut.outhalf(0);                    // e_phentsize = prog header entry size
-  FHOut.outhalf(0);                    // e_phnum = # prog header entries = 0
+  ElfHdr.emitByte(0x7f); // e_ident[EI_MAG0]
+  ElfHdr.emitByte('E');  // e_ident[EI_MAG1]
+  ElfHdr.emitByte('L');  // e_ident[EI_MAG2]
+  ElfHdr.emitByte('F');  // e_ident[EI_MAG3]
+
+  ElfHdr.emitByte(TEW->getEIClass()); // e_ident[EI_CLASS]
+  ElfHdr.emitByte(TEW->getEIData());  // e_ident[EI_DATA]
+  ElfHdr.emitByte(EV_CURRENT);        // e_ident[EI_VERSION]
+  ElfHdr.emitAlignment(16);           // e_ident[EI_NIDENT-EI_PAD]
+
+  ElfHdr.emitWord16(ET_REL);             // e_type
+  ElfHdr.emitWord16(TEW->getEMachine()); // e_machine = target
+  ElfHdr.emitWord32(EV_CURRENT);         // e_version
+  ElfHdr.emitWord(0);                    // e_entry, no entry point in .o file
+  ElfHdr.emitWord(0);                    // e_phoff, no program header for .o
+  ELFHdr_e_shoff_Offset = ElfHdr.size();
+  ElfHdr.emitWord(0);                    // e_shoff = sec hdr table off in bytes
+  ElfHdr.emitWord32(TEW->getEFlags());   // e_flags = whatever the target wants
+  ElfHdr.emitWord16(TEW->getHdrSize());  // e_ehsize = ELF header size
+  ElfHdr.emitWord16(0);                  // e_phentsize = prog header entry size
+  ElfHdr.emitWord16(0);                  // e_phnum = # prog header entries = 0
 
   // e_shentsize = Section header entry size
-  FHOut.outhalf(ELFSection::getSectionHdrSize(is64Bit));
+  ElfHdr.emitWord16(TEW->getSHdrSize());
 
   // e_shnum     = # of section header ents
-  ELFHdr_e_shnum_Offset = FH.size();
-  FHOut.outhalf(0);
+  ELFHdr_e_shnum_Offset = ElfHdr.size();
+  ElfHdr.emitWord16(0); // Placeholder
 
   // e_shstrndx  = Section # of '.shstrtab'
-  ELFHdr_e_shstrndx_Offset = FH.size();
-  FHOut.outhalf(0);
+  ELFHdr_e_shstrndx_Offset = ElfHdr.size();
+  ElfHdr.emitWord16(0); // Placeholder
 
   // Add the null section, which is required to be first in the file.
   getSection("", ELFSection::SHT_NULL, 0);
 
-  // Start up the symbol table.  The first entry in the symtab is the null
+  // Start up the symbol table.  The first entry in the symtab is the null 
   // entry.
-  SymbolTable.push_back(ELFSym(0));
+  SymbolList.push_back(ELFSym(0));
 
   return false;
 }
@@ -162,7 +159,7 @@
     ExternalSym.SetBind(ELFSym::STB_GLOBAL);
     ExternalSym.SetType(ELFSym::STT_NOTYPE);
     ExternalSym.SectionIdx = ELFSection::SHN_UNDEF;
-    SymbolTable.push_back(ExternalSym);
+    SymbolList.push_back(ExternalSym);
     return;
   }
 
@@ -185,7 +182,7 @@
       CommonSym.SetBind(ELFSym::STB_GLOBAL);
       CommonSym.SetType(ELFSym::STT_OBJECT);
       CommonSym.SectionIdx = ELFSection::SHN_COMMON;
-      SymbolTable.push_back(CommonSym);
+      SymbolList.push_back(CommonSym);
       getSection(S->getName(), ELFSection::SHT_NOBITS,
         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC, 1);
       return;
@@ -222,7 +219,7 @@
     // Set the idx of the .bss section
     BSSSym.SectionIdx = BSSSection.SectionIdx;
     if (!GV->hasPrivateLinkage())
-      SymbolTable.push_back(BSSSym);
+      SymbolList.push_back(BSSSym);
 
     // Reserve space in the .bss section for this symbol.
     BSSSection.Size += Size;
@@ -262,21 +259,18 @@
   if (Align > ElfS.Align)
     ElfS.Align = Align;
 
-  DataBuffer &GblCstBuf = ElfS.SectionData;
-  OutputBuffer GblCstTab(GblCstBuf, is64Bit, isLittleEndian);
-
   // S.Value should contain the symbol index inside the section,
   // and all symbols should start on their required alignment boundary
-  GblSym.Value = (GblCstBuf.size() + (Align-1)) & (-Align);
-  GblCstBuf.insert(GblCstBuf.end(), GblSym.Value-GblCstBuf.size(), 0);
+  GblSym.Value = (ElfS.size() + (Align-1)) & (-Align);
+  ElfS.emitAlignment(Align);
 
   // Emit the constant symbol to its section
-  EmitGlobalConstant(CV, GblCstTab);
-  SymbolTable.push_back(GblSym);
+  EmitGlobalConstant(CV, ElfS);
+  SymbolList.push_back(GblSym);
 }
 
 void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
-                                         OutputBuffer &GblCstTab) {
+                                         ELFSection &GblS) {
 
   // Print the fields in successive locations. Pad to align if needed!
   const TargetData *TD = TM.getTargetData();
@@ -293,40 +287,40 @@
     sizeSoFar += fieldSize + padSize;
 
     // Now print the actual field value.
-    EmitGlobalConstant(field, GblCstTab);
+    EmitGlobalConstant(field, GblS);
 
     // Insert padding - this may include padding to increase the size of the
     // current field up to the ABI size (if the struct is not packed) as well
     // as padding to ensure that the next field starts at the right offset.
     for (unsigned p=0; p < padSize; p++)
-      GblCstTab.outbyte(0);
+      GblS.emitByte(0);
   }
   assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
          "Layout of constant struct may be incorrect!");
 }
 
-void ELFWriter::EmitGlobalConstant(const Constant *CV, OutputBuffer &GblCstTab) {
+void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) {
   const TargetData *TD = TM.getTargetData();
   unsigned Size = TD->getTypeAllocSize(CV->getType());
 
   if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
     if (CVA->isString()) {
       std::string GblStr = CVA->getAsString();
-      GblCstTab.outstring(GblStr, GblStr.length());
+      GblS.emitString(GblStr);
     } else { // Not a string.  Print the values in successive locations
       for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
-        EmitGlobalConstant(CVA->getOperand(i), GblCstTab);
+        EmitGlobalConstant(CVA->getOperand(i), GblS);
     }
     return;
   } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
-    EmitGlobalConstantStruct(CVS, GblCstTab);
+    EmitGlobalConstantStruct(CVS, GblS);
     return;
   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
     uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
     if (CFP->getType() == Type::DoubleTy)
-      GblCstTab.outxword(Val);
+      GblS.emitWord64(Val);
     else if (CFP->getType() == Type::FloatTy)
-      GblCstTab.outword(Val);
+      GblS.emitWord32(Val);
     else if (CFP->getType() == Type::X86_FP80Ty) {
       assert(0 && "X86_FP80Ty global emission not implemented");
     } else if (CFP->getType() == Type::PPC_FP128Ty)
@@ -334,16 +328,16 @@
     return;
   } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
     if (Size == 4)
-      GblCstTab.outword(CI->getZExtValue());
+      GblS.emitWord32(CI->getZExtValue());
     else if (Size == 8)
-      GblCstTab.outxword(CI->getZExtValue());
+      GblS.emitWord64(CI->getZExtValue());
     else
       assert(0 && "LargeInt global emission not implemented");
     return;
   } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
     const VectorType *PTy = CP->getType();
     for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
-      EmitGlobalConstant(CP->getOperand(I), GblCstTab);
+      EmitGlobalConstant(CP->getOperand(I), GblS);
     return;
   }
   assert(0 && "unknown global constant");
@@ -358,26 +352,30 @@
 /// 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 BinaryObjects. Since the
-  /// current ELFCodeEmiter uses CurrBuff, ... it doesn't update S.SectionData
+  /// 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)
+  if (TS.Size) {
+    BinaryData &BD = TS.getData();
     for (unsigned e=0; e<TS.Size; ++e)
-      TS.SectionData.push_back(TS.SectionData[e]);
+      BD.push_back(BD[e]);
+  }
 
-  // Get .data and .bss section, they should always be present in the binary
+  // Emit .data section placeholder
   getDataSection();
+
+  // Emit .bss section placeholder
   getBSSSection();
 
-  // build data, bss and "common" sections.
+  // Build and emit data, bss and "common" sections.
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I)
     EmitGlobal(I);
 
   // Emit non-executable stack note
   if (TAI->getNonexecutableStackDirective())
-    getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
+    getNonExecStackSection();
 
   // Emit the symbol table now, if non-empty.
   EmitSymbolTable();
@@ -385,10 +383,10 @@
   // Emit the relocation sections.
   EmitRelocations();
 
-  // Emit the string table for the sections in the ELF file.
+  // Emit the sections string table.
   EmitSectionTableStringTable();
 
-  // Emit the sections to the .o file, and emit the section table for the file.
+  // Dump the sections and section table to the .o file.
   OutputSectionsAndSectionTable();
 
   // We are done with the abstract symbols.
@@ -404,106 +402,97 @@
 void ELFWriter::EmitRelocations() {
 }
 
-/// EmitSymbol - Write symbol 'Sym' to the symbol table 'SymTabOut'
-void ELFWriter::EmitSymbol(OutputBuffer &SymTabOut, ELFSym &Sym) {
+/// EmitSymbol - Write symbol 'Sym' to the symbol table 'SymbolTable'
+void ELFWriter::EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym) {
   if (is64Bit) {
-    SymTabOut.outword(Sym.NameIdx);
-    SymTabOut.outbyte(Sym.Info);
-    SymTabOut.outbyte(Sym.Other);
-    SymTabOut.outhalf(Sym.SectionIdx);
-    SymTabOut.outaddr64(Sym.Value);
-    SymTabOut.outxword(Sym.Size);
+    SymbolTable.emitWord32(Sym.NameIdx);
+    SymbolTable.emitByte(Sym.Info);
+    SymbolTable.emitByte(Sym.Other);
+    SymbolTable.emitWord16(Sym.SectionIdx);
+    SymbolTable.emitWord64(Sym.Value);
+    SymbolTable.emitWord64(Sym.Size);
   } else {
-    SymTabOut.outword(Sym.NameIdx);
-    SymTabOut.outaddr32(Sym.Value);
-    SymTabOut.outword(Sym.Size);
-    SymTabOut.outbyte(Sym.Info);
-    SymTabOut.outbyte(Sym.Other);
-    SymTabOut.outhalf(Sym.SectionIdx);
+    SymbolTable.emitWord32(Sym.NameIdx);
+    SymbolTable.emitWord32(Sym.Value);
+    SymbolTable.emitWord32(Sym.Size);
+    SymbolTable.emitByte(Sym.Info);
+    SymbolTable.emitByte(Sym.Other);
+    SymbolTable.emitWord16(Sym.SectionIdx);
   }
 }
 
-/// EmitSectionHeader - Write section 'Section' header in 'TableOut'
+/// EmitSectionHeader - Write section 'Section' header in 'SHdrTab'
 /// Section Header Table
-void ELFWriter::EmitSectionHeader(OutputBuffer &TableOut, const ELFSection &S) {
-  TableOut.outword(S.NameIdx);
-  TableOut.outword(S.Type);
+void ELFWriter::EmitSectionHeader(BinaryObject &SHdrTab, 
+                                  const ELFSection &SHdr) {
+  SHdrTab.emitWord32(SHdr.NameIdx);
+  SHdrTab.emitWord32(SHdr.Type);
   if (is64Bit) {
-    TableOut.outxword(S.Flags);
-    TableOut.outaddr(S.Addr);
-    TableOut.outaddr(S.Offset);
-    TableOut.outxword(S.Size);
-    TableOut.outword(S.Link);
-    TableOut.outword(S.Info);
-    TableOut.outxword(S.Align);
-    TableOut.outxword(S.EntSize);
+    SHdrTab.emitWord64(SHdr.Flags);
+    SHdrTab.emitWord(SHdr.Addr);
+    SHdrTab.emitWord(SHdr.Offset);
+    SHdrTab.emitWord64(SHdr.Size);
+    SHdrTab.emitWord32(SHdr.Link);
+    SHdrTab.emitWord32(SHdr.Info);
+    SHdrTab.emitWord64(SHdr.Align);
+    SHdrTab.emitWord64(SHdr.EntSize);
   } else {
-    TableOut.outword(S.Flags);
-    TableOut.outaddr(S.Addr);
-    TableOut.outaddr(S.Offset);
-    TableOut.outword(S.Size);
-    TableOut.outword(S.Link);
-    TableOut.outword(S.Info);
-    TableOut.outword(S.Align);
-    TableOut.outword(S.EntSize);
+    SHdrTab.emitWord32(SHdr.Flags);
+    SHdrTab.emitWord(SHdr.Addr);
+    SHdrTab.emitWord(SHdr.Offset);
+    SHdrTab.emitWord32(SHdr.Size);
+    SHdrTab.emitWord32(SHdr.Link);
+    SHdrTab.emitWord32(SHdr.Info);
+    SHdrTab.emitWord32(SHdr.Align);
+    SHdrTab.emitWord32(SHdr.EntSize);
   }
 }
 
 /// EmitSymbolTable - If the current symbol table is non-empty, emit the string
 /// table for it and then the symbol table itself.
 void ELFWriter::EmitSymbolTable() {
-  if (SymbolTable.size() == 1) return;  // Only the null entry.
+  if (SymbolList.size() == 1) return;  // Only the null entry.
 
   // FIXME: compact all local symbols to the start of the symtab.
   unsigned FirstNonLocalSymbol = 1;
 
   ELFSection &StrTab = getStringTableSection();
-  DataBuffer &StrTabBuf = StrTab.SectionData;
-  OutputBuffer StrTabOut(StrTabBuf, is64Bit, isLittleEndian);
 
   // Set the zero'th symbol to a null byte, as required.
-  StrTabOut.outbyte(0);
+  StrTab.emitByte(0);
 
   unsigned Index = 1;
-  for (unsigned i = 1, e = SymbolTable.size(); i != e; ++i) {
+  for (unsigned i = 1, e = SymbolList.size(); i != e; ++i) {
     // Use the name mangler to uniquify the LLVM symbol.
-    std::string Name = Mang->getValueName(SymbolTable[i].GV);
+    std::string Name = Mang->getValueName(SymbolList[i].GV);
 
     if (Name.empty()) {
-      SymbolTable[i].NameIdx = 0;
+      SymbolList[i].NameIdx = 0;
     } else {
-      SymbolTable[i].NameIdx = Index;
-
-      // Add the name to the output buffer, including the null terminator.
-      StrTabBuf.insert(StrTabBuf.end(), Name.begin(), Name.end());
-
-      // Add a null terminator.
-      StrTabBuf.push_back(0);
+      SymbolList[i].NameIdx = Index;
+      StrTab.emitString(Name);
 
       // Keep track of the number of bytes emitted to this section.
       Index += Name.size()+1;
     }
   }
-  assert(Index == StrTabBuf.size());
+  assert(Index == StrTab.size());
   StrTab.Size = Index;
 
   // Now that we have emitted the string table and know the offset into the
   // string table of each symbol, emit the symbol table itself.
   ELFSection &SymTab = getSymbolTableSection();
-  SymTab.Align = is64Bit ? 8 : 4;
-  SymTab.Link = StrTab.SectionIdx;      // Section Index of .strtab.
-  SymTab.Info = FirstNonLocalSymbol;    // First non-STB_LOCAL symbol.
+  SymTab.Align = TEW->getSymTabAlignment();
+  SymTab.Link  = StrTab.SectionIdx;      // Section Index of .strtab.
+  SymTab.Info  = FirstNonLocalSymbol;    // First non-STB_LOCAL symbol.
 
   // Size of each symtab entry.
-  SymTab.EntSize = ELFSym::getEntrySize(is64Bit);
-
-  DataBuffer &SymTabBuf = SymTab.SectionData;
-  OutputBuffer SymTabOut(SymTabBuf, is64Bit, isLittleEndian);
+  SymTab.EntSize = TEW->getSymTabEntrySize();
 
-  for (unsigned i = 0, e = SymbolTable.size(); i != e; ++i)
-    EmitSymbol(SymTabOut, SymbolTable[i]);
+  for (unsigned i = 0, e = SymbolList.size(); i != e; ++i)
+    EmitSymbol(SymTab, SymbolList[i]);
 
-  SymTab.Size = SymTabBuf.size();
+  SymTab.Size = SymTab.size();
 }
 
 /// EmitSectionTableStringTable - This method adds and emits a section for the
@@ -515,32 +504,25 @@
 
   // Now that we know which section number is the .shstrtab section, update the
   // e_shstrndx entry in the ELF header.
-  OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
-  FHOut.fixhalf(SHStrTab.SectionIdx, ELFHdr_e_shstrndx_Offset);
+  ElfHdr.fixWord16(SHStrTab.SectionIdx, ELFHdr_e_shstrndx_Offset);
 
   // Set the NameIdx of each section in the string table and emit the bytes for
   // the string table.
   unsigned Index = 0;
-  DataBuffer &Buf = SHStrTab.SectionData;
 
   for (std::list<ELFSection>::iterator I = SectionList.begin(),
          E = SectionList.end(); I != E; ++I) {
     // Set the index into the table.  Note if we have lots of entries with
     // common suffixes, we could memoize them here if we cared.
     I->NameIdx = Index;
-
-    // Add the name to the output buffer, including the null terminator.
-    Buf.insert(Buf.end(), I->Name.begin(), I->Name.end());
-
-    // Add a null terminator.
-    Buf.push_back(0);
+    SHStrTab.emitString(I->getName());
 
     // Keep track of the number of bytes emitted to this section.
-    Index += I->Name.size()+1;
+    Index += I->getName().size()+1;
   }
 
   // Set the size of .shstrtab now that we know what it is.
-  assert(Index == Buf.size());
+  assert(Index == SHStrTab.size());
   SHStrTab.Size = Index;
 }
 
@@ -549,7 +531,7 @@
 /// SectionTable.
 void ELFWriter::OutputSectionsAndSectionTable() {
   // Pass #1: Compute the file offset for each section.
-  size_t FileOff = FileHeader.size();   // File header first.
+  size_t FileOff = ElfHdr.size();   // File header first.
 
   // Adjust alignment of all section if needed.
   for (std::list<ELFSection>::iterator I = SectionList.begin(),
@@ -559,14 +541,14 @@
     if (!I->SectionIdx)
       continue;
 
-    if (!I->SectionData.size()) {
+    if (!I->size()) {
       I->Offset = FileOff;
       continue;
     }
 
     // Update Section size
     if (!I->Size)
-      I->Size = I->SectionData.size();
+      I->Size = I->size();
 
     // Align FileOff to whatever the alignment restrictions of the section are.
     if (I->Align)
@@ -582,43 +564,40 @@
 
   // Now that we know where all of the sections will be emitted, set the e_shnum
   // entry in the ELF header.
-  OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
-  FHOut.fixhalf(NumSections, ELFHdr_e_shnum_Offset);
+  ElfHdr.fixWord16(NumSections, ELFHdr_e_shnum_Offset);
 
   // Now that we know the offset in the file of the section table, update the
   // e_shoff address in the ELF header.
-  FHOut.fixaddr(FileOff, ELFHdr_e_shoff_Offset);
+  ElfHdr.fixWord(FileOff, ELFHdr_e_shoff_Offset);
 
   // Now that we know all of the data in the file header, emit it and all of the
   // sections!
-  O.write((char*)&FileHeader[0], FileHeader.size());
-  FileOff = FileHeader.size();
-  DataBuffer().swap(FileHeader);
+  O.write((char *)&ElfHdr.getData()[0], ElfHdr.size());
+  FileOff = ElfHdr.size();
 
-  DataBuffer Table;
-  OutputBuffer TableOut(Table, is64Bit, isLittleEndian);
+  // Section Header Table blob
+  BinaryObject SHdrTable(isLittleEndian, is64Bit);
 
-  // Emit all of the section data and build the section table itself.
+  // Emit all of sections to the file and build the section header table.
   while (!SectionList.empty()) {
-    const ELFSection &S = *SectionList.begin();
-    DOUT << "SectionIdx: " << S.SectionIdx << ", Name: " << S.Name
+    ELFSection &S = *SectionList.begin();
+    DOUT << "SectionIdx: " << S.SectionIdx << ", Name: " << S.getName()
          << ", Size: " << S.Size << ", Offset: " << S.Offset
-         << ", SectionData Size: " << S.SectionData.size() << "\n";
-
+         << ", SectionData Size: " << S.size() << "\n";
 
     // Align FileOff to whatever the alignment restrictions of the section are.
     if (S.Align) {
       for (size_t NewFileOff = (FileOff+S.Align-1) & ~(S.Align-1);
-           FileOff != NewFileOff; ++FileOff)
+        FileOff != NewFileOff; ++FileOff)
         O << (char)0xAB;
     }
 
-    if (S.SectionData.size()) {
-      O.write((char*)&S.SectionData[0], S.Size);
+    if (S.size()) {
+      O.write((char *)&S.getData()[0], S.Size);
       FileOff += S.Size;
     }
 
-    EmitSectionHeader(TableOut, S);
+    EmitSectionHeader(SHdrTable, S);
     SectionList.pop_front();
   }
 
@@ -628,5 +607,5 @@
     O << (char)0xAB;
 
   // Emit the section table itself.
-  O.write((char*)&Table[0], Table.size());
+  O.write((char *)&SHdrTable.getData()[0], SHdrTable.size());
 }

Modified: llvm/trunk/lib/CodeGen/ELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.h?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.h Sun Jun 14 02:53:21 2009
@@ -24,6 +24,7 @@
 #include <map>
 
 namespace llvm {
+  class BinaryObject;
   class ConstantStruct;
   class ELFCodeEmitter;
   class GlobalVariable;
@@ -56,6 +57,9 @@
     /// Target machine description.
     TargetMachine &TM;
 
+    /// Target Elf Writer description.
+    const TargetELFWriterInfo *TEW;
+
     /// Mang - The object used to perform name mangling for this module.
     Mangler *Mang;
 
@@ -85,13 +89,8 @@
     bool doFinalization(Module &M);
 
   private:
-    // The buffer we accumulate the file header into.  Note that this should be
-    // changed into something much more efficient later (and the bitcode writer
-    // as well!).
-    DataBuffer FileHeader;
-
-    /// ElfHdr - Hold information about the ELF Header
-    ELFHeader *ElfHdr;
+    // Blob containing the Elf header
+    BinaryObject ElfHdr;
 
     /// SectionList - This is the list of sections that we have emitted to the
     /// file.  Once the file has been completely built, the section header table
@@ -110,7 +109,7 @@
       ELFSection *&SN = SectionLookup[Name];
       if (SN) return *SN;
 
-      SectionList.push_back(Name);
+      SectionList.push_back(ELFSection(Name, isLittleEndian, is64Bit));
       SN = &SectionList.back();
       SN->SectionIdx = NumSections++;
       SN->Type = Type;
@@ -125,6 +124,10 @@
                         ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
     }
 
+    ELFSection &getNonExecStackSection() {
+      return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
+    }
+
     ELFSection &getSymbolTableSection() {
       return getSection(".symtab", ELFSection::SHT_SYMTAB, 0);
     }
@@ -143,14 +146,14 @@
                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
     }
 
-    /// SymbolTable - This is the list of symbols we have emitted to the file.
+    /// SymbolList - This is the list of symbols we have emitted to the file.
     /// This actually gets rearranged before emission to the file (to put the
     /// local symbols first in the list).
-    std::vector<ELFSym> SymbolTable;
+    std::vector<ELFSym> SymbolList;
 
-    /// PendingSyms - This is a list of externally defined symbols that we have
-    /// been asked to emit, but have not seen a reference to.  When a reference
-    /// is seen, the symbol will move from this list to the SymbolTable.
+    /// PendingGlobals - List of externally defined symbols that we have been
+    /// asked to emit, but have not seen a reference to.  When a reference
+    /// is seen, the symbol will move from this list to the SymbolList.
     SetVector<GlobalValue*> PendingGlobals;
 
     // As we complete the ELF file, we need to update fields in the ELF header
@@ -160,15 +163,16 @@
     unsigned ELFHdr_e_shoff_Offset;     // e_shoff    in ELF header.
     unsigned ELFHdr_e_shstrndx_Offset;  // e_shstrndx in ELF header.
     unsigned ELFHdr_e_shnum_Offset;     // e_shnum    in ELF header.
+
   private:
     void EmitGlobal(GlobalVariable *GV);
-    void EmitGlobalConstant(const Constant *C, OutputBuffer &GblCstTab);
+    void EmitGlobalConstant(const Constant *C, ELFSection &GblS);
     void EmitGlobalConstantStruct(const ConstantStruct *CVS,
-                                  OutputBuffer &GblCstTab);
+                                  ELFSection &GblS);
     void EmitRelocations();
-    void EmitSectionHeader(OutputBuffer &TableOut, const ELFSection &Section);
+    void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr);
     void EmitSectionTableStringTable();
-    void EmitSymbol(OutputBuffer &SymTabOut, ELFSym &Sym);
+    void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym);
     void EmitSymbolTable();
     void OutputSectionsAndSectionTable();
   };

Modified: llvm/trunk/lib/Target/TargetELFWriterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetELFWriterInfo.cpp?rev=73333&r1=73332&r2=73333&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetELFWriterInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetELFWriterInfo.cpp Sun Jun 14 02:53:21 2009
@@ -17,7 +17,10 @@
 #include "llvm/Target/TargetMachine.h"
 using namespace llvm;
 
-TargetELFWriterInfo::TargetELFWriterInfo(TargetMachine &tm) : TM(tm) {}
+TargetELFWriterInfo::TargetELFWriterInfo(TargetMachine &tm) : TM(tm) {
+  is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
+  isLittleEndian = TM.getTargetData()->isLittleEndian();
+}
 
 TargetELFWriterInfo::~TargetELFWriterInfo() {}
 





More information about the llvm-commits mailing list