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 "AMDGPUMCTargetDesc.h"
10#include "llvm/BinaryFormat/ELF.h"
11#include "llvm/MC/MCELFObjectWriter.h"
12#include "llvm/MC/MCExpr.h"
13#include "llvm/MC/MCFixup.h"
14#include "llvm/MC/MCObjectWriter.h"
15#include "llvm/MC/MCSymbol.h"
16#include "llvm/MC/MCValue.h"
17#include "llvm/Support/ErrorHandling.h"
18
19using namespace llvm;
20
21namespace {
22
23class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter {
24public:
25  AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend,
26                        uint8_t ABIVersion);
27
28protected:
29  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
30                        const MCFixup &Fixup, bool IsPCRel) const override;
31};
32
33
34} // end anonymous namespace
35
36AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit,
37                                             uint8_t OSABI,
38                                             bool HasRelocationAddend,
39                                             uint8_t ABIVersion)
40  : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU,
41                            HasRelocationAddend, ABIVersion) {}
42
43unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
44                                             const MCValue &Target,
45                                             const MCFixup &Fixup,
46                                             bool IsPCRel) const {
47  if (const auto *SymA = Target.getSymA()) {
48    // SCRATCH_RSRC_DWORD[01] is a special global variable that represents
49    // the scratch buffer.
50    if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" ||
51        SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1")
52      return ELF::R_AMDGPU_ABS32_LO;
53  }
54
55  switch (Target.getAccessVariant()) {
56  default:
57    break;
58  case MCSymbolRefExpr::VK_GOTPCREL:
59    return ELF::R_AMDGPU_GOTPCREL;
60  case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO:
61    return ELF::R_AMDGPU_GOTPCREL32_LO;
62  case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI:
63    return ELF::R_AMDGPU_GOTPCREL32_HI;
64  case MCSymbolRefExpr::VK_AMDGPU_REL32_LO:
65    return ELF::R_AMDGPU_REL32_LO;
66  case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
67    return ELF::R_AMDGPU_REL32_HI;
68  case MCSymbolRefExpr::VK_AMDGPU_REL64:
69    return ELF::R_AMDGPU_REL64;
70  }
71
72  switch (Fixup.getKind()) {
73  default: break;
74  case FK_PCRel_4:
75    return ELF::R_AMDGPU_REL32;
76  case FK_Data_4:
77  case FK_SecRel_4:
78    return ELF::R_AMDGPU_ABS32;
79  case FK_Data_8:
80    return ELF::R_AMDGPU_ABS64;
81  }
82
83  llvm_unreachable("unhandled relocation type");
84}
85
86std::unique_ptr<MCObjectTargetWriter>
87llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
88                                  bool HasRelocationAddend,
89                                  uint8_t ABIVersion) {
90  return std::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
91                                                  HasRelocationAddend,
92                                                  ABIVersion);
93}
94