MCELFObjectWriter.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_MC_MCELFOBJECTWRITER_H
  14. #define LLVM_MC_MCELFOBJECTWRITER_H
  15. #include "llvm/ADT/Triple.h"
  16. #include "llvm/BinaryFormat/ELF.h"
  17. #include "llvm/MC/MCObjectWriter.h"
  18. #include "llvm/MC/MCSectionELF.h"
  19. #include "llvm/Support/Casting.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. #include <cstdint>
  22. #include <vector>
  23. namespace llvm {
  24. class MCAssembler;
  25. class MCContext;
  26. class MCFixup;
  27. class MCSymbol;
  28. class MCSymbolELF;
  29. class MCValue;
  30. struct ELFRelocationEntry {
  31. uint64_t Offset; // Where is the relocation.
  32. const MCSymbolELF *Symbol; // The symbol to relocate with.
  33. unsigned Type; // The type of the relocation.
  34. uint64_t Addend; // The addend to use.
  35. const MCSymbolELF *OriginalSymbol; // The original value of Symbol if we changed it.
  36. uint64_t OriginalAddend; // The original value of addend.
  37. ELFRelocationEntry(uint64_t Offset, const MCSymbolELF *Symbol, unsigned Type,
  38. uint64_t Addend, const MCSymbolELF *OriginalSymbol,
  39. uint64_t OriginalAddend)
  40. : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend),
  41. OriginalSymbol(OriginalSymbol), OriginalAddend(OriginalAddend) {}
  42. void print(raw_ostream &Out) const {
  43. Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type
  44. << ", Addend=" << Addend << ", OriginalSymbol=" << OriginalSymbol
  45. << ", OriginalAddend=" << OriginalAddend;
  46. }
  47. LLVM_DUMP_METHOD void dump() const { print(errs()); }
  48. };
  49. class MCELFObjectTargetWriter : public MCObjectTargetWriter {
  50. const uint8_t OSABI;
  51. const uint8_t ABIVersion;
  52. const uint16_t EMachine;
  53. const unsigned HasRelocationAddend : 1;
  54. const unsigned Is64Bit : 1;
  55. protected:
  56. MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_, uint16_t EMachine_,
  57. bool HasRelocationAddend_, uint8_t ABIVersion_ = 0);
  58. public:
  59. virtual ~MCELFObjectTargetWriter() = default;
  60. Triple::ObjectFormatType getFormat() const override { return Triple::ELF; }
  61. static bool classof(const MCObjectTargetWriter *W) {
  62. return W->getFormat() == Triple::ELF;
  63. }
  64. static uint8_t getOSABI(Triple::OSType OSType) {
  65. switch (OSType) {
  66. case Triple::CloudABI:
  67. return ELF::ELFOSABI_CLOUDABI;
  68. case Triple::HermitCore:
  69. return ELF::ELFOSABI_STANDALONE;
  70. case Triple::PS4:
  71. case Triple::FreeBSD:
  72. return ELF::ELFOSABI_FREEBSD;
  73. case Triple::Solaris:
  74. return ELF::ELFOSABI_SOLARIS;
  75. default:
  76. return ELF::ELFOSABI_NONE;
  77. }
  78. }
  79. virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
  80. const MCFixup &Fixup, bool IsPCRel) const = 0;
  81. virtual bool needsRelocateWithSymbol(const MCSymbol &Sym,
  82. unsigned Type) const;
  83. virtual void sortRelocs(const MCAssembler &Asm,
  84. std::vector<ELFRelocationEntry> &Relocs);
  85. virtual void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec);
  86. /// \name Accessors
  87. /// @{
  88. uint8_t getOSABI() const { return OSABI; }
  89. uint8_t getABIVersion() const { return ABIVersion; }
  90. uint16_t getEMachine() const { return EMachine; }
  91. bool hasRelocationAddend() const { return HasRelocationAddend; }
  92. bool is64Bit() const { return Is64Bit; }
  93. /// @}
  94. // Instead of changing everyone's API we pack the N64 Type fields
  95. // into the existing 32 bit data unsigned.
  96. #define R_TYPE_SHIFT 0
  97. #define R_TYPE_MASK 0xffffff00
  98. #define R_TYPE2_SHIFT 8
  99. #define R_TYPE2_MASK 0xffff00ff
  100. #define R_TYPE3_SHIFT 16
  101. #define R_TYPE3_MASK 0xff00ffff
  102. #define R_SSYM_SHIFT 24
  103. #define R_SSYM_MASK 0x00ffffff
  104. // N64 relocation type accessors
  105. uint8_t getRType(uint32_t Type) const {
  106. return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
  107. }
  108. uint8_t getRType2(uint32_t Type) const {
  109. return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
  110. }
  111. uint8_t getRType3(uint32_t Type) const {
  112. return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
  113. }
  114. uint8_t getRSsym(uint32_t Type) const {
  115. return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
  116. }
  117. // N64 relocation type setting
  118. static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
  119. return ((Value1 & 0xff) << R_TYPE_SHIFT) |
  120. ((Value2 & 0xff) << R_TYPE2_SHIFT) |
  121. ((Value3 & 0xff) << R_TYPE3_SHIFT);
  122. }
  123. unsigned setRSsym(unsigned Value, unsigned Type) const {
  124. return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
  125. }
  126. // On AArch64, return a new section to be added to the ELF object that
  127. // contains relocations used to describe every symbol that should have memory
  128. // tags applied. Returns nullptr if no such section is necessary (i.e. there's
  129. // no tagged globals).
  130. virtual MCSectionELF *getMemtagRelocsSection(MCContext &Ctx) const {
  131. return nullptr;
  132. }
  133. };
  134. /// Construct a new ELF writer instance.
  135. ///
  136. /// \param MOTW - The target specific ELF writer subclass.
  137. /// \param OS - The stream to write to.
  138. /// \returns The constructed object writer.
  139. std::unique_ptr<MCObjectWriter>
  140. createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
  141. raw_pwrite_stream &OS, bool IsLittleEndian);
  142. std::unique_ptr<MCObjectWriter>
  143. createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
  144. raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
  145. bool IsLittleEndian);
  146. } // end namespace llvm
  147. #endif // LLVM_MC_MCELFOBJECTWRITER_H
  148. #ifdef __GNUC__
  149. #pragma GCC diagnostic pop
  150. #endif