Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.9 KiB

  1. //===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_MC_MCELFOBJECTWRITER_H
  10. #define LLVM_MC_MCELFOBJECTWRITER_H
  11. #include "llvm/ADT/Triple.h"
  12. #include "llvm/Support/DataTypes.h"
  13. #include "llvm/Support/ELF.h"
  14. #include <vector>
  15. namespace llvm {
  16. class MCAssembler;
  17. class MCFixup;
  18. class MCFragment;
  19. class MCObjectWriter;
  20. class MCSymbol;
  21. class MCValue;
  22. /// @name Relocation Data
  23. /// @{
  24. struct ELFRelocationEntry {
  25. // Make these big enough for both 32-bit and 64-bit
  26. uint64_t r_offset;
  27. int Index;
  28. unsigned Type;
  29. const MCSymbol *Symbol;
  30. uint64_t r_addend;
  31. const MCFixup *Fixup;
  32. ELFRelocationEntry()
  33. : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {}
  34. ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType,
  35. const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
  36. : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
  37. r_addend(Addend), Fixup(&Fixup) {}
  38. // Support lexicographic sorting.
  39. bool operator<(const ELFRelocationEntry &RE) const {
  40. return RE.r_offset < r_offset;
  41. }
  42. };
  43. class MCELFObjectTargetWriter {
  44. const uint8_t OSABI;
  45. const uint16_t EMachine;
  46. const unsigned HasRelocationAddend : 1;
  47. const unsigned Is64Bit : 1;
  48. const unsigned IsN64 : 1;
  49. protected:
  50. MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
  51. uint16_t EMachine_, bool HasRelocationAddend,
  52. bool IsN64=false);
  53. public:
  54. static uint8_t getOSABI(Triple::OSType OSType) {
  55. switch (OSType) {
  56. case Triple::FreeBSD:
  57. return ELF::ELFOSABI_FREEBSD;
  58. case Triple::Linux:
  59. return ELF::ELFOSABI_LINUX;
  60. default:
  61. return ELF::ELFOSABI_NONE;
  62. }
  63. }
  64. virtual ~MCELFObjectTargetWriter() {}
  65. virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
  66. bool IsPCRel, bool IsRelocWithSymbol,
  67. int64_t Addend) const = 0;
  68. virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
  69. const MCValue &Target,
  70. const MCFragment &F,
  71. const MCFixup &Fixup,
  72. bool IsPCRel) const;
  73. virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
  74. const MCFixup &Fixup,
  75. bool IsPCRel) const;
  76. virtual void adjustFixupOffset(const MCFixup &Fixup,
  77. uint64_t &RelocOffset);
  78. virtual void sortRelocs(const MCAssembler &Asm,
  79. std::vector<ELFRelocationEntry> &Relocs);
  80. /// @name Accessors
  81. /// @{
  82. uint8_t getOSABI() const { return OSABI; }
  83. uint16_t getEMachine() const { return EMachine; }
  84. bool hasRelocationAddend() const { return HasRelocationAddend; }
  85. bool is64Bit() const { return Is64Bit; }
  86. bool isN64() const { return IsN64; }
  87. /// @}
  88. // Instead of changing everyone's API we pack the N64 Type fields
  89. // into the existing 32 bit data unsigned.
  90. #define R_TYPE_SHIFT 0
  91. #define R_TYPE_MASK 0xffffff00
  92. #define R_TYPE2_SHIFT 8
  93. #define R_TYPE2_MASK 0xffff00ff
  94. #define R_TYPE3_SHIFT 16
  95. #define R_TYPE3_MASK 0xff00ffff
  96. #define R_SSYM_SHIFT 24
  97. #define R_SSYM_MASK 0x00ffffff
  98. // N64 relocation type accessors
  99. unsigned getRType(uint32_t Type) const {
  100. return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
  101. }
  102. unsigned getRType2(uint32_t Type) const {
  103. return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
  104. }
  105. unsigned getRType3(uint32_t Type) const {
  106. return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
  107. }
  108. unsigned getRSsym(uint32_t Type) const {
  109. return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
  110. }
  111. // N64 relocation type setting
  112. unsigned setRType(unsigned Value, unsigned Type) const {
  113. return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
  114. }
  115. unsigned setRType2(unsigned Value, unsigned Type) const {
  116. return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
  117. }
  118. unsigned setRType3(unsigned Value, unsigned Type) const {
  119. return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
  120. }
  121. unsigned setRSsym(unsigned Value, unsigned Type) const {
  122. return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
  123. }
  124. };
  125. /// \brief Construct a new ELF writer instance.
  126. ///
  127. /// \param MOTW - The target specific ELF writer subclass.
  128. /// \param OS - The stream to write to.
  129. /// \returns The constructed object writer.
  130. MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
  131. raw_ostream &OS, bool IsLittleEndian);
  132. } // End llvm namespace
  133. #endif