1 //===-- AMDGPUELFObjectWriter.cpp - AMDGPU ELF Writer ----------------------==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 /// \file
9 //===----------------------------------------------------------------------===//
10 
11 #include "AMDGPUMCTargetDesc.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCFixup.h"
14 
15 using namespace llvm;
16 
17 namespace {
18 
19 class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter {
20 public:
21   AMDGPUELFObjectWriter(bool Is64Bit, bool HasRelocationAddend);
22 protected:
23   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
24                         const MCFixup &Fixup, bool IsPCRel) const override;
25 };
26 
27 
28 } // End anonymous namespace
29 
30 AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit,
31                                              bool HasRelocationAddend)
32   : MCELFObjectTargetWriter(Is64Bit,
33                             ELF::ELFOSABI_AMDGPU_HSA,
34                             ELF::EM_AMDGPU,
35                             HasRelocationAddend) { }
36 
37 unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
38                                              const MCValue &Target,
39                                              const MCFixup &Fixup,
40                                              bool IsPCRel) const {
41   if (const auto *SymA = Target.getSymA()) {
42     // SCRATCH_RSRC_DWORD[01] is a special global variable that represents
43     // the scratch buffer.
44     if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0")
45       return ELF::R_AMDGPU_ABS32_LO;
46 
47     if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1")
48       return ELF::R_AMDGPU_ABS32_HI;
49   }
50 
51   switch (Target.getAccessVariant()) {
52   default:
53     break;
54   case MCSymbolRefExpr::VK_GOTPCREL:
55     return ELF::R_AMDGPU_GOTPCREL;
56   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO:
57     return ELF::R_AMDGPU_GOTPCREL32_LO;
58   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI:
59     return ELF::R_AMDGPU_GOTPCREL32_HI;
60   case MCSymbolRefExpr::VK_AMDGPU_REL32_LO:
61     return ELF::R_AMDGPU_REL32_LO;
62   case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
63     return ELF::R_AMDGPU_REL32_HI;
64   }
65 
66   switch (Fixup.getKind()) {
67   default: break;
68   case FK_PCRel_4:
69     return ELF::R_AMDGPU_REL32;
70   case FK_Data_4:
71   case FK_SecRel_4:
72     return ELF::R_AMDGPU_ABS32;
73   case FK_Data_8:
74     return ELF::R_AMDGPU_ABS64;
75   }
76 
77   llvm_unreachable("unhandled relocation type");
78 }
79 
80 
81 MCObjectWriter *llvm::createAMDGPUELFObjectWriter(bool Is64Bit,
82                                                   bool HasRelocationAddend,
83                                                   raw_pwrite_stream &OS) {
84   MCELFObjectTargetWriter *MOTW =
85       new AMDGPUELFObjectWriter(Is64Bit, HasRelocationAddend);
86   return createELFObjectWriter(MOTW, OS, true);
87 }
88