From 34f03fff2d117068b4d627922484d2d79ed9c025 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 17 Jan 2007 03:46:30 +0000 Subject: [PATCH] New "TargetObjInfo" class. This holds information that the object writers will 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 | 57 ++++++++++ lib/Target/PowerPC/PPCTargetObjInfo.cpp | 22 ++++ lib/Target/PowerPC/PPCTargetObjInfo.h | 145 ++++++++++++++++++++++++ lib/Target/X86/X86TargetObjInfo.cpp | 22 ++++ lib/Target/X86/X86TargetObjInfo.h | 141 +++++++++++++++++++++++ 5 files changed, 387 insertions(+) create mode 100644 include/llvm/Target/TargetObjInfo.h create mode 100644 lib/Target/PowerPC/PPCTargetObjInfo.cpp create mode 100644 lib/Target/PowerPC/PPCTargetObjInfo.h create mode 100644 lib/Target/X86/X86TargetObjInfo.cpp create mode 100644 lib/Target/X86/X86TargetObjInfo.h diff --git a/include/llvm/Target/TargetObjInfo.h b/include/llvm/Target/TargetObjInfo.h new file mode 100644 index 00000000000..ffad3543ba7 --- /dev/null +++ b/include/llvm/Target/TargetObjInfo.h @@ -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 +#include + +namespace llvm { + + struct TargetObjInfo { + TargetObjInfo() {} + virtual ~TargetObjInfo() {} + + typedef std::vector 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 index 00000000000..f57f35e7401 --- /dev/null +++ b/lib/Target/PowerPC/PPCTargetObjInfo.cpp @@ -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 index 00000000000..4c44fb38194 --- /dev/null +++ b/lib/Target/PowerPC/PPCTargetObjInfo.h @@ -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 index 00000000000..4333a402f9b --- /dev/null +++ b/lib/Target/X86/X86TargetObjInfo.cpp @@ -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 index 00000000000..57580ea0249 --- /dev/null +++ b/lib/Target/X86/X86TargetObjInfo.h @@ -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 -- 2.34.1