1285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===// 2285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// 3285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// The LLVM Compiler Infrastructure 4285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// 5285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// This file is distributed under the University of Illinois Open Source 6285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// License. See LICENSE.TXT for details. 7285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola// 8285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola//===----------------------------------------------------------------------===// 9285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola 10285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#ifndef LLVM_MC_MCELFOBJECTWRITER_H 11285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#define LLVM_MC_MCELFOBJECTWRITER_H 12285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola 13f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/ADT/Triple.h" 14285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#include "llvm/Support/DataTypes.h" 15dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola#include "llvm/Support/ELF.h" 1600ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka#include <vector> 17285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola 18285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindolanamespace llvm { 19f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCAssembler; 20f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCFixup; 21f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCFragment; 22f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCObjectWriter; 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass MCSectionData; 24f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCSymbol; 25f1d0f7781e766df878bec4e7977fa3204374f394Craig Topperclass MCValue; 26f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper 276024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaclass MCELFObjectTargetWriter { 28dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola const uint8_t OSABI; 29bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola const uint16_t EMachine; 30bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola const unsigned HasRelocationAddend : 1; 31bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola const unsigned Is64Bit : 1; 3293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter const unsigned IsN64 : 1; 33dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola 346024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaprotected: 35dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola 36dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, 3793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter uint16_t EMachine_, bool HasRelocationAddend, 3893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter bool IsN64=false); 396024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola 406024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolapublic: 41dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola static uint8_t getOSABI(Triple::OSType OSType) { 42dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola switch (OSType) { 43dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola case Triple::FreeBSD: 44dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola return ELF::ELFOSABI_FREEBSD; 45dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola case Triple::Linux: 46dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola return ELF::ELFOSABI_LINUX; 47dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola default: 48dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola return ELF::ELFOSABI_NONE; 49dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola } 50dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola } 51dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola 5284070ffbe6905f31cf369ad3f6742dfa5188332cRafael Espindola virtual ~MCELFObjectTargetWriter() {} 53bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola 54edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsPCRel) const = 0; 56f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines virtual bool needsRelocateWithSymbol(unsigned Type) const; 58edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola 59bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola /// @name Accessors 60bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola /// @{ 61ed2507a9dabc6d10c9e1e3685f528651b8cb73fdMichael Liao uint8_t getOSABI() const { return OSABI; } 62ed2507a9dabc6d10c9e1e3685f528651b8cb73fdMichael Liao uint16_t getEMachine() const { return EMachine; } 63ed2507a9dabc6d10c9e1e3685f528651b8cb73fdMichael Liao bool hasRelocationAddend() const { return HasRelocationAddend; } 64d4304031cb465ca85e2bebb352b7cde5a92a1c39Rafael Espindola bool is64Bit() const { return Is64Bit; } 6593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter bool isN64() const { return IsN64; } 66bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola /// @} 6793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter 6893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter // Instead of changing everyone's API we pack the N64 Type fields 6993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter // into the existing 32 bit data unsigned. 7093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE_SHIFT 0 7193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE_MASK 0xffffff00 7293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE2_SHIFT 8 7393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE2_MASK 0xffff00ff 7493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE3_SHIFT 16 7593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_TYPE3_MASK 0xff00ffff 7693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_SSYM_SHIFT 24 7793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter#define R_SSYM_MASK 0x00ffffff 7893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter 7993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter // N64 relocation type accessors 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t getRType(uint32_t Type) const { 8193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff); 8293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t getRType2(uint32_t Type) const { 8493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff); 8593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t getRType3(uint32_t Type) const { 8793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff); 8893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t getRSsym(uint32_t Type) const { 9093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff); 9193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 9293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter 9393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter // N64 relocation type setting 9493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter unsigned setRType(unsigned Value, unsigned Type) const { 9593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT)); 9693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 9793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter unsigned setRType2(unsigned Value, unsigned Type) const { 9893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT); 9993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 10093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter unsigned setRType3(unsigned Value, unsigned Type) const { 10193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT); 10293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 10393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter unsigned setRSsym(unsigned Value, unsigned Type) const { 10493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT); 10593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 1066024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola}; 1076024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola 108285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola/// \brief Construct a new ELF writer instance. 109285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola/// 1106024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola/// \param MOTW - The target specific ELF writer subclass. 111285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola/// \param OS - The stream to write to. 112285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola/// \returns The constructed object writer. 1136024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 114bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &OS, bool IsLittleEndian); 115285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola} // End llvm namespace 116285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola 117285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#endif 118