LLVM API Documentation
00001 //===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_MC_MCELFOBJECTWRITER_H 00011 #define LLVM_MC_MCELFOBJECTWRITER_H 00012 00013 #include "llvm/ADT/Triple.h" 00014 #include "llvm/Support/DataTypes.h" 00015 #include "llvm/Support/ELF.h" 00016 #include <vector> 00017 00018 namespace llvm { 00019 class MCAssembler; 00020 class MCFixup; 00021 class MCFragment; 00022 class MCObjectWriter; 00023 class MCSymbol; 00024 class MCValue; 00025 00026 /// @name Relocation Data 00027 /// @{ 00028 00029 struct ELFRelocationEntry { 00030 // Make these big enough for both 32-bit and 64-bit 00031 uint64_t r_offset; 00032 int Index; 00033 unsigned Type; 00034 const MCSymbol *Symbol; 00035 uint64_t r_addend; 00036 const MCFixup *Fixup; 00037 00038 ELFRelocationEntry() 00039 : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {} 00040 00041 ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType, 00042 const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup) 00043 : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym), 00044 r_addend(Addend), Fixup(&Fixup) {} 00045 }; 00046 00047 class MCELFObjectTargetWriter { 00048 const uint8_t OSABI; 00049 const uint16_t EMachine; 00050 const unsigned HasRelocationAddend : 1; 00051 const unsigned Is64Bit : 1; 00052 const unsigned IsN64 : 1; 00053 00054 protected: 00055 00056 MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, 00057 uint16_t EMachine_, bool HasRelocationAddend, 00058 bool IsN64=false); 00059 00060 public: 00061 static uint8_t getOSABI(Triple::OSType OSType) { 00062 switch (OSType) { 00063 case Triple::FreeBSD: 00064 return ELF::ELFOSABI_FREEBSD; 00065 case Triple::Linux: 00066 return ELF::ELFOSABI_LINUX; 00067 default: 00068 return ELF::ELFOSABI_NONE; 00069 } 00070 } 00071 00072 virtual ~MCELFObjectTargetWriter() {} 00073 00074 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 00075 bool IsPCRel, bool IsRelocWithSymbol, 00076 int64_t Addend) const = 0; 00077 virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 00078 const MCValue &Target, 00079 const MCFragment &F, 00080 const MCFixup &Fixup, 00081 bool IsPCRel) const; 00082 virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, 00083 const MCFixup &Fixup, 00084 bool IsPCRel) const; 00085 00086 virtual void sortRelocs(const MCAssembler &Asm, 00087 std::vector<ELFRelocationEntry> &Relocs); 00088 00089 /// @name Accessors 00090 /// @{ 00091 uint8_t getOSABI() const { return OSABI; } 00092 uint16_t getEMachine() const { return EMachine; } 00093 bool hasRelocationAddend() const { return HasRelocationAddend; } 00094 bool is64Bit() const { return Is64Bit; } 00095 bool isN64() const { return IsN64; } 00096 /// @} 00097 00098 // Instead of changing everyone's API we pack the N64 Type fields 00099 // into the existing 32 bit data unsigned. 00100 #define R_TYPE_SHIFT 0 00101 #define R_TYPE_MASK 0xffffff00 00102 #define R_TYPE2_SHIFT 8 00103 #define R_TYPE2_MASK 0xffff00ff 00104 #define R_TYPE3_SHIFT 16 00105 #define R_TYPE3_MASK 0xff00ffff 00106 #define R_SSYM_SHIFT 24 00107 #define R_SSYM_MASK 0x00ffffff 00108 00109 // N64 relocation type accessors 00110 unsigned getRType(uint32_t Type) const { 00111 return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff); 00112 } 00113 unsigned getRType2(uint32_t Type) const { 00114 return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff); 00115 } 00116 unsigned getRType3(uint32_t Type) const { 00117 return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff); 00118 } 00119 unsigned getRSsym(uint32_t Type) const { 00120 return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff); 00121 } 00122 00123 // N64 relocation type setting 00124 unsigned setRType(unsigned Value, unsigned Type) const { 00125 return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT)); 00126 } 00127 unsigned setRType2(unsigned Value, unsigned Type) const { 00128 return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT); 00129 } 00130 unsigned setRType3(unsigned Value, unsigned Type) const { 00131 return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT); 00132 } 00133 unsigned setRSsym(unsigned Value, unsigned Type) const { 00134 return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT); 00135 } 00136 }; 00137 00138 /// \brief Construct a new ELF writer instance. 00139 /// 00140 /// \param MOTW - The target specific ELF writer subclass. 00141 /// \param OS - The stream to write to. 00142 /// \returns The constructed object writer. 00143 MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 00144 raw_ostream &OS, bool IsLittleEndian); 00145 } // End llvm namespace 00146 00147 #endif