1 //===- AMDGPUELFObjectWriter.cpp - AMDGPU ELF Writer ----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "AMDGPUFixupKinds.h" 10 #include "AMDGPUMCTargetDesc.h" 11 #include "MCTargetDesc/AMDGPUMCExpr.h" 12 #include "llvm/MC/MCContext.h" 13 #include "llvm/MC/MCELFObjectWriter.h" 14 #include "llvm/MC/MCValue.h" 15 16 using namespace llvm; 17 18 namespace { 19 20 class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter { 21 public: 22 AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend); 23 24 protected: 25 unsigned getRelocType(const MCFixup &, const MCValue &, 26 bool IsPCRel) const override; 27 }; 28 29 30 } // end anonymous namespace 31 32 AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 33 bool HasRelocationAddend) 34 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU, 35 HasRelocationAddend) {} 36 37 unsigned AMDGPUELFObjectWriter::getRelocType(const MCFixup &Fixup, 38 const MCValue &Target, 39 bool IsPCRel) const { 40 if (const auto *SymA = Target.getAddSym()) { 41 // SCRATCH_RSRC_DWORD[01] is a special global variable that represents 42 // the scratch buffer. 43 if (SymA->getName() == "SCRATCH_RSRC_DWORD0" || 44 SymA->getName() == "SCRATCH_RSRC_DWORD1") 45 return ELF::R_AMDGPU_ABS32_LO; 46 } 47 48 switch (AMDGPUMCExpr::Specifier(Target.getSpecifier())) { 49 default: 50 break; 51 case AMDGPUMCExpr::S_GOTPCREL: 52 return ELF::R_AMDGPU_GOTPCREL; 53 case AMDGPUMCExpr::S_GOTPCREL32_LO: 54 return ELF::R_AMDGPU_GOTPCREL32_LO; 55 case AMDGPUMCExpr::S_GOTPCREL32_HI: 56 return ELF::R_AMDGPU_GOTPCREL32_HI; 57 case AMDGPUMCExpr::S_REL32_LO: 58 return ELF::R_AMDGPU_REL32_LO; 59 case AMDGPUMCExpr::S_REL32_HI: 60 return ELF::R_AMDGPU_REL32_HI; 61 case AMDGPUMCExpr::S_REL64: 62 return ELF::R_AMDGPU_REL64; 63 case AMDGPUMCExpr::S_ABS32_LO: 64 return ELF::R_AMDGPU_ABS32_LO; 65 case AMDGPUMCExpr::S_ABS32_HI: 66 return ELF::R_AMDGPU_ABS32_HI; 67 } 68 69 MCFixupKind Kind = Fixup.getKind(); 70 switch (Kind) { 71 default: break; 72 case FK_Data_4: 73 case FK_SecRel_4: 74 return IsPCRel ? ELF::R_AMDGPU_REL32 : ELF::R_AMDGPU_ABS32; 75 case FK_Data_8: 76 return IsPCRel ? ELF::R_AMDGPU_REL64 : ELF::R_AMDGPU_ABS64; 77 } 78 79 if (Fixup.getKind() == AMDGPU::fixup_si_sopp_br) { 80 const auto *SymA = Target.getAddSym(); 81 assert(SymA); 82 83 if (SymA->isUndefined()) { 84 reportError(Fixup.getLoc(), 85 Twine("undefined label '") + SymA->getName() + "'"); 86 return ELF::R_AMDGPU_NONE; 87 } 88 return ELF::R_AMDGPU_REL16; 89 } 90 91 llvm_unreachable("unhandled relocation type"); 92 } 93 94 std::unique_ptr<MCObjectTargetWriter> 95 llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 96 bool HasRelocationAddend) { 97 return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI, 98 HasRelocationAddend); 99 } 100