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   }
57 
58   switch (Fixup.getKind()) {
59   default: break;
60   case FK_PCRel_4:
61     return ELF::R_AMDGPU_REL32;
62   case FK_Data_4:
63   case FK_SecRel_4:
64     return ELF::R_AMDGPU_ABS32;
65   case FK_Data_8:
66     return ELF::R_AMDGPU_ABS64;
67   }
68 
69   llvm_unreachable("unhandled relocation type");
70 }
71 
72 
73 MCObjectWriter *llvm::createAMDGPUELFObjectWriter(bool Is64Bit,
74                                                   bool HasRelocationAddend,
75                                                   raw_pwrite_stream &OS) {
76   MCELFObjectTargetWriter *MOTW =
77       new AMDGPUELFObjectWriter(Is64Bit, HasRelocationAddend);
78   return createELFObjectWriter(MOTW, OS, true);
79 }
80