AMDGPU.cpp revision 360784
1//===- AMDGPU.cpp ---------------------------------------------------------===// 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 "InputFiles.h" 10#include "Symbols.h" 11#include "Target.h" 12#include "lld/Common/ErrorHandler.h" 13#include "llvm/Object/ELF.h" 14#include "llvm/Support/Endian.h" 15 16using namespace llvm; 17using namespace llvm::object; 18using namespace llvm::support::endian; 19using namespace llvm::ELF; 20 21namespace lld { 22namespace elf { 23 24namespace { 25class AMDGPU final : public TargetInfo { 26public: 27 AMDGPU(); 28 uint32_t calcEFlags() const override; 29 void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; 30 RelExpr getRelExpr(RelType type, const Symbol &s, 31 const uint8_t *loc) const override; 32 RelType getDynRel(RelType type) const override; 33}; 34} // namespace 35 36AMDGPU::AMDGPU() { 37 relativeRel = R_AMDGPU_RELATIVE64; 38 gotRel = R_AMDGPU_ABS64; 39 noneRel = R_AMDGPU_NONE; 40 symbolicRel = R_AMDGPU_ABS64; 41} 42 43static uint32_t getEFlags(InputFile *file) { 44 return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader()->e_flags; 45} 46 47uint32_t AMDGPU::calcEFlags() const { 48 assert(!objectFiles.empty()); 49 uint32_t ret = getEFlags(objectFiles[0]); 50 51 // Verify that all input files have the same e_flags. 52 for (InputFile *f : makeArrayRef(objectFiles).slice(1)) { 53 if (ret == getEFlags(f)) 54 continue; 55 error("incompatible e_flags: " + toString(f)); 56 return 0; 57 } 58 return ret; 59} 60 61void AMDGPU::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { 62 switch (type) { 63 case R_AMDGPU_ABS32: 64 case R_AMDGPU_GOTPCREL: 65 case R_AMDGPU_GOTPCREL32_LO: 66 case R_AMDGPU_REL32: 67 case R_AMDGPU_REL32_LO: 68 write32le(loc, val); 69 break; 70 case R_AMDGPU_ABS64: 71 case R_AMDGPU_REL64: 72 write64le(loc, val); 73 break; 74 case R_AMDGPU_GOTPCREL32_HI: 75 case R_AMDGPU_REL32_HI: 76 write32le(loc, val >> 32); 77 break; 78 default: 79 llvm_unreachable("unknown relocation"); 80 } 81} 82 83RelExpr AMDGPU::getRelExpr(RelType type, const Symbol &s, 84 const uint8_t *loc) const { 85 switch (type) { 86 case R_AMDGPU_ABS32: 87 case R_AMDGPU_ABS64: 88 return R_ABS; 89 case R_AMDGPU_REL32: 90 case R_AMDGPU_REL32_LO: 91 case R_AMDGPU_REL32_HI: 92 case R_AMDGPU_REL64: 93 return R_PC; 94 case R_AMDGPU_GOTPCREL: 95 case R_AMDGPU_GOTPCREL32_LO: 96 case R_AMDGPU_GOTPCREL32_HI: 97 return R_GOT_PC; 98 default: 99 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + 100 ") against symbol " + toString(s)); 101 return R_NONE; 102 } 103} 104 105RelType AMDGPU::getDynRel(RelType type) const { 106 if (type == R_AMDGPU_ABS64) 107 return type; 108 return R_AMDGPU_NONE; 109} 110 111TargetInfo *getAMDGPUTargetInfo() { 112 static AMDGPU target; 113 return ⌖ 114} 115 116} // namespace elf 117} // namespace lld 118