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:
210b57cec5SDimitry Andric AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend,
220b57cec5SDimitry Andric uint8_t ABIVersion);
230b57cec5SDimitry Andric
240b57cec5SDimitry Andric protected:
250b57cec5SDimitry Andric unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
260b57cec5SDimitry Andric const MCFixup &Fixup, bool IsPCRel) const override;
270b57cec5SDimitry Andric };
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric } // end anonymous namespace
310b57cec5SDimitry Andric
AMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend,uint8_t ABIVersion)320b57cec5SDimitry Andric AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit,
330b57cec5SDimitry Andric uint8_t OSABI,
340b57cec5SDimitry Andric bool HasRelocationAddend,
350b57cec5SDimitry Andric uint8_t ABIVersion)
360b57cec5SDimitry Andric : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU,
370b57cec5SDimitry Andric HasRelocationAddend, ABIVersion) {}
380b57cec5SDimitry Andric
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const390b57cec5SDimitry Andric unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
400b57cec5SDimitry Andric const MCValue &Target,
410b57cec5SDimitry Andric const MCFixup &Fixup,
420b57cec5SDimitry Andric bool IsPCRel) const {
430b57cec5SDimitry Andric if (const auto *SymA = Target.getSymA()) {
440b57cec5SDimitry Andric // SCRATCH_RSRC_DWORD[01] is a special global variable that represents
450b57cec5SDimitry Andric // the scratch buffer.
460b57cec5SDimitry Andric if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" ||
470b57cec5SDimitry Andric SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1")
480b57cec5SDimitry Andric return ELF::R_AMDGPU_ABS32_LO;
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric switch (Target.getAccessVariant()) {
520b57cec5SDimitry Andric default:
530b57cec5SDimitry Andric break;
540b57cec5SDimitry Andric case MCSymbolRefExpr::VK_GOTPCREL:
550b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL;
560b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO:
570b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL32_LO;
580b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI:
590b57cec5SDimitry Andric return ELF::R_AMDGPU_GOTPCREL32_HI;
600b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL32_LO:
610b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32_LO;
620b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
630b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32_HI;
640b57cec5SDimitry Andric case MCSymbolRefExpr::VK_AMDGPU_REL64:
650b57cec5SDimitry Andric return ELF::R_AMDGPU_REL64;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric switch (Fixup.getKind()) {
690b57cec5SDimitry Andric default: break;
700b57cec5SDimitry Andric case FK_PCRel_4:
710b57cec5SDimitry Andric return ELF::R_AMDGPU_REL32;
720b57cec5SDimitry Andric case FK_Data_4:
730b57cec5SDimitry Andric case FK_SecRel_4:
740b57cec5SDimitry Andric return ELF::R_AMDGPU_ABS32;
750b57cec5SDimitry Andric case FK_Data_8:
760b57cec5SDimitry Andric return ELF::R_AMDGPU_ABS64;
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric
795ffd83dbSDimitry Andric if (Fixup.getTargetKind() == AMDGPU::fixup_si_sopp_br) {
805ffd83dbSDimitry Andric const auto *SymA = Target.getSymA();
815ffd83dbSDimitry Andric assert(SymA);
825ffd83dbSDimitry Andric
83*5f7ddb14SDimitry Andric if (SymA->getSymbol().isUndefined()) {
84*5f7ddb14SDimitry Andric Ctx.reportError(Fixup.getLoc(), Twine("undefined label '") +
85*5f7ddb14SDimitry Andric SymA->getSymbol().getName() + "'");
865ffd83dbSDimitry Andric return ELF::R_AMDGPU_NONE;
875ffd83dbSDimitry Andric }
88*5f7ddb14SDimitry Andric return ELF::R_AMDGPU_REL16;
89*5f7ddb14SDimitry Andric }
905ffd83dbSDimitry Andric
910b57cec5SDimitry Andric llvm_unreachable("unhandled relocation type");
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createAMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend,uint8_t ABIVersion)950b57cec5SDimitry Andric llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
960b57cec5SDimitry Andric bool HasRelocationAddend,
970b57cec5SDimitry Andric uint8_t ABIVersion) {
988bcb0991SDimitry Andric return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
990b57cec5SDimitry Andric HasRelocationAddend,
1000b57cec5SDimitry Andric ABIVersion);
1010b57cec5SDimitry Andric }
102