17a7e6055SDimitry Andric //===- AMDGPUELFObjectWriter.cpp - AMDGPU ELF Writer ----------------------===//
28f0fd8f6SDimitry Andric //
38f0fd8f6SDimitry Andric //                     The LLVM Compiler Infrastructure
48f0fd8f6SDimitry Andric //
58f0fd8f6SDimitry Andric // This file is distributed under the University of Illinois Open Source
68f0fd8f6SDimitry Andric // License. See LICENSE.TXT for details.
78f0fd8f6SDimitry Andric //
88f0fd8f6SDimitry Andric //===----------------------------------------------------------------------===//
98f0fd8f6SDimitry Andric 
108f0fd8f6SDimitry Andric #include "AMDGPUMCTargetDesc.h"
11db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
128f0fd8f6SDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
137a7e6055SDimitry Andric #include "llvm/MC/MCExpr.h"
148f0fd8f6SDimitry Andric #include "llvm/MC/MCFixup.h"
152cab237bSDimitry Andric #include "llvm/MC/MCObjectWriter.h"
167a7e6055SDimitry Andric #include "llvm/MC/MCSymbol.h"
177a7e6055SDimitry Andric #include "llvm/MC/MCValue.h"
187a7e6055SDimitry Andric #include "llvm/Support/ErrorHandling.h"
198f0fd8f6SDimitry Andric 
208f0fd8f6SDimitry Andric using namespace llvm;
218f0fd8f6SDimitry Andric 
228f0fd8f6SDimitry Andric namespace {
238f0fd8f6SDimitry Andric 
248f0fd8f6SDimitry Andric class AMDGPUELFObjectWriter : public MCELFObjectTargetWriter {
258f0fd8f6SDimitry Andric public:
262cab237bSDimitry Andric   AMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend);
277a7e6055SDimitry Andric 
288f0fd8f6SDimitry Andric protected:
293ca95b02SDimitry Andric   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
303ca95b02SDimitry Andric                         const MCFixup &Fixup, bool IsPCRel) const override;
318f0fd8f6SDimitry Andric };
328f0fd8f6SDimitry Andric 
338f0fd8f6SDimitry Andric 
347a7e6055SDimitry Andric } // end anonymous namespace
358f0fd8f6SDimitry Andric 
AMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)363ca95b02SDimitry Andric AMDGPUELFObjectWriter::AMDGPUELFObjectWriter(bool Is64Bit,
372cab237bSDimitry Andric                                              uint8_t OSABI,
383ca95b02SDimitry Andric                                              bool HasRelocationAddend)
392cab237bSDimitry Andric   : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_AMDGPU,
403ca95b02SDimitry Andric                             HasRelocationAddend) {}
418f0fd8f6SDimitry Andric 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const423ca95b02SDimitry Andric unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
433ca95b02SDimitry Andric                                              const MCValue &Target,
443ca95b02SDimitry Andric                                              const MCFixup &Fixup,
453ca95b02SDimitry Andric                                              bool IsPCRel) const {
46d88c1a5aSDimitry Andric   if (const auto *SymA = Target.getSymA()) {
473ca95b02SDimitry Andric     // SCRATCH_RSRC_DWORD[01] is a special global variable that represents
483ca95b02SDimitry Andric     // the scratch buffer.
49*b5893f02SDimitry Andric     if (SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD0" ||
50*b5893f02SDimitry Andric         SymA->getSymbol().getName() == "SCRATCH_RSRC_DWORD1")
513ca95b02SDimitry Andric       return ELF::R_AMDGPU_ABS32_LO;
52d88c1a5aSDimitry Andric   }
533ca95b02SDimitry Andric 
543ca95b02SDimitry Andric   switch (Target.getAccessVariant()) {
553ca95b02SDimitry Andric   default:
563ca95b02SDimitry Andric     break;
573ca95b02SDimitry Andric   case MCSymbolRefExpr::VK_GOTPCREL:
583ca95b02SDimitry Andric     return ELF::R_AMDGPU_GOTPCREL;
59d88c1a5aSDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_LO:
60d88c1a5aSDimitry Andric     return ELF::R_AMDGPU_GOTPCREL32_LO;
61d88c1a5aSDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_GOTPCREL32_HI:
62d88c1a5aSDimitry Andric     return ELF::R_AMDGPU_GOTPCREL32_HI;
63d88c1a5aSDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL32_LO:
64d88c1a5aSDimitry Andric     return ELF::R_AMDGPU_REL32_LO;
65d88c1a5aSDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
66d88c1a5aSDimitry Andric     return ELF::R_AMDGPU_REL32_HI;
674ba319b5SDimitry Andric   case MCSymbolRefExpr::VK_AMDGPU_REL64:
684ba319b5SDimitry Andric     return ELF::R_AMDGPU_REL64;
693ca95b02SDimitry Andric   }
703ca95b02SDimitry Andric 
713ca95b02SDimitry Andric   switch (Fixup.getKind()) {
723ca95b02SDimitry Andric   default: break;
733ca95b02SDimitry Andric   case FK_PCRel_4:
743ca95b02SDimitry Andric     return ELF::R_AMDGPU_REL32;
75d88c1a5aSDimitry Andric   case FK_Data_4:
763ca95b02SDimitry Andric   case FK_SecRel_4:
773ca95b02SDimitry Andric     return ELF::R_AMDGPU_ABS32;
78d88c1a5aSDimitry Andric   case FK_Data_8:
79d88c1a5aSDimitry Andric     return ELF::R_AMDGPU_ABS64;
803ca95b02SDimitry Andric   }
813ca95b02SDimitry Andric 
823ca95b02SDimitry Andric   llvm_unreachable("unhandled relocation type");
833ca95b02SDimitry Andric }
843ca95b02SDimitry Andric 
854ba319b5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createAMDGPUELFObjectWriter(bool Is64Bit,uint8_t OSABI,bool HasRelocationAddend)862cab237bSDimitry Andric llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
874ba319b5SDimitry Andric                                   bool HasRelocationAddend) {
884ba319b5SDimitry Andric   return llvm::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
892cab237bSDimitry Andric                                                   HasRelocationAddend);
908f0fd8f6SDimitry Andric }
91