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 "llvm/MC/MCContext.h" 12 #include "llvm/MC/MCELFObjectWriter.h" 13 #include "llvm/MC/MCValue.h" 14 15 using namespace llvm; 16 17 namespace { 18 19 class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter { 20 public: 21 AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend); 22 23 protected: 24 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 25 const MCFixup &Fixup, bool IsPCRel) const override; 26 }; 27 28 29 } // end anonymous namespace 30 31 AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 32 bool HasRelocationAddend) 33 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU, 34 HasRelocationAddend) {} 35 36 unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx, 37 const MCValue &Target, 38 const MCFixup &Fixup, 39 bool IsPCRel) const { 40 if (const auto *SymA = Target.getSymA()) { 41 // SCRATCH_RSRC_DWORD[01] is a special global variable that represents 42 // the scratch buffer. 43 if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" || 44 SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1") 45 return ELF::R_AMDGPU_ABS32_LO; 46 } 47 48 switch (Target.getAccessVariant()) { 49 default: 50 break; 51 case MCSymbolRefExpr::VK_GOTPCREL: 52 return ELF::R_AMDGPU_GOTPCREL; 53 case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO: 54 return ELF::R_AMDGPU_GOTPCREL32_LO; 55 case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI: 56 return ELF::R_AMDGPU_GOTPCREL32_HI; 57 case MCSymbolRefExpr::VK_AMDGPU_REL32_LO: 58 return ELF::R_AMDGPU_REL32_LO; 59 case MCSymbolRefExpr::VK_AMDGPU_REL32_HI: 60 return ELF::R_AMDGPU_REL32_HI; 61 case MCSymbolRefExpr::VK_AMDGPU_REL64: 62 return ELF::R_AMDGPU_REL64; 63 case MCSymbolRefExpr::VK_AMDGPU_ABS32_LO: 64 return ELF::R_AMDGPU_ABS32_LO; 65 case MCSymbolRefExpr::VK_AMDGPU_ABS32_HI: 66 return ELF::R_AMDGPU_ABS32_HI; 67 } 68 69 MCFixupKind Kind = Fixup.getKind(); 70 if (Kind >= FirstLiteralRelocationKind) 71 return Kind - FirstLiteralRelocationKind; 72 switch (Kind) { 73 default: break; 74 case FK_PCRel_4: 75 return ELF::R_AMDGPU_REL32; 76 case FK_Data_4: 77 case FK_SecRel_4: 78 return IsPCRel ? ELF::R_AMDGPU_REL32 : ELF::R_AMDGPU_ABS32; 79 case FK_Data_8: 80 return IsPCRel ? ELF::R_AMDGPU_REL64 : ELF::R_AMDGPU_ABS64; 81 } 82 83 if (Fixup.getTargetKind() == AMDGPU::fixup_si_sopp_br) { 84 const auto *SymA = Target.getSymA(); 85 assert(SymA); 86 87 if (SymA->getSymbol().isUndefined()) { 88 Ctx.reportError(Fixup.getLoc(), Twine("undefined label '") + 89 SymA->getSymbol().getName() + "'"); 90 return ELF::R_AMDGPU_NONE; 91 } 92 return ELF::R_AMDGPU_REL16; 93 } 94 95 llvm_unreachable("unhandled relocation type"); 96 } 97 98 std::unique_ptr<MCObjectTargetWriter> 99 llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 100 bool HasRelocationAddend) { 101 return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI, 102 HasRelocationAddend); 103 } 104