xref: /src/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
171d5a254SDimitry Andric //===- AMDGPUELFObjectWriter.cpp - AMDGPU ELF Writer ----------------------===//
259d6cff9SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
659d6cff9SDimitry Andric //
759d6cff9SDimitry Andric //===----------------------------------------------------------------------===//
859d6cff9SDimitry Andric 
9cfca06d7SDimitry Andric #include "AMDGPUFixupKinds.h"
1059d6cff9SDimitry Andric #include "AMDGPUMCTargetDesc.h"
11cfca06d7SDimitry Andric #include "llvm/MC/MCContext.h"
1259d6cff9SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
1371d5a254SDimitry Andric #include "llvm/MC/MCValue.h"
1459d6cff9SDimitry Andric 
1559d6cff9SDimitry Andric using namespace llvm;
1659d6cff9SDimitry Andric 
1759d6cff9SDimitry Andric namespace {
1859d6cff9SDimitry Andric 
1959d6cff9SDimitry Andric class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter {
2059d6cff9SDimitry Andric public:
214df029ccSDimitry Andric   AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend);
2271d5a254SDimitry Andric 
2359d6cff9SDimitry Andric protected:
2401095a5dSDimitry Andric   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
2501095a5dSDimitry Andric                         const MCFixup &Fixup, bool IsPCRel) const override;
2659d6cff9SDimitry Andric };
2759d6cff9SDimitry Andric 
2859d6cff9SDimitry Andric 
2971d5a254SDimitry Andric } // end anonymous namespace
3059d6cff9SDimitry Andric 
AMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)314df029ccSDimitry Andric AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
324df029ccSDimitry Andric                                              bool HasRelocationAddend)
33044eb2f6SDimitry Andric     : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU,
344df029ccSDimitry Andric                               HasRelocationAddend) {}
3559d6cff9SDimitry Andric 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const3601095a5dSDimitry Andric unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
3701095a5dSDimitry Andric                                              const MCValue &Target,
3801095a5dSDimitry Andric                                              const MCFixup &Fixup,
3901095a5dSDimitry Andric                                              bool IsPCRel) const {
40b915e9e0SDimitry Andric   if (const auto *SymA = Target.getSymA()) {
4101095a5dSDimitry Andric     // SCRATCH_RSRC_DWORD[01] is a special global variable that represents
4201095a5dSDimitry Andric     // the scratch buffer.
43d8e91e46SDimitry Andric     if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" ||
44d8e91e46SDimitry Andric         SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1")
4501095a5dSDimitry Andric       return ELF::R_AMDGPU_ABS32_LO;
46b915e9e0SDimitry Andric   }
4701095a5dSDimitry Andric 
4801095a5dSDimitry Andric   switch (Target.getAccessVariant()) {
4901095a5dSDimitry Andric   default:
5001095a5dSDimitry Andric     break;
5101095a5dSDimitry Andric   case MCSymbolRefExpr::VK_GOTPCREL:
5201095a5dSDimitry Andric     return ELF::R_AMDGPU_GOTPCREL;
53b915e9e0SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO:
54b915e9e0SDimitry Andric     return ELF::R_AMDGPU_GOTPCREL32_LO;
55b915e9e0SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI:
56b915e9e0SDimitry Andric     return ELF::R_AMDGPU_GOTPCREL32_HI;
57b915e9e0SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL32_LO:
58b915e9e0SDimitry Andric     return ELF::R_AMDGPU_REL32_LO;
59b915e9e0SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
60b915e9e0SDimitry Andric     return ELF::R_AMDGPU_REL32_HI;
61eb11fae6SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL64:
62eb11fae6SDimitry Andric     return ELF::R_AMDGPU_REL64;
63b1c73532SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_ABS32_LO:
64b1c73532SDimitry Andric     return ELF::R_AMDGPU_ABS32_LO;
65b1c73532SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_ABS32_HI:
66b1c73532SDimitry Andric     return ELF::R_AMDGPU_ABS32_HI;
6701095a5dSDimitry Andric   }
6801095a5dSDimitry Andric 
69145449b1SDimitry Andric   MCFixupKind Kind = Fixup.getKind();
70145449b1SDimitry Andric   if (Kind >= FirstLiteralRelocationKind)
71145449b1SDimitry Andric     return Kind - FirstLiteralRelocationKind;
72145449b1SDimitry Andric   switch (Kind) {
7301095a5dSDimitry Andric   default: break;
7401095a5dSDimitry Andric   case FK_PCRel_4:
7501095a5dSDimitry Andric     return ELF::R_AMDGPU_REL32;
76b915e9e0SDimitry Andric   case FK_Data_4:
7701095a5dSDimitry Andric   case FK_SecRel_4:
787fa27ce4SDimitry Andric     return IsPCRel ? ELF::R_AMDGPU_REL32 : ELF::R_AMDGPU_ABS32;
79b915e9e0SDimitry Andric   case FK_Data_8:
807fa27ce4SDimitry Andric     return IsPCRel ? ELF::R_AMDGPU_REL64 : ELF::R_AMDGPU_ABS64;
8101095a5dSDimitry Andric   }
8201095a5dSDimitry Andric 
83cfca06d7SDimitry Andric   if (Fixup.getTargetKind() == AMDGPU::fixup_si_sopp_br) {
84cfca06d7SDimitry Andric     const auto *SymA = Target.getSymA();
85cfca06d7SDimitry Andric     assert(SymA);
86cfca06d7SDimitry Andric 
87344a3780SDimitry Andric     if (SymA->getSymbol().isUndefined()) {
88344a3780SDimitry Andric       Ctx.reportError(Fixup.getLoc(), Twine("undefined label '") +
89344a3780SDimitry Andric                                           SymA->getSymbol().getName() + "'");
90cfca06d7SDimitry Andric       return ELF::R_AMDGPU_NONE;
91cfca06d7SDimitry Andric     }
92344a3780SDimitry Andric     return ELF::R_AMDGPU_REL16;
93344a3780SDimitry Andric   }
94cfca06d7SDimitry Andric 
9501095a5dSDimitry Andric   llvm_unreachable("unhandled relocation type");
9601095a5dSDimitry Andric }
9701095a5dSDimitry Andric 
98eb11fae6SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createAMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)99044eb2f6SDimitry Andric llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
1004df029ccSDimitry Andric                                   bool HasRelocationAddend) {
1011d5ae102SDimitry Andric   return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
1024df029ccSDimitry Andric                                                  HasRelocationAddend);
10359d6cff9SDimitry Andric }
104