10b57cec5SDimitry Andric //===- AMDGPUELFObjectWriter.cpp - AMDGPU ELF Writer ----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #include "AMDGPUFixupKinds.h" 100b57cec5SDimitry Andric #include "AMDGPUMCTargetDesc.h" 115ffd83dbSDimitry Andric #include "llvm/MC/MCContext.h" 120b57cec5SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric using namespace llvm; 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric namespace { 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter { 200b57cec5SDimitry Andric public: 21*7a6dacacSDimitry Andric AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend); 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric protected: 240b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 250b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override; 260b57cec5SDimitry Andric }; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric } // end anonymous namespace 300b57cec5SDimitry Andric 31*7a6dacacSDimitry Andric AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 32*7a6dacacSDimitry Andric bool HasRelocationAddend) 330b57cec5SDimitry Andric : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU, 34*7a6dacacSDimitry Andric HasRelocationAddend) {} 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx, 370b57cec5SDimitry Andric const MCValue &Target, 380b57cec5SDimitry Andric const MCFixup &Fixup, 390b57cec5SDimitry Andric bool IsPCRel) const { 400b57cec5SDimitry Andric if (const auto *SymA = Target.getSymA()) { 410b57cec5SDimitry Andric // SCRATCH_RSRC_DWORD[01] is a special global variable that represents 420b57cec5SDimitry Andric // the scratch buffer. 430b57cec5SDimitry Andric if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" || 440b57cec5SDimitry Andric SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1") 450b57cec5SDimitry Andric return ELF::R_AMDGPU_ABS32_LO; 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric switch (Target.getAccessVariant()) { 490b57cec5SDimitry Andric default: 500b57cec5SDimitry Andric break; 510b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL: 520b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL; 530b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO: 540b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL32_LO; 550b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI: 560b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL32_HI; 570b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL32_LO: 580b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32_LO; 590b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL32_HI: 600b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32_HI; 610b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL64: 620b57cec5SDimitry Andric return ELF::R_AMDGPU_REL64; 635f757f3fSDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_ABS32_LO: 645f757f3fSDimitry Andric return ELF::R_AMDGPU_ABS32_LO; 655f757f3fSDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_ABS32_HI: 665f757f3fSDimitry Andric return ELF::R_AMDGPU_ABS32_HI; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 6981ad6265SDimitry Andric MCFixupKind Kind = Fixup.getKind(); 7081ad6265SDimitry Andric if (Kind >= FirstLiteralRelocationKind) 7181ad6265SDimitry Andric return Kind - FirstLiteralRelocationKind; 7281ad6265SDimitry Andric switch (Kind) { 730b57cec5SDimitry Andric default: break; 740b57cec5SDimitry Andric case FK_PCRel_4: 750b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32; 760b57cec5SDimitry Andric case FK_Data_4: 770b57cec5SDimitry Andric case FK_SecRel_4: 7806c3fb27SDimitry Andric return IsPCRel ? ELF::R_AMDGPU_REL32 : ELF::R_AMDGPU_ABS32; 790b57cec5SDimitry Andric case FK_Data_8: 8006c3fb27SDimitry Andric return IsPCRel ? ELF::R_AMDGPU_REL64 : ELF::R_AMDGPU_ABS64; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 835ffd83dbSDimitry Andric if (Fixup.getTargetKind() == AMDGPU::fixup_si_sopp_br) { 845ffd83dbSDimitry Andric const auto *SymA = Target.getSymA(); 855ffd83dbSDimitry Andric assert(SymA); 865ffd83dbSDimitry Andric 87fe6060f1SDimitry Andric if (SymA->getSymbol().isUndefined()) { 88fe6060f1SDimitry Andric Ctx.reportError(Fixup.getLoc(), Twine("undefined label '") + 89fe6060f1SDimitry Andric SymA->getSymbol().getName() + "'"); 905ffd83dbSDimitry Andric return ELF::R_AMDGPU_NONE; 915ffd83dbSDimitry Andric } 92fe6060f1SDimitry Andric return ELF::R_AMDGPU_REL16; 93fe6060f1SDimitry Andric } 945ffd83dbSDimitry Andric 950b57cec5SDimitry Andric llvm_unreachable("unhandled relocation type"); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter> 990b57cec5SDimitry Andric llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, 100*7a6dacacSDimitry Andric bool HasRelocationAddend) { 1018bcb0991SDimitry Andric return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI, 102*7a6dacacSDimitry Andric HasRelocationAddend); 1030b57cec5SDimitry Andric } 104