MCELFObjectWriter.h revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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