blob: 885b3dbf80fada148d917e6969d2a4de29419bbb [file] [log] [blame]
Rui Ueyama21c0a9c2017-06-16 17:32:43 +00001//===- PPC64.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
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000010#include "Symbols.h"
11#include "SyntheticSections.h"
12#include "Target.h"
Bob Haarmanb8a59c82017-10-25 22:28:38 +000013#include "lld/Common/ErrorHandler.h"
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000014#include "llvm/Support/Endian.h"
15
16using namespace llvm;
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000017using namespace llvm::ELF;
18using namespace lld;
19using namespace lld::elf;
20
21static uint64_t PPC64TocOffset = 0x8000;
22
23uint64_t elf::getPPC64TocBase() {
24 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
25 // TOC starts where the first of these sections starts. We always create a
26 // .got when we see a relocation that uses it, so for us the start is always
27 // the .got.
28 uint64_t TocVA = InX::Got->getVA();
29
30 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
31 // thus permitting a full 64 Kbytes segment. Note that the glibc startup
32 // code (crt1.o) assumes that you can get from the TOC base to the
33 // start of the .toc section with only a single (signed) 16-bit relocation.
34 return TocVA + PPC64TocOffset;
35}
36
37namespace {
38class PPC64 final : public TargetInfo {
39public:
40 PPC64();
Rui Ueyamaf52496e2017-11-03 21:21:47 +000041 RelExpr getRelExpr(RelType Type, const Symbol &S,
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000042 const uint8_t *Loc) const override;
43 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
44 int32_t Index, unsigned RelOff) const override;
Rui Ueyama67533a22017-10-11 22:49:24 +000045 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000046};
47} // namespace
48
49// Relocation masks following the #lo(value), #hi(value), #ha(value),
50// #higher(value), #highera(value), #highest(value), and #highesta(value)
51// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
52// document.
53static uint16_t applyPPCLo(uint64_t V) { return V; }
54static uint16_t applyPPCHi(uint64_t V) { return V >> 16; }
55static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; }
56static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; }
57static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; }
58static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; }
59static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; }
60
61PPC64::PPC64() {
62 PltRel = GotRel = R_PPC64_GLOB_DAT;
63 RelativeRel = R_PPC64_RELATIVE;
64 GotEntrySize = 8;
65 GotPltEntrySize = 8;
66 PltEntrySize = 32;
67 PltHeaderSize = 0;
68
69 // We need 64K pages (at least under glibc/Linux, the loader won't
70 // set different permissions on a finer granularity than that).
71 DefaultMaxPageSize = 65536;
72
73 // The PPC64 ELF ABI v1 spec, says:
74 //
75 // It is normally desirable to put segments with different characteristics
76 // in separate 256 Mbyte portions of the address space, to give the
77 // operating system full paging flexibility in the 64-bit address space.
78 //
79 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
80 // use 0x10000000 as the starting address.
81 DefaultImageBase = 0x10000000;
82}
83
Rui Ueyamaf52496e2017-11-03 21:21:47 +000084RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
Rui Ueyamabe855292017-10-12 03:14:06 +000085 const uint8_t *Loc) const {
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000086 switch (Type) {
Rui Ueyama21c0a9c2017-06-16 17:32:43 +000087 case R_PPC64_TOC16:
88 case R_PPC64_TOC16_DS:
89 case R_PPC64_TOC16_HA:
90 case R_PPC64_TOC16_HI:
91 case R_PPC64_TOC16_LO:
92 case R_PPC64_TOC16_LO_DS:
93 return R_GOTREL;
94 case R_PPC64_TOC:
95 return R_PPC_TOC;
96 case R_PPC64_REL24:
97 return R_PPC_PLT_OPD;
Rui Ueyamabe855292017-10-12 03:14:06 +000098 default:
99 return R_ABS;
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000100 }
101}
102
103void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
104 uint64_t PltEntryAddr, int32_t Index,
105 unsigned RelOff) const {
106 uint64_t Off = GotPltEntryAddr - getPPC64TocBase();
107
108 // FIXME: What we should do, in theory, is get the offset of the function
109 // descriptor in the .opd section, and use that as the offset from %r2 (the
110 // TOC-base pointer). Instead, we have the GOT-entry offset, and that will
111 // be a pointer to the function descriptor in the .opd section. Using
112 // this scheme is simpler, but requires an extra indirection per PLT dispatch.
113
Fangrui Song0c483022018-03-09 18:03:22 +0000114 write32(Buf, 0xf8410028); // std %r2, 40(%r1)
115 write32(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
116 write32(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
117 write32(Buf + 12, 0xe96c0000); // ld %r11,0(%r12)
118 write32(Buf + 16, 0x7d6903a6); // mtctr %r11
119 write32(Buf + 20, 0xe84c0008); // ld %r2,8(%r12)
120 write32(Buf + 24, 0xe96c0010); // ld %r11,16(%r12)
121 write32(Buf + 28, 0x4e800420); // bctr
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000122}
123
Rui Ueyama67533a22017-10-11 22:49:24 +0000124static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000125 uint64_t V = Val - PPC64TocOffset;
126 switch (Type) {
127 case R_PPC64_TOC16:
128 return {R_PPC64_ADDR16, V};
129 case R_PPC64_TOC16_DS:
130 return {R_PPC64_ADDR16_DS, V};
131 case R_PPC64_TOC16_HA:
132 return {R_PPC64_ADDR16_HA, V};
133 case R_PPC64_TOC16_HI:
134 return {R_PPC64_ADDR16_HI, V};
135 case R_PPC64_TOC16_LO:
136 return {R_PPC64_ADDR16_LO, V};
137 case R_PPC64_TOC16_LO_DS:
138 return {R_PPC64_ADDR16_LO_DS, V};
139 default:
140 return {Type, Val};
141 }
142}
143
Rui Ueyama67533a22017-10-11 22:49:24 +0000144void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000145 // For a TOC-relative relocation, proceed in terms of the corresponding
146 // ADDR16 relocation type.
147 std::tie(Type, Val) = toAddr16Rel(Type, Val);
148
149 switch (Type) {
150 case R_PPC64_ADDR14: {
151 checkAlignment<4>(Loc, Val, Type);
152 // Preserve the AA/LK bits in the branch instruction
153 uint8_t AALK = Loc[3];
Fangrui Song0c483022018-03-09 18:03:22 +0000154 write16(Loc + 2, (AALK & 3) | (Val & 0xfffc));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000155 break;
156 }
157 case R_PPC64_ADDR16:
158 checkInt<16>(Loc, Val, Type);
Fangrui Song0c483022018-03-09 18:03:22 +0000159 write16(Loc, Val);
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000160 break;
161 case R_PPC64_ADDR16_DS:
162 checkInt<16>(Loc, Val, Type);
Fangrui Song0c483022018-03-09 18:03:22 +0000163 write16(Loc, (read16(Loc) & 3) | (Val & ~3));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000164 break;
165 case R_PPC64_ADDR16_HA:
166 case R_PPC64_REL16_HA:
Fangrui Song0c483022018-03-09 18:03:22 +0000167 write16(Loc, applyPPCHa(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000168 break;
169 case R_PPC64_ADDR16_HI:
170 case R_PPC64_REL16_HI:
Fangrui Song0c483022018-03-09 18:03:22 +0000171 write16(Loc, applyPPCHi(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000172 break;
173 case R_PPC64_ADDR16_HIGHER:
Fangrui Song0c483022018-03-09 18:03:22 +0000174 write16(Loc, applyPPCHigher(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000175 break;
176 case R_PPC64_ADDR16_HIGHERA:
Fangrui Song0c483022018-03-09 18:03:22 +0000177 write16(Loc, applyPPCHighera(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000178 break;
179 case R_PPC64_ADDR16_HIGHEST:
Fangrui Song0c483022018-03-09 18:03:22 +0000180 write16(Loc, applyPPCHighest(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000181 break;
182 case R_PPC64_ADDR16_HIGHESTA:
Fangrui Song0c483022018-03-09 18:03:22 +0000183 write16(Loc, applyPPCHighesta(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000184 break;
185 case R_PPC64_ADDR16_LO:
Fangrui Song0c483022018-03-09 18:03:22 +0000186 write16(Loc, applyPPCLo(Val));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000187 break;
188 case R_PPC64_ADDR16_LO_DS:
189 case R_PPC64_REL16_LO:
Fangrui Song0c483022018-03-09 18:03:22 +0000190 write16(Loc, (read16(Loc) & 3) | (applyPPCLo(Val) & ~3));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000191 break;
192 case R_PPC64_ADDR32:
193 case R_PPC64_REL32:
194 checkInt<32>(Loc, Val, Type);
Fangrui Song0c483022018-03-09 18:03:22 +0000195 write32(Loc, Val);
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000196 break;
197 case R_PPC64_ADDR64:
198 case R_PPC64_REL64:
199 case R_PPC64_TOC:
Fangrui Song0c483022018-03-09 18:03:22 +0000200 write64(Loc, Val);
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000201 break;
202 case R_PPC64_REL24: {
203 uint32_t Mask = 0x03FFFFFC;
204 checkInt<24>(Loc, Val, Type);
Fangrui Song0c483022018-03-09 18:03:22 +0000205 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
Rui Ueyama21c0a9c2017-06-16 17:32:43 +0000206 break;
207 }
208 default:
209 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
210 }
211}
212
Rui Ueyamae145bc22017-06-16 20:15:03 +0000213TargetInfo *elf::getPPC64TargetInfo() {
214 static PPC64 Target;
215 return &Target;
216}