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     return read32le(loc);
36   default:
37     error("TODO: Unhandled relocation type " + std::to_string(type));
38     return 0;
39   }
40 }
41 
42 void X86_64::relocateOne(uint8_t *loc, uint8_t type, uint64_t val) const {
43   switch (type) {
44   case X86_64_RELOC_SIGNED:
45     // This type is only used for pc-relative relocations, so offset by 4 since
46     // the RIP has advanced by 4 at this point.
47     write32le(loc, val - 4);
48     break;
49   default:
50     llvm_unreachable(
51         "getImplicitAddend should have flagged all unhandled relocation types");
52   }
53 }
54 
55 } // namespace
56 
57 TargetInfo *macho::createX86_64TargetInfo() {
58   static X86_64 t;
59   return &t;
60 }
61