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