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