1 //===- Relocations.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 "Relocations.h"
10 #include "Symbols.h"
11 #include "SyntheticSections.h"
12 #include "Target.h"
13 
14 #include "lld/Common/ErrorHandler.h"
15 
16 using namespace llvm;
17 using namespace lld;
18 using namespace lld::macho;
19 
20 static_assert(sizeof(void *) != 8 || sizeof(Reloc) == 24,
21               "Try to minimize Reloc's size; we create many instances");
22 
23 bool macho::validateSymbolRelocation(const Symbol *sym,
24                                      const InputSection *isec, const Reloc &r) {
25   const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
26   bool valid = true;
27   auto message = [relocAttrs, sym, isec, &valid](const Twine &diagnostic) {
28     valid = false;
29     return (relocAttrs.name + " relocation " + diagnostic + " for `" +
30             sym->getName() + "' in " + toString(isec))
31         .str();
32   };
33 
34   if (relocAttrs.hasAttr(RelocAttrBits::TLV) != sym->isTlv())
35     error(message(Twine("requires that variable ") +
36                   (sym->isTlv() ? "not " : "") + "be thread-local"));
37 
38   return valid;
39 }
40 
41 void macho::reportRangeError(const Reloc &r, const Twine &v, uint8_t bits,
42                              int64_t min, uint64_t max) {
43   std::string hint;
44   if (auto *sym = r.referent.dyn_cast<Symbol *>())
45     hint = "; references " + toString(*sym);
46   // TODO: get location of reloc using something like LLD-ELF's getErrorPlace()
47   error("relocation " + target->getRelocAttrs(r.type).name +
48         " is out of range: " + v + " is not in [" + Twine(min) + ", " +
49         Twine(max) + "]" + hint);
50 }
51 
52 void macho::reportRangeError(SymbolDiagnostic d, const Twine &v, uint8_t bits,
53                              int64_t min, uint64_t max) {
54   std::string hint;
55   if (d.symbol)
56     hint = "; references " + toString(*d.symbol);
57   error(d.reason + " is out of range: " + v + " is not in [" + Twine(min) +
58         ", " + Twine(max) + "]" + hint);
59 }
60 
61 const RelocAttrs macho::invalidRelocAttrs{"INVALID", RelocAttrBits::_0};
62