New "TargetObjInfo" class. This holds information that the object writers will
authorBill Wendling <isanbard@gmail.com>
Wed, 17 Jan 2007 03:46:30 +0000 (03:46 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 17 Jan 2007 03:46:30 +0000 (03:46 +0000)
use to write things to the file. It's abstract so each target should implement
its own version for each writer type.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33286 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetObjInfo.h [new file with mode: 0644]
lib/Target/PowerPC/PPCTargetObjInfo.cpp [new file with mode: 0644]
lib/Target/PowerPC/PPCTargetObjInfo.h [new file with mode: 0644]
lib/Target/X86/X86TargetObjInfo.cpp [new file with mode: 0644]
lib/Target/X86/X86TargetObjInfo.h [new file with mode: 0644]

diff --git a/include/llvm/Target/TargetObjInfo.h b/include/llvm/Target/TargetObjInfo.h
new file mode 100644 (file)
index 0000000..ffad354
--- /dev/null
@@ -0,0 +1,57 @@
+//===-- llvm/Target/TargetObjInfo.h - Object File Info ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the basis for target specific object
+// writers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_OBJ_INFO_H
+#define LLVM_TARGET_OBJ_INFO_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+  struct TargetObjInfo {
+    TargetObjInfo() {}
+    virtual ~TargetObjInfo() {}
+
+    typedef std::vector<unsigned char> DataBuffer;
+
+    virtual void align(DataBuffer &Output, unsigned Boundary) const = 0;
+
+    //===------------------------------------------------------------------===//
+    // Out Functions - Output the specified value to the data buffer.
+
+    virtual void outbyte(DataBuffer &Output, unsigned char X) const = 0;
+    virtual void outhalf(DataBuffer &Output, unsigned short X) const = 0;
+    virtual void outword(DataBuffer &Output, unsigned X) const = 0;
+    virtual void outxword(DataBuffer &Output, uint64_t X) const = 0;
+    virtual void outaddr32(DataBuffer &Output, unsigned X) const = 0;
+    virtual void outaddr64(DataBuffer &Output, uint64_t X) const = 0;
+    virtual void outaddr(DataBuffer &Output, uint64_t X) const = 0;
+    virtual void outstring(DataBuffer &Output, std::string &S,
+                           unsigned Length) const = 0;
+
+    //===------------------------------------------------------------------===//
+    // Fix Functions - Replace an existing entry at an offset.
+
+    virtual void fixhalf(DataBuffer &Output, unsigned short X,
+                         unsigned Offset) const = 0;
+    virtual void fixword(DataBuffer &Output, unsigned X,
+                         unsigned Offset) const = 0;
+    virtual void fixaddr(DataBuffer &Output, uint64_t X,
+                         unsigned Offset) const = 0;
+  };
+
+} // end llvm namespace
+
+#endif // LLVM_TARGET_OBJ_INFO_H
diff --git a/lib/Target/PowerPC/PPCTargetObjInfo.cpp b/lib/Target/PowerPC/PPCTargetObjInfo.cpp
new file mode 100644 (file)
index 0000000..f57f35e
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- PPCTargetObjInfo.cpp - Object File Info ----------------------------==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target object file properties for PowerPC.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPCTargetObjInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace llvm;
+
+MachOTargetObjInfo::MachOTargetObjInfo(const TargetMachine &tm)
+  : TM(tm),
+    is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64),
+    isLittleEndian(TM.getTargetData()->isLittleEndian()) {}
diff --git a/lib/Target/PowerPC/PPCTargetObjInfo.h b/lib/Target/PowerPC/PPCTargetObjInfo.h
new file mode 100644 (file)
index 0000000..4c44fb3
--- /dev/null
@@ -0,0 +1,145 @@
+//===-- PPCTargetObjInfo.h - Object File Info --------------------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target object file properties for PowerPC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PPCTARGETOBJINFO_H
+#define PPCTARGETOBJINFO_H
+
+#include "llvm/Target/TargetObjInfo.h"
+
+namespace llvm {
+
+  class TargetMachine;
+
+  struct MachOTargetObjInfo : public TargetObjInfo {
+    MachOTargetObjInfo(const TargetMachine &PPC_TM);
+
+    // align - Emit padding into the file until the current output position is
+    // aligned to the specified power of two boundary.
+    virtual void align(DataBuffer &Output, unsigned Boundary) const {
+      assert(Boundary && (Boundary & (Boundary-1)) == 0 &&
+             "Must align to 2^k boundary");
+      size_t Size = Output.size();
+
+      if (Size & (Boundary-1)) {
+        // Add padding to get alignment to the correct place.
+        size_t Pad = Boundary - (Size & (Boundary - 1));
+        Output.resize(Size + Pad);
+      }
+    }
+
+    //===------------------------------------------------------------------===//
+    // Out Functions - Output the specified value to the data buffer.
+
+    virtual void outbyte(DataBuffer &Output, unsigned char X) const {
+      Output.push_back(X);
+    }
+    virtual void outhalf(DataBuffer &Output, unsigned short X) const {
+      if (isLittleEndian) {
+        Output.push_back(X & 255);
+        Output.push_back(X >> 8);
+      } else {
+        Output.push_back(X >> 8);
+        Output.push_back(X & 255);
+      }
+    }
+    virtual void outword(DataBuffer &Output, unsigned X) const {
+      if (isLittleEndian) {
+        Output.push_back((X >>  0) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >> 24) & 255);
+      } else {
+        Output.push_back((X >> 24) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >>  0) & 255);
+      }
+    }
+    virtual void outxword(DataBuffer &Output, uint64_t X) const {
+      if (isLittleEndian) {
+        Output.push_back(unsigned(X >>  0) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 56) & 255);
+      } else {
+        Output.push_back(unsigned(X >> 56) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >>  0) & 255);
+      }
+    }
+    virtual void outaddr32(DataBuffer &Output, unsigned X) const {
+      outword(Output, X);
+    }
+    virtual void outaddr64(DataBuffer &Output, uint64_t X) const {
+      outxword(Output, X);
+    }
+    virtual void outaddr(DataBuffer &Output, uint64_t X) const {
+      if (!is64Bit)
+        outword(Output, (unsigned)X);
+      else
+        outxword(Output, X);
+    }
+    virtual void outstring(DataBuffer &Output, std::string &S,
+                           unsigned Length) const {
+      unsigned len_to_copy = S.length() < Length ? S.length() : Length;
+      unsigned len_to_fill = S.length() < Length ? Length-S.length() : 0;
+
+      for (unsigned i = 0; i < len_to_copy; ++i)
+        outbyte(Output, S[i]);
+
+      for (unsigned i = 0; i < len_to_fill; ++i)
+        outbyte(Output, 0);
+    }
+
+    //===------------------------------------------------------------------===//
+    // Fix Functions - Replace an existing entry at an offset.
+
+    virtual void fixhalf(DataBuffer &Output, unsigned short X,
+                         unsigned Offset) const {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
+    }
+    virtual void fixword(DataBuffer &Output, unsigned X,
+                         unsigned Offset) const {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
+      P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
+      P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
+    }
+    virtual void fixaddr(DataBuffer &Output, uint64_t X,
+                         unsigned Offset) const {
+      // Not implemented
+    }
+  private:
+    /// Target machine description.
+    const TargetMachine &TM;
+
+    /// is64Bit/isLittleEndian - This information is inferred from the target
+    /// machine directly, indicating what header values and flags to set.
+    bool is64Bit, isLittleEndian;
+  };
+
+} // end llvm namespace
+
+#endif // PPCTARGETOBJINFO_H
diff --git a/lib/Target/X86/X86TargetObjInfo.cpp b/lib/Target/X86/X86TargetObjInfo.cpp
new file mode 100644 (file)
index 0000000..4333a40
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- X86TargetObjInfo.cpp - Object File Info ----------------------------==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target object file properties for X86
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86TargetObjInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace llvm;
+
+ELFTargetObjInfo::ELFTargetObjInfo(const TargetMachine &tm)
+  : TM(tm),
+    is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64),
+    isLittleEndian(TM.getTargetData()->isLittleEndian()) {}
diff --git a/lib/Target/X86/X86TargetObjInfo.h b/lib/Target/X86/X86TargetObjInfo.h
new file mode 100644 (file)
index 0000000..57580ea
--- /dev/null
@@ -0,0 +1,141 @@
+//===-- X86TargetObjInfo.h - Object File Info --------------------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target object file properties for X86
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86TARGETOBJINFO_H
+#define X86TARGETOBJINFO_H
+
+#include "llvm/Target/TargetObjInfo.h"
+
+namespace llvm {
+
+  class TargetMachine;
+
+  struct ELFTargetObjInfo : public TargetObjInfo {
+    ELFTargetObjInfo(const TargetMachine &tm);
+
+    // align - Emit padding into the file until the current output position is
+    // aligned to the specified power of two boundary.
+    virtual void align(DataBuffer &Output, unsigned Boundary) const {
+      assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+             "Must align to 2^k boundary");
+      size_t Size = Output.size();
+
+      if (Size & (Boundary - 1)) {
+        // Add padding to get alignment to the correct place.
+        size_t Pad = Boundary - (Size & (Boundary - 1));
+        Output.resize(Size + Pad);
+      }
+    }
+
+    //===------------------------------------------------------------------===//
+    // Out Functions - Output the specified value to the data buffer.
+
+    virtual void outbyte(DataBuffer &Output, unsigned char X) const {
+      Output.push_back(X);
+    }
+    virtual void outhalf(DataBuffer &Output, unsigned short X) const {
+      if (isLittleEndian) {
+        Output.push_back(X & 255);
+        Output.push_back(X >> 8);
+      } else {
+        Output.push_back(X >> 8);
+        Output.push_back(X & 255);
+      }
+    }
+    virtual void outword(DataBuffer &Output, unsigned X) const {
+      if (isLittleEndian) {
+        Output.push_back((X >>  0) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >> 24) & 255);
+      } else {
+        Output.push_back((X >> 24) & 255);
+        Output.push_back((X >> 16) & 255);
+        Output.push_back((X >>  8) & 255);
+        Output.push_back((X >>  0) & 255);
+      }
+    }
+    virtual void outxword(DataBuffer &Output, uint64_t X) const {
+      if (isLittleEndian) {
+        Output.push_back(unsigned(X >>  0) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 56) & 255);
+      } else {
+        Output.push_back(unsigned(X >> 56) & 255);
+        Output.push_back(unsigned(X >> 48) & 255);
+        Output.push_back(unsigned(X >> 40) & 255);
+        Output.push_back(unsigned(X >> 32) & 255);
+        Output.push_back(unsigned(X >> 24) & 255);
+        Output.push_back(unsigned(X >> 16) & 255);
+        Output.push_back(unsigned(X >>  8) & 255);
+        Output.push_back(unsigned(X >>  0) & 255);
+      }
+    }
+    virtual void outaddr32(DataBuffer &Output, unsigned X) const {
+      outword(Output, X);
+    }
+    virtual void outaddr64(DataBuffer &Output, uint64_t X) const {
+      outxword(Output, X);
+    }
+    virtual void outaddr(DataBuffer &Output, uint64_t X) const {
+      if (!is64Bit)
+        outword(Output, (unsigned)X);
+      else
+        outxword(Output, X);
+    }
+    virtual void outstring(DataBuffer &Output, std::string &S,
+                           unsigned Length) const {
+      // Not implemented
+    }
+
+    //===------------------------------------------------------------------===//
+    // Fix Functions - Replace an existing entry at an offset.
+
+    virtual void fixhalf(DataBuffer &Output, unsigned short X,
+                         unsigned Offset) const {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 8)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 0)) & 255;
+    }
+    virtual void fixword(DataBuffer &Output, unsigned X,
+                         unsigned Offset) const {
+      unsigned char *P = &Output[Offset];
+      P[0] = (X >> (isLittleEndian ?  0 : 24)) & 255;
+      P[1] = (X >> (isLittleEndian ?  8 : 16)) & 255;
+      P[2] = (X >> (isLittleEndian ? 16 :  8)) & 255;
+      P[3] = (X >> (isLittleEndian ? 24 :  0)) & 255;
+    }
+    virtual void fixaddr(DataBuffer &Output, uint64_t X,
+                         unsigned Offset) const {
+      if (!is64Bit)
+        fixword(Output, (unsigned)X, Offset);
+      else
+        assert(0 && "Emission of 64-bit data not implemented yet!");
+    }
+  private:
+    /// Target machine description.
+    const TargetMachine &TM;
+
+    /// is64Bit/isLittleEndian - This information is inferred from the target
+    /// machine directly, indicating what header values and flags to set.
+    bool is64Bit, isLittleEndian;
+  };
+
+} // end llvm namespace
+
+#endif // X86TARGETOBJINFO_H