1218893Sdim//===- Target.cpp ---------------------------------------------------------===//
2218893Sdim//
3246259Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4246259Sdim// See https://llvm.org/LICENSE.txt for license information.
5218893Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6218893Sdim//
7218893Sdim//===----------------------------------------------------------------------===//
8243830Sdim//
9243830Sdim// Machine-specific things, such as applying relocations, creation of
10243830Sdim// GOT or PLT entries, etc., are handled in this file.
11218893Sdim//
12218893Sdim// Refer the ELF spec for the single letter variables, S, A or P, used
13218893Sdim// in this file.
14218893Sdim//
15239462Sdim// Some functions defined in this file has "relaxTls" as part of their names.
16226633Sdim// They do peephole optimization for TLS variables by rewriting instructions.
17221345Sdim// They are not part of the ABI but optional optimization, so you can skip
18218893Sdim// them if you are not interested in how TLS variables are optimized.
19218893Sdim// See the following paper for the details.
20226633Sdim//
21243830Sdim//   Ulrich Drepper, ELF Handling For Thread-Local Storage
22218893Sdim//   http://www.akkadia.org/drepper/tls.pdf
23218893Sdim//
24218893Sdim//===----------------------------------------------------------------------===//
25221345Sdim
26226633Sdim#include "Target.h"
27226633Sdim#include "InputFiles.h"
28226633Sdim#include "OutputSections.h"
29226633Sdim#include "SymbolTable.h"
30234353Sdim#include "Symbols.h"
31218893Sdim#include "SyntheticSections.h"
32218893Sdim#include "lld/Common/ErrorHandler.h"
33218893Sdim#include "llvm/Object/ELF.h"
34218893Sdim
35226633Sdimusing namespace llvm;
36218893Sdimusing namespace llvm::object;
37218893Sdimusing namespace llvm::ELF;
38218893Sdimusing namespace lld;
39218893Sdimusing namespace lld::elf;
40218893Sdim
41218893Sdimconst TargetInfo *elf::target;
42218893Sdim
43234353Sdimstd::string lld::toString(RelType type) {
44218893Sdim  StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
45218893Sdim  if (s == "Unknown")
46218893Sdim    return ("Unknown (" + Twine(type) + ")").str();
47218893Sdim  return std::string(s);
48218893Sdim}
49239462Sdim
50218893SdimTargetInfo *elf::getTarget() {
51218893Sdim  switch (config->emachine) {
52218893Sdim  case EM_386:
53218893Sdim  case EM_IAMCU:
54218893Sdim    return getX86TargetInfo();
55  case EM_AARCH64:
56    return getAArch64TargetInfo();
57  case EM_AMDGPU:
58    return getAMDGPUTargetInfo();
59  case EM_ARM:
60    return getARMTargetInfo();
61  case EM_AVR:
62    return getAVRTargetInfo();
63  case EM_HEXAGON:
64    return getHexagonTargetInfo();
65  case EM_MIPS:
66    switch (config->ekind) {
67    case ELF32LEKind:
68      return getMipsTargetInfo<ELF32LE>();
69    case ELF32BEKind:
70      return getMipsTargetInfo<ELF32BE>();
71    case ELF64LEKind:
72      return getMipsTargetInfo<ELF64LE>();
73    case ELF64BEKind:
74      return getMipsTargetInfo<ELF64BE>();
75    default:
76      llvm_unreachable("unsupported MIPS target");
77    }
78  case EM_MSP430:
79    return getMSP430TargetInfo();
80  case EM_PPC:
81    return getPPCTargetInfo();
82  case EM_PPC64:
83    return getPPC64TargetInfo();
84  case EM_RISCV:
85    return getRISCVTargetInfo();
86  case EM_SPARCV9:
87    return getSPARCV9TargetInfo();
88  case EM_X86_64:
89    return getX86_64TargetInfo();
90  }
91  llvm_unreachable("unknown target machine");
92}
93
94ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
95  assert(loc != nullptr);
96  for (InputSectionBase *d : ctx.inputSections) {
97    auto *isec = dyn_cast<InputSection>(d);
98    if (!isec || !isec->getParent() || (isec->type & SHT_NOBITS))
99      continue;
100
101    const uint8_t *isecLoc =
102        Out::bufferStart
103            ? (Out::bufferStart + isec->getParent()->offset + isec->outSecOff)
104            : isec->contentMaybeDecompress().data();
105    if (isecLoc == nullptr) {
106      assert(isa<SyntheticSection>(isec) && "No data but not synthetic?");
107      continue;
108    }
109    if (isecLoc <= loc && loc < isecLoc + isec->getSize()) {
110      std::string objLoc = isec->getLocation(loc - isecLoc);
111      // Return object file location and source file location.
112      // TODO: Refactor getSrcMsg not to take a variable.
113      Undefined dummy(nullptr, "", STB_LOCAL, 0, 0);
114      return {isec, objLoc + ": ",
115              isec->file ? isec->getSrcMsg(dummy, loc - isecLoc) : ""};
116    }
117  }
118  return {};
119}
120
121TargetInfo::~TargetInfo() {}
122
123int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
124  internalLinkerError(getErrorLocation(buf),
125                      "cannot read addend for relocation " + toString(type));
126  return 0;
127}
128
129bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
130
131bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
132                            uint64_t branchAddr, const Symbol &s,
133                            int64_t a) const {
134  return false;
135}
136
137bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
138                                                  uint8_t stOther) const {
139  llvm_unreachable("Target doesn't support split stacks.");
140}
141
142bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
143  return true;
144}
145
146RelExpr TargetInfo::adjustTlsExpr(RelType type, RelExpr expr) const {
147  return expr;
148}
149
150RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
151                                    const uint8_t *data) const {
152  return R_GOT_PC;
153}
154
155void TargetInfo::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
156  const unsigned bits = config->is64 ? 64 : 32;
157  uint64_t secAddr = sec.getOutputSection()->addr;
158  if (auto *s = dyn_cast<InputSection>(&sec))
159    secAddr += s->outSecOff;
160  for (const Relocation &rel : sec.relocs()) {
161    uint8_t *loc = buf + rel.offset;
162    const uint64_t val = SignExtend64(
163        sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
164                             secAddr + rel.offset, *rel.sym, rel.expr),
165        bits);
166    if (rel.expr != R_RELAX_HINT)
167      relocate(loc, rel, val);
168  }
169}
170
171uint64_t TargetInfo::getImageBase() const {
172  // Use --image-base if set. Fall back to the target default if not.
173  if (config->imageBase)
174    return *config->imageBase;
175  return config->isPic ? 0 : defaultImageBase;
176}
177