brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 86668c5 Raw
196 lines · cpp
1//===- SPARCV9.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Symbols.h"10#include "SyntheticSections.h"11#include "Target.h"12#include "llvm/Support/Endian.h"13 14using namespace llvm;15using namespace llvm::support::endian;16using namespace llvm::ELF;17using namespace lld;18using namespace lld::elf;19 20namespace {21class SPARCV9 final : public TargetInfo {22public:23  SPARCV9(Ctx &);24  RelExpr getRelExpr(RelType type, const Symbol &s,25                     const uint8_t *loc) const override;26  void writePlt(uint8_t *buf, const Symbol &sym,27                uint64_t pltEntryAddr) const override;28  void relocate(uint8_t *loc, const Relocation &rel,29                uint64_t val) const override;30};31} // namespace32 33SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {34  copyRel = R_SPARC_COPY;35  gotRel = R_SPARC_GLOB_DAT;36  pltRel = R_SPARC_JMP_SLOT;37  relativeRel = R_SPARC_RELATIVE;38  symbolicRel = R_SPARC_64;39  pltEntrySize = 32;40  pltHeaderSize = 4 * pltEntrySize;41 42  defaultCommonPageSize = 8192;43  defaultMaxPageSize = 0x100000;44  defaultImageBase = 0x100000;45}46 47RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,48                            const uint8_t *loc) const {49  switch (type) {50  case R_SPARC_32:51  case R_SPARC_UA32:52  case R_SPARC_64:53  case R_SPARC_UA64:54  case R_SPARC_H44:55  case R_SPARC_M44:56  case R_SPARC_L44:57  case R_SPARC_HH22:58  case R_SPARC_HM10:59  case R_SPARC_LM22:60  case R_SPARC_HI22:61  case R_SPARC_LO10:62    return R_ABS;63  case R_SPARC_PC10:64  case R_SPARC_PC22:65  case R_SPARC_DISP32:66  case R_SPARC_WDISP30:67    return R_PC;68  case R_SPARC_GOT10:69    return R_GOT_OFF;70  case R_SPARC_GOT22:71    return R_GOT_OFF;72  case R_SPARC_WPLT30:73    return R_PLT_PC;74  case R_SPARC_NONE:75    return R_NONE;76  case R_SPARC_TLS_LE_HIX22:77  case R_SPARC_TLS_LE_LOX10:78    return R_TPREL;79  default:80    Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v81             << ") against symbol " << &s;82    return R_NONE;83  }84}85 86void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,87                       uint64_t val) const {88  switch (rel.type) {89  case R_SPARC_32:90  case R_SPARC_UA32:91    // V-word3292    checkUInt(ctx, loc, val, 32, rel);93    write32be(loc, val);94    break;95  case R_SPARC_DISP32:96    // V-disp3297    checkInt(ctx, loc, val, 32, rel);98    write32be(loc, val);99    break;100  case R_SPARC_WDISP30:101  case R_SPARC_WPLT30:102    // V-disp30103    checkInt(ctx, loc, val, 32, rel);104    write32be(loc, (read32be(loc) & ~0x3fffffff) | ((val >> 2) & 0x3fffffff));105    break;106  case R_SPARC_22:107    // V-imm22108    checkUInt(ctx, loc, val, 22, rel);109    write32be(loc, (read32be(loc) & ~0x003fffff) | (val & 0x003fffff));110    break;111  case R_SPARC_GOT22:112  case R_SPARC_PC22:113  case R_SPARC_LM22:114    // T-imm22115    write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 10) & 0x003fffff));116    break;117  case R_SPARC_HI22:118    // V-imm22119    checkUInt(ctx, loc, val >> 10, 22, rel);120    write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 10) & 0x003fffff));121    break;122  case R_SPARC_WDISP19:123    // V-disp19124    checkInt(ctx, loc, val, 21, rel);125    write32be(loc, (read32be(loc) & ~0x0007ffff) | ((val >> 2) & 0x0007ffff));126    break;127  case R_SPARC_GOT10:128  case R_SPARC_PC10:129    // T-simm10130    write32be(loc, (read32be(loc) & ~0x000003ff) | (val & 0x000003ff));131    break;132  case R_SPARC_LO10:133    // T-simm13134    write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x000003ff));135    break;136  case R_SPARC_64:137  case R_SPARC_UA64:138    // V-xword64139    write64be(loc, val);140    break;141  case R_SPARC_HH22:142    // V-imm22143    checkUInt(ctx, loc, val >> 42, 22, rel);144    write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 42) & 0x003fffff));145    break;146  case R_SPARC_HM10:147    // T-simm13148    write32be(loc, (read32be(loc) & ~0x00001fff) | ((val >> 32) & 0x000003ff));149    break;150  case R_SPARC_H44:151    // V-imm22152    checkUInt(ctx, loc, val >> 22, 22, rel);153    write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 22) & 0x003fffff));154    break;155  case R_SPARC_M44:156    // T-imm10157    write32be(loc, (read32be(loc) & ~0x000003ff) | ((val >> 12) & 0x000003ff));158    break;159  case R_SPARC_L44:160    // T-imm13161    write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x00000fff));162    break;163  case R_SPARC_TLS_LE_HIX22:164    // T-imm22165    write32be(loc, (read32be(loc) & ~0x003fffff) | ((~val >> 10) & 0x003fffff));166    break;167  case R_SPARC_TLS_LE_LOX10:168    // T-simm13169    write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x000003ff) | 0x1C00);170    break;171  default:172    llvm_unreachable("unknown relocation");173  }174}175 176void SPARCV9::writePlt(uint8_t *buf, const Symbol & /*sym*/,177                       uint64_t pltEntryAddr) const {178  const uint8_t pltData[] = {179      0x03, 0x00, 0x00, 0x00, // sethi   (. - .PLT0), %g1180      0x30, 0x68, 0x00, 0x00, // ba,a    %xcc, .PLT1181      0x01, 0x00, 0x00, 0x00, // nop182      0x01, 0x00, 0x00, 0x00, // nop183      0x01, 0x00, 0x00, 0x00, // nop184      0x01, 0x00, 0x00, 0x00, // nop185      0x01, 0x00, 0x00, 0x00, // nop186      0x01, 0x00, 0x00, 0x00  // nop187  };188  memcpy(buf, pltData, sizeof(pltData));189 190  uint64_t off = pltEntryAddr - ctx.in.plt->getVA();191  relocateNoSym(buf, R_SPARC_22, off);192  relocateNoSym(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));193}194 195void elf::setSPARCV9TargetInfo(Ctx &ctx) { ctx.target.reset(new SPARCV9(ctx)); }196