blob: 69a6dc6b2aaf63a4123a204c2ccff7029fcd506e [file] [log] [blame]
Rafael Espindola01205f72015-09-22 18:19:46 +00001//===- Target.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Target.h"
11
12#include "llvm/ADT/ArrayRef.h"
13#include "llvm/Support/Endian.h"
14#include "llvm/Support/ELF.h"
15
16using namespace llvm;
17using namespace llvm::ELF;
18
19namespace lld {
20namespace elf2 {
21
22std::unique_ptr<TargetInfo> Target;
23
24TargetInfo::~TargetInfo() {}
25
26X86TargetInfo::X86TargetInfo() { PCRelReloc = R_386_PC32; }
27
28void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
29 uint64_t PltEntryAddr) const {
30 ArrayRef<uint8_t> Jmp = {0xff, 0x25}; // jmpl *val
31 memcpy(Buf, Jmp.data(), Jmp.size());
32 Buf += Jmp.size();
33
34 assert(isUInt<32>(GotEntryAddr));
35 support::endian::write32le(Buf, GotEntryAddr);
36 Buf += 4;
37
38 ArrayRef<uint8_t> Nops = {0x90, 0x90};
39 memcpy(Buf, Nops.data(), Nops.size());
40}
41
42bool X86TargetInfo::relocNeedsGot(uint32_t Type) const {
43 if (relocNeedsPlt(Type))
44 return true;
45 switch (Type) {
46 default:
47 return false;
48 case R_386_GOT32:
49 return true;
50 }
51}
52
53bool X86TargetInfo::relocNeedsPlt(uint32_t Type) const {
54 switch (Type) {
55 default:
56 return false;
57 case R_386_PLT32:
58 return true;
59 }
60}
61
62X86_64TargetInfo::X86_64TargetInfo() { PCRelReloc = R_X86_64_PC32; }
63
64void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
65 uint64_t PltEntryAddr) const {
66 ArrayRef<uint8_t> Jmp = {0xff, 0x25}; // jmpq *val(%rip)
67 memcpy(Buf, Jmp.data(), Jmp.size());
68 Buf += Jmp.size();
69
70 uintptr_t NextPC = PltEntryAddr + 6;
Rafael Espindola8c21fad2015-09-22 20:06:19 +000071 intptr_t Delta = GotEntryAddr - NextPC;
Rafael Espindola01205f72015-09-22 18:19:46 +000072 assert(isInt<32>(Delta));
73 support::endian::write32le(Buf, Delta);
74 Buf += 4;
75
76 ArrayRef<uint8_t> Nops = {0x90, 0x90};
77 memcpy(Buf, Nops.data(), Nops.size());
78}
79
80bool X86_64TargetInfo::relocNeedsGot(uint32_t Type) const {
81 if (relocNeedsPlt(Type))
82 return true;
83 switch (Type) {
84 default:
85 return false;
86 case R_X86_64_GOTPCREL:
87 return true;
88 }
89}
90
91bool X86_64TargetInfo::relocNeedsPlt(uint32_t Type) const {
92 switch (Type) {
93 default:
94 return false;
95 case R_X86_64_PLT32:
96 return true;
97 }
98}
99}
100}