1 //===- X86_64.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 "Target.h"
10 #include "lld/Common/ErrorHandler.h"
11 #include "llvm/BinaryFormat/MachO.h"
12 #include "llvm/Support/Endian.h"
13 
14 using namespace llvm::MachO;
15 using namespace llvm::support::endian;
16 using namespace lld;
17 using namespace lld::macho;
18 
19 namespace {
20 
21 struct X86_64 : TargetInfo {
22   X86_64();
23   uint64_t getImplicitAddend(const uint8_t *loc, uint8_t type) const override;
24   void relocateOne(uint8_t *loc, uint8_t type, uint64_t val) const override;
25 };
26 
27 X86_64::X86_64() {
28   cpuType = CPU_TYPE_X86_64;
29   cpuSubtype = CPU_SUBTYPE_X86_64_ALL;
30 }
31 
32 uint64_t X86_64::getImplicitAddend(const uint8_t *loc, uint8_t type) const {
33   switch (type) {
34   case X86_64_RELOC_SIGNED:
35   case X86_64_RELOC_GOT_LOAD:
36     return read32le(loc);
37   default:
38     error("TODO: Unhandled relocation type " + std::to_string(type));
39     return 0;
40   }
41 }
42 
43 void X86_64::relocateOne(uint8_t *loc, uint8_t type, uint64_t val) const {
44   switch (type) {
45   case X86_64_RELOC_SIGNED:
46   case X86_64_RELOC_GOT_LOAD:
47     // These types are only used for pc-relative relocations, so offset by 4
48     // since the RIP has advanced by 4 at this point.
49     write32le(loc, val - 4);
50     break;
51   default:
52     llvm_unreachable(
53         "getImplicitAddend should have flagged all unhandled relocation types");
54   }
55 }
56 
57 } // namespace
58 
59 TargetInfo *macho::createX86_64TargetInfo() {
60   static X86_64 t;
61   return &t;
62 }
63