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