xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
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 
AMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)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 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const360b57cec5SDimitry 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>
createAMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)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