1ece8a530Spatrick //===- PPC64.cpp ----------------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick
9*05edf1c1Srobert #include "InputFiles.h"
10*05edf1c1Srobert #include "OutputSections.h"
11bb684c34Spatrick #include "SymbolTable.h"
12ece8a530Spatrick #include "Symbols.h"
13ece8a530Spatrick #include "SyntheticSections.h"
14ece8a530Spatrick #include "Target.h"
15ece8a530Spatrick #include "Thunks.h"
16*05edf1c1Srobert #include "lld/Common/CommonLinkerContext.h"
17ece8a530Spatrick #include "llvm/Support/Endian.h"
18ece8a530Spatrick
19ece8a530Spatrick using namespace llvm;
20ece8a530Spatrick using namespace llvm::object;
21ece8a530Spatrick using namespace llvm::support::endian;
22ece8a530Spatrick using namespace llvm::ELF;
23bb684c34Spatrick using namespace lld;
24bb684c34Spatrick using namespace lld::elf;
25ece8a530Spatrick
261cf9926bSpatrick constexpr uint64_t ppc64TocOffset = 0x8000;
271cf9926bSpatrick constexpr uint64_t dynamicThreadPointerOffset = 0x8000;
28ece8a530Spatrick
29ece8a530Spatrick // The instruction encoding of bits 21-30 from the ISA for the Xform and Dform
30ece8a530Spatrick // instructions that can be used as part of the initial exec TLS sequence.
31ece8a530Spatrick enum XFormOpcd {
32ece8a530Spatrick LBZX = 87,
33ece8a530Spatrick LHZX = 279,
34ece8a530Spatrick LWZX = 23,
35ece8a530Spatrick LDX = 21,
36ece8a530Spatrick STBX = 215,
37ece8a530Spatrick STHX = 407,
38ece8a530Spatrick STWX = 151,
39ece8a530Spatrick STDX = 149,
40ece8a530Spatrick ADD = 266,
41ece8a530Spatrick };
42ece8a530Spatrick
43ece8a530Spatrick enum DFormOpcd {
44ece8a530Spatrick LBZ = 34,
45ece8a530Spatrick LBZU = 35,
46ece8a530Spatrick LHZ = 40,
47ece8a530Spatrick LHZU = 41,
48ece8a530Spatrick LHAU = 43,
49ece8a530Spatrick LWZ = 32,
50ece8a530Spatrick LWZU = 33,
51ece8a530Spatrick LFSU = 49,
52ece8a530Spatrick LD = 58,
53ece8a530Spatrick LFDU = 51,
54ece8a530Spatrick STB = 38,
55ece8a530Spatrick STBU = 39,
56ece8a530Spatrick STH = 44,
57ece8a530Spatrick STHU = 45,
58ece8a530Spatrick STW = 36,
59ece8a530Spatrick STWU = 37,
60ece8a530Spatrick STFSU = 53,
61ece8a530Spatrick STFDU = 55,
62ece8a530Spatrick STD = 62,
63ece8a530Spatrick ADDI = 14
64ece8a530Spatrick };
65ece8a530Spatrick
661cf9926bSpatrick constexpr uint32_t NOP = 0x60000000;
671cf9926bSpatrick
681cf9926bSpatrick enum class PPCLegacyInsn : uint32_t {
691cf9926bSpatrick NOINSN = 0,
701cf9926bSpatrick // Loads.
711cf9926bSpatrick LBZ = 0x88000000,
721cf9926bSpatrick LHZ = 0xa0000000,
731cf9926bSpatrick LWZ = 0x80000000,
741cf9926bSpatrick LHA = 0xa8000000,
751cf9926bSpatrick LWA = 0xe8000002,
761cf9926bSpatrick LD = 0xe8000000,
771cf9926bSpatrick LFS = 0xC0000000,
781cf9926bSpatrick LXSSP = 0xe4000003,
791cf9926bSpatrick LFD = 0xc8000000,
801cf9926bSpatrick LXSD = 0xe4000002,
811cf9926bSpatrick LXV = 0xf4000001,
821cf9926bSpatrick LXVP = 0x18000000,
831cf9926bSpatrick
841cf9926bSpatrick // Stores.
851cf9926bSpatrick STB = 0x98000000,
861cf9926bSpatrick STH = 0xb0000000,
871cf9926bSpatrick STW = 0x90000000,
881cf9926bSpatrick STD = 0xf8000000,
891cf9926bSpatrick STFS = 0xd0000000,
901cf9926bSpatrick STXSSP = 0xf4000003,
911cf9926bSpatrick STFD = 0xd8000000,
921cf9926bSpatrick STXSD = 0xf4000002,
931cf9926bSpatrick STXV = 0xf4000005,
941cf9926bSpatrick STXVP = 0x18000001
951cf9926bSpatrick };
961cf9926bSpatrick enum class PPCPrefixedInsn : uint64_t {
971cf9926bSpatrick NOINSN = 0,
981cf9926bSpatrick PREFIX_MLS = 0x0610000000000000,
991cf9926bSpatrick PREFIX_8LS = 0x0410000000000000,
1001cf9926bSpatrick
1011cf9926bSpatrick // Loads.
1021cf9926bSpatrick PLBZ = PREFIX_MLS,
1031cf9926bSpatrick PLHZ = PREFIX_MLS,
1041cf9926bSpatrick PLWZ = PREFIX_MLS,
1051cf9926bSpatrick PLHA = PREFIX_MLS,
1061cf9926bSpatrick PLWA = PREFIX_8LS | 0xa4000000,
1071cf9926bSpatrick PLD = PREFIX_8LS | 0xe4000000,
1081cf9926bSpatrick PLFS = PREFIX_MLS,
1091cf9926bSpatrick PLXSSP = PREFIX_8LS | 0xac000000,
1101cf9926bSpatrick PLFD = PREFIX_MLS,
1111cf9926bSpatrick PLXSD = PREFIX_8LS | 0xa8000000,
1121cf9926bSpatrick PLXV = PREFIX_8LS | 0xc8000000,
1131cf9926bSpatrick PLXVP = PREFIX_8LS | 0xe8000000,
1141cf9926bSpatrick
1151cf9926bSpatrick // Stores.
1161cf9926bSpatrick PSTB = PREFIX_MLS,
1171cf9926bSpatrick PSTH = PREFIX_MLS,
1181cf9926bSpatrick PSTW = PREFIX_MLS,
1191cf9926bSpatrick PSTD = PREFIX_8LS | 0xf4000000,
1201cf9926bSpatrick PSTFS = PREFIX_MLS,
1211cf9926bSpatrick PSTXSSP = PREFIX_8LS | 0xbc000000,
1221cf9926bSpatrick PSTFD = PREFIX_MLS,
1231cf9926bSpatrick PSTXSD = PREFIX_8LS | 0xb8000000,
1241cf9926bSpatrick PSTXV = PREFIX_8LS | 0xd8000000,
1251cf9926bSpatrick PSTXVP = PREFIX_8LS | 0xf8000000
1261cf9926bSpatrick };
checkPPCLegacyInsn(uint32_t encoding)1271cf9926bSpatrick static bool checkPPCLegacyInsn(uint32_t encoding) {
1281cf9926bSpatrick PPCLegacyInsn insn = static_cast<PPCLegacyInsn>(encoding);
1291cf9926bSpatrick if (insn == PPCLegacyInsn::NOINSN)
1301cf9926bSpatrick return false;
1311cf9926bSpatrick #define PCREL_OPT(Legacy, PCRel, InsnMask) \
1321cf9926bSpatrick if (insn == PPCLegacyInsn::Legacy) \
1331cf9926bSpatrick return true;
1341cf9926bSpatrick #include "PPCInsns.def"
1351cf9926bSpatrick #undef PCREL_OPT
1361cf9926bSpatrick return false;
1371cf9926bSpatrick }
1381cf9926bSpatrick
1391cf9926bSpatrick // Masks to apply to legacy instructions when converting them to prefixed,
1401cf9926bSpatrick // pc-relative versions. For the most part, the primary opcode is shared
1411cf9926bSpatrick // between the legacy instruction and the suffix of its prefixed version.
1421cf9926bSpatrick // However, there are some instances where that isn't the case (DS-Form and
1431cf9926bSpatrick // DQ-form instructions).
1441cf9926bSpatrick enum class LegacyToPrefixMask : uint64_t {
1451cf9926bSpatrick NOMASK = 0x0,
1461cf9926bSpatrick OPC_AND_RST = 0xffe00000, // Primary opc (0-5) and R[ST] (6-10).
1471cf9926bSpatrick ONLY_RST = 0x3e00000, // [RS]T (6-10).
1481cf9926bSpatrick ST_STX28_TO5 =
1491cf9926bSpatrick 0x8000000003e00000, // S/T (6-10) - The [S/T]X bit moves from 28 to 5.
1501cf9926bSpatrick };
1511cf9926bSpatrick
152*05edf1c1Srobert namespace {
153*05edf1c1Srobert class PPC64 final : public TargetInfo {
154*05edf1c1Srobert public:
155*05edf1c1Srobert PPC64();
156*05edf1c1Srobert int getTlsGdRelaxSkip(RelType type) const override;
157*05edf1c1Srobert uint32_t calcEFlags() const override;
158*05edf1c1Srobert RelExpr getRelExpr(RelType type, const Symbol &s,
159*05edf1c1Srobert const uint8_t *loc) const override;
160*05edf1c1Srobert RelType getDynRel(RelType type) const override;
161*05edf1c1Srobert int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
162*05edf1c1Srobert void writePltHeader(uint8_t *buf) const override;
163*05edf1c1Srobert void writePlt(uint8_t *buf, const Symbol &sym,
164*05edf1c1Srobert uint64_t pltEntryAddr) const override;
165*05edf1c1Srobert void writeIplt(uint8_t *buf, const Symbol &sym,
166*05edf1c1Srobert uint64_t pltEntryAddr) const override;
167*05edf1c1Srobert void relocate(uint8_t *loc, const Relocation &rel,
168*05edf1c1Srobert uint64_t val) const override;
169*05edf1c1Srobert void writeGotHeader(uint8_t *buf) const override;
170*05edf1c1Srobert bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
171*05edf1c1Srobert uint64_t branchAddr, const Symbol &s,
172*05edf1c1Srobert int64_t a) const override;
173*05edf1c1Srobert uint32_t getThunkSectionSpacing() const override;
174*05edf1c1Srobert bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override;
175*05edf1c1Srobert RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
176*05edf1c1Srobert RelExpr adjustGotPcExpr(RelType type, int64_t addend,
177*05edf1c1Srobert const uint8_t *loc) const override;
178*05edf1c1Srobert void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const;
179*05edf1c1Srobert void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
180*05edf1c1Srobert
181*05edf1c1Srobert bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
182*05edf1c1Srobert uint8_t stOther) const override;
183*05edf1c1Srobert
184*05edf1c1Srobert private:
185*05edf1c1Srobert void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
186*05edf1c1Srobert void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
187*05edf1c1Srobert void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
188*05edf1c1Srobert void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
189*05edf1c1Srobert };
190*05edf1c1Srobert } // namespace
191*05edf1c1Srobert
getPPC64TocBase()192bb684c34Spatrick uint64_t elf::getPPC64TocBase() {
193ece8a530Spatrick // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
194ece8a530Spatrick // TOC starts where the first of these sections starts. We always create a
195ece8a530Spatrick // .got when we see a relocation that uses it, so for us the start is always
196ece8a530Spatrick // the .got.
197ece8a530Spatrick uint64_t tocVA = in.got->getVA();
198ece8a530Spatrick
199ece8a530Spatrick // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
200ece8a530Spatrick // thus permitting a full 64 Kbytes segment. Note that the glibc startup
201ece8a530Spatrick // code (crt1.o) assumes that you can get from the TOC base to the
202ece8a530Spatrick // start of the .toc section with only a single (signed) 16-bit relocation.
203ece8a530Spatrick return tocVA + ppc64TocOffset;
204ece8a530Spatrick }
205ece8a530Spatrick
getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther)206bb684c34Spatrick unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther) {
207ece8a530Spatrick // The offset is encoded into the 3 most significant bits of the st_other
208ece8a530Spatrick // field, with some special values described in section 3.4.1 of the ABI:
209ece8a530Spatrick // 0 --> Zero offset between the GEP and LEP, and the function does NOT use
210ece8a530Spatrick // the TOC pointer (r2). r2 will hold the same value on returning from
211ece8a530Spatrick // the function as it did on entering the function.
212ece8a530Spatrick // 1 --> Zero offset between the GEP and LEP, and r2 should be treated as a
213ece8a530Spatrick // caller-saved register for all callers.
214ece8a530Spatrick // 2-6 --> The binary logarithm of the offset eg:
215ece8a530Spatrick // 2 --> 2^2 = 4 bytes --> 1 instruction.
216ece8a530Spatrick // 6 --> 2^6 = 64 bytes --> 16 instructions.
217ece8a530Spatrick // 7 --> Reserved.
218ece8a530Spatrick uint8_t gepToLep = (stOther >> 5) & 7;
219ece8a530Spatrick if (gepToLep < 2)
220ece8a530Spatrick return 0;
221ece8a530Spatrick
222ece8a530Spatrick // The value encoded in the st_other bits is the
223ece8a530Spatrick // log-base-2(offset).
224ece8a530Spatrick if (gepToLep < 7)
225ece8a530Spatrick return 1 << gepToLep;
226ece8a530Spatrick
227ece8a530Spatrick error("reserved value of 7 in the 3 most-significant-bits of st_other");
228ece8a530Spatrick return 0;
229ece8a530Spatrick }
230ece8a530Spatrick
writePrefixedInstruction(uint8_t * loc,uint64_t insn)2311cf9926bSpatrick void elf::writePrefixedInstruction(uint8_t *loc, uint64_t insn) {
2321cf9926bSpatrick insn = config->isLE ? insn << 32 | insn >> 32 : insn;
2331cf9926bSpatrick write64(loc, insn);
2341cf9926bSpatrick }
2351cf9926bSpatrick
addOptional(StringRef name,uint64_t value,std::vector<Defined * > & defined)236bb684c34Spatrick static bool addOptional(StringRef name, uint64_t value,
237bb684c34Spatrick std::vector<Defined *> &defined) {
238*05edf1c1Srobert Symbol *sym = symtab.find(name);
239bb684c34Spatrick if (!sym || sym->isDefined())
240bb684c34Spatrick return false;
241*05edf1c1Srobert sym->resolve(Defined{/*file=*/nullptr, StringRef(), STB_GLOBAL, STV_HIDDEN,
242*05edf1c1Srobert STT_FUNC, value,
243bb684c34Spatrick /*size=*/0, /*section=*/nullptr});
244bb684c34Spatrick defined.push_back(cast<Defined>(sym));
245bb684c34Spatrick return true;
246bb684c34Spatrick }
247bb684c34Spatrick
248bb684c34Spatrick // If from is 14, write ${prefix}14: firstInsn; ${prefix}15:
249bb684c34Spatrick // firstInsn+0x200008; ...; ${prefix}31: firstInsn+(31-14)*0x200008; $tail
250bb684c34Spatrick // The labels are defined only if they exist in the symbol table.
writeSequence(MutableArrayRef<uint32_t> buf,const char * prefix,int from,uint32_t firstInsn,ArrayRef<uint32_t> tail)251bb684c34Spatrick static void writeSequence(MutableArrayRef<uint32_t> buf, const char *prefix,
252bb684c34Spatrick int from, uint32_t firstInsn,
253bb684c34Spatrick ArrayRef<uint32_t> tail) {
254bb684c34Spatrick std::vector<Defined *> defined;
255bb684c34Spatrick char name[16];
256bb684c34Spatrick int first;
257bb684c34Spatrick uint32_t *ptr = buf.data();
258bb684c34Spatrick for (int r = from; r < 32; ++r) {
259bb684c34Spatrick format("%s%d", prefix, r).snprint(name, sizeof(name));
260bb684c34Spatrick if (addOptional(name, 4 * (r - from), defined) && defined.size() == 1)
261bb684c34Spatrick first = r - from;
262bb684c34Spatrick write32(ptr++, firstInsn + 0x200008 * (r - from));
263bb684c34Spatrick }
264bb684c34Spatrick for (uint32_t insn : tail)
265bb684c34Spatrick write32(ptr++, insn);
266bb684c34Spatrick assert(ptr == &*buf.end());
267bb684c34Spatrick
268bb684c34Spatrick if (defined.empty())
269bb684c34Spatrick return;
270bb684c34Spatrick // The full section content has the extent of [begin, end). We drop unused
271bb684c34Spatrick // instructions and write [first,end).
272bb684c34Spatrick auto *sec = make<InputSection>(
273bb684c34Spatrick nullptr, SHF_ALLOC, SHT_PROGBITS, 4,
274*05edf1c1Srobert ArrayRef(reinterpret_cast<uint8_t *>(buf.data() + first),
275bb684c34Spatrick 4 * (buf.size() - first)),
276bb684c34Spatrick ".text");
277*05edf1c1Srobert ctx.inputSections.push_back(sec);
278bb684c34Spatrick for (Defined *sym : defined) {
279bb684c34Spatrick sym->section = sec;
280bb684c34Spatrick sym->value -= 4 * first;
281bb684c34Spatrick }
282bb684c34Spatrick }
283bb684c34Spatrick
284bb684c34Spatrick // Implements some save and restore functions as described by ELF V2 ABI to be
285bb684c34Spatrick // compatible with GCC. With GCC -Os, when the number of call-saved registers
286bb684c34Spatrick // exceeds a certain threshold, GCC generates _savegpr0_* _restgpr0_* calls and
287bb684c34Spatrick // expects the linker to define them. See
288bb684c34Spatrick // https://sourceware.org/pipermail/binutils/2002-February/017444.html and
289bb684c34Spatrick // https://sourceware.org/pipermail/binutils/2004-August/036765.html . This is
290bb684c34Spatrick // weird because libgcc.a would be the natural place. The linker generation
291bb684c34Spatrick // approach has the advantage that the linker can generate multiple copies to
292bb684c34Spatrick // avoid long branch thunks. However, we don't consider the advantage
293bb684c34Spatrick // significant enough to complicate our trunk implementation, so we take the
294bb684c34Spatrick // simple approach and synthesize .text sections providing the implementation.
addPPC64SaveRestore()295bb684c34Spatrick void elf::addPPC64SaveRestore() {
296bb684c34Spatrick static uint32_t savegpr0[20], restgpr0[21], savegpr1[19], restgpr1[19];
297bb684c34Spatrick constexpr uint32_t blr = 0x4e800020, mtlr_0 = 0x7c0803a6;
298bb684c34Spatrick
299bb684c34Spatrick // _restgpr0_14: ld 14, -144(1); _restgpr0_15: ld 15, -136(1); ...
300bb684c34Spatrick // Tail: ld 0, 16(1); mtlr 0; blr
301bb684c34Spatrick writeSequence(restgpr0, "_restgpr0_", 14, 0xe9c1ff70,
302bb684c34Spatrick {0xe8010010, mtlr_0, blr});
303bb684c34Spatrick // _restgpr1_14: ld 14, -144(12); _restgpr1_15: ld 15, -136(12); ...
304bb684c34Spatrick // Tail: blr
305bb684c34Spatrick writeSequence(restgpr1, "_restgpr1_", 14, 0xe9ccff70, {blr});
306bb684c34Spatrick // _savegpr0_14: std 14, -144(1); _savegpr0_15: std 15, -136(1); ...
307bb684c34Spatrick // Tail: std 0, 16(1); blr
308bb684c34Spatrick writeSequence(savegpr0, "_savegpr0_", 14, 0xf9c1ff70, {0xf8010010, blr});
309bb684c34Spatrick // _savegpr1_14: std 14, -144(12); _savegpr1_15: std 15, -136(12); ...
310bb684c34Spatrick // Tail: blr
311bb684c34Spatrick writeSequence(savegpr1, "_savegpr1_", 14, 0xf9ccff70, {blr});
312bb684c34Spatrick }
313bb684c34Spatrick
314ece8a530Spatrick // Find the R_PPC64_ADDR64 in .rela.toc with matching offset.
315ece8a530Spatrick template <typename ELFT>
316ece8a530Spatrick static std::pair<Defined *, int64_t>
getRelaTocSymAndAddend(InputSectionBase * tocSec,uint64_t offset)317ece8a530Spatrick getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
318ece8a530Spatrick // .rela.toc contains exclusively R_PPC64_ADDR64 relocations sorted by
319ece8a530Spatrick // r_offset: 0, 8, 16, etc. For a given Offset, Offset / 8 gives us the
320ece8a530Spatrick // relocation index in most cases.
321ece8a530Spatrick //
322ece8a530Spatrick // In rare cases a TOC entry may store a constant that doesn't need an
323ece8a530Spatrick // R_PPC64_ADDR64, the corresponding r_offset is therefore missing. Offset / 8
324ece8a530Spatrick // points to a relocation with larger r_offset. Do a linear probe then.
325ece8a530Spatrick // Constants are extremely uncommon in .toc and the extra number of array
326ece8a530Spatrick // accesses can be seen as a small constant.
327*05edf1c1Srobert ArrayRef<typename ELFT::Rela> relas =
328*05edf1c1Srobert tocSec->template relsOrRelas<ELFT>().relas;
329*05edf1c1Srobert if (relas.empty())
330*05edf1c1Srobert return {};
331ece8a530Spatrick uint64_t index = std::min<uint64_t>(offset / 8, relas.size() - 1);
332ece8a530Spatrick for (;;) {
333ece8a530Spatrick if (relas[index].r_offset == offset) {
334ece8a530Spatrick Symbol &sym = tocSec->getFile<ELFT>()->getRelocTargetSym(relas[index]);
335ece8a530Spatrick return {dyn_cast<Defined>(&sym), getAddend<ELFT>(relas[index])};
336ece8a530Spatrick }
337ece8a530Spatrick if (relas[index].r_offset < offset || index == 0)
338ece8a530Spatrick break;
339ece8a530Spatrick --index;
340ece8a530Spatrick }
341ece8a530Spatrick return {};
342ece8a530Spatrick }
343ece8a530Spatrick
344ece8a530Spatrick // When accessing a symbol defined in another translation unit, compilers
345ece8a530Spatrick // reserve a .toc entry, allocate a local label and generate toc-indirect
346bb684c34Spatrick // instructions:
347ece8a530Spatrick //
348ece8a530Spatrick // addis 3, 2, .LC0@toc@ha # R_PPC64_TOC16_HA
349ece8a530Spatrick // ld 3, .LC0@toc@l(3) # R_PPC64_TOC16_LO_DS, load the address from a .toc entry
350ece8a530Spatrick // ld/lwa 3, 0(3) # load the value from the address
351ece8a530Spatrick //
352ece8a530Spatrick // .section .toc,"aw",@progbits
353ece8a530Spatrick // .LC0: .tc var[TC],var
354ece8a530Spatrick //
355ece8a530Spatrick // If var is defined, non-preemptable and addressable with a 32-bit signed
356ece8a530Spatrick // offset from the toc base, the address of var can be computed by adding an
357ece8a530Spatrick // offset to the toc base, saving a load.
358ece8a530Spatrick //
359ece8a530Spatrick // addis 3,2,var@toc@ha # this may be relaxed to a nop,
360ece8a530Spatrick // addi 3,3,var@toc@l # then this becomes addi 3,2,var@toc
361ece8a530Spatrick // ld/lwa 3, 0(3) # load the value from the address
362ece8a530Spatrick //
363ece8a530Spatrick // Returns true if the relaxation is performed.
tryRelaxPPC64TocIndirection(const Relocation & rel,uint8_t * bufLoc)364*05edf1c1Srobert static bool tryRelaxPPC64TocIndirection(const Relocation &rel,
365*05edf1c1Srobert uint8_t *bufLoc) {
366ece8a530Spatrick assert(config->tocOptimize);
367ece8a530Spatrick if (rel.addend < 0)
368ece8a530Spatrick return false;
369ece8a530Spatrick
370ece8a530Spatrick // If the symbol is not the .toc section, this isn't a toc-indirection.
371ece8a530Spatrick Defined *defSym = dyn_cast<Defined>(rel.sym);
372ece8a530Spatrick if (!defSym || !defSym->isSection() || defSym->section->name != ".toc")
373ece8a530Spatrick return false;
374ece8a530Spatrick
375ece8a530Spatrick Defined *d;
376ece8a530Spatrick int64_t addend;
377ece8a530Spatrick auto *tocISB = cast<InputSectionBase>(defSym->section);
378ece8a530Spatrick std::tie(d, addend) =
379ece8a530Spatrick config->isLE ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend)
380ece8a530Spatrick : getRelaTocSymAndAddend<ELF64BE>(tocISB, rel.addend);
381ece8a530Spatrick
382ece8a530Spatrick // Only non-preemptable defined symbols can be relaxed.
383ece8a530Spatrick if (!d || d->isPreemptible)
384ece8a530Spatrick return false;
385ece8a530Spatrick
386ece8a530Spatrick // R_PPC64_ADDR64 should have created a canonical PLT for the non-preemptable
387ece8a530Spatrick // ifunc and changed its type to STT_FUNC.
388ece8a530Spatrick assert(!d->isGnuIFunc());
389ece8a530Spatrick
390ece8a530Spatrick // Two instructions can materialize a 32-bit signed offset from the toc base.
391ece8a530Spatrick uint64_t tocRelative = d->getVA(addend) - getPPC64TocBase();
392ece8a530Spatrick if (!isInt<32>(tocRelative))
393ece8a530Spatrick return false;
394ece8a530Spatrick
395bb684c34Spatrick // Add PPC64TocOffset that will be subtracted by PPC64::relocate().
396*05edf1c1Srobert static_cast<const PPC64 &>(*target).relaxGot(bufLoc, rel,
397*05edf1c1Srobert tocRelative + ppc64TocOffset);
398ece8a530Spatrick return true;
399ece8a530Spatrick }
400ece8a530Spatrick
401ece8a530Spatrick // Relocation masks following the #lo(value), #hi(value), #ha(value),
402ece8a530Spatrick // #higher(value), #highera(value), #highest(value), and #highesta(value)
403ece8a530Spatrick // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
404ece8a530Spatrick // document.
lo(uint64_t v)405ece8a530Spatrick static uint16_t lo(uint64_t v) { return v; }
hi(uint64_t v)406ece8a530Spatrick static uint16_t hi(uint64_t v) { return v >> 16; }
ha(uint64_t v)4071cf9926bSpatrick static uint64_t ha(uint64_t v) { return (v + 0x8000) >> 16; }
higher(uint64_t v)408ece8a530Spatrick static uint16_t higher(uint64_t v) { return v >> 32; }
highera(uint64_t v)409ece8a530Spatrick static uint16_t highera(uint64_t v) { return (v + 0x8000) >> 32; }
highest(uint64_t v)410ece8a530Spatrick static uint16_t highest(uint64_t v) { return v >> 48; }
highesta(uint64_t v)411ece8a530Spatrick static uint16_t highesta(uint64_t v) { return (v + 0x8000) >> 48; }
412ece8a530Spatrick
413ece8a530Spatrick // Extracts the 'PO' field of an instruction encoding.
getPrimaryOpCode(uint32_t encoding)414ece8a530Spatrick static uint8_t getPrimaryOpCode(uint32_t encoding) { return (encoding >> 26); }
415ece8a530Spatrick
isDQFormInstruction(uint32_t encoding)416ece8a530Spatrick static bool isDQFormInstruction(uint32_t encoding) {
417ece8a530Spatrick switch (getPrimaryOpCode(encoding)) {
418ece8a530Spatrick default:
419ece8a530Spatrick return false;
4201cf9926bSpatrick case 6: // Power10 paired loads/stores (lxvp, stxvp).
421ece8a530Spatrick case 56:
422ece8a530Spatrick // The only instruction with a primary opcode of 56 is `lq`.
423ece8a530Spatrick return true;
424ece8a530Spatrick case 61:
425ece8a530Spatrick // There are both DS and DQ instruction forms with this primary opcode.
426ece8a530Spatrick // Namely `lxv` and `stxv` are the DQ-forms that use it.
427ece8a530Spatrick // The DS 'XO' bits being set to 01 is restricted to DQ form.
428ece8a530Spatrick return (encoding & 3) == 0x1;
429ece8a530Spatrick }
430ece8a530Spatrick }
431ece8a530Spatrick
isDSFormInstruction(PPCLegacyInsn insn)4321cf9926bSpatrick static bool isDSFormInstruction(PPCLegacyInsn insn) {
4331cf9926bSpatrick switch (insn) {
4341cf9926bSpatrick default:
4351cf9926bSpatrick return false;
4361cf9926bSpatrick case PPCLegacyInsn::LWA:
4371cf9926bSpatrick case PPCLegacyInsn::LD:
4381cf9926bSpatrick case PPCLegacyInsn::LXSD:
4391cf9926bSpatrick case PPCLegacyInsn::LXSSP:
4401cf9926bSpatrick case PPCLegacyInsn::STD:
4411cf9926bSpatrick case PPCLegacyInsn::STXSD:
4421cf9926bSpatrick case PPCLegacyInsn::STXSSP:
4431cf9926bSpatrick return true;
4441cf9926bSpatrick }
4451cf9926bSpatrick }
4461cf9926bSpatrick
getPPCLegacyInsn(uint32_t encoding)4471cf9926bSpatrick static PPCLegacyInsn getPPCLegacyInsn(uint32_t encoding) {
4481cf9926bSpatrick uint32_t opc = encoding & 0xfc000000;
4491cf9926bSpatrick
4501cf9926bSpatrick // If the primary opcode is shared between multiple instructions, we need to
4511cf9926bSpatrick // fix it up to match the actual instruction we are after.
4521cf9926bSpatrick if ((opc == 0xe4000000 || opc == 0xe8000000 || opc == 0xf4000000 ||
4531cf9926bSpatrick opc == 0xf8000000) &&
4541cf9926bSpatrick !isDQFormInstruction(encoding))
4551cf9926bSpatrick opc = encoding & 0xfc000003;
4561cf9926bSpatrick else if (opc == 0xf4000000)
4571cf9926bSpatrick opc = encoding & 0xfc000007;
4581cf9926bSpatrick else if (opc == 0x18000000)
4591cf9926bSpatrick opc = encoding & 0xfc00000f;
4601cf9926bSpatrick
4611cf9926bSpatrick // If the value is not one of the enumerators in PPCLegacyInsn, we want to
4621cf9926bSpatrick // return PPCLegacyInsn::NOINSN.
4631cf9926bSpatrick if (!checkPPCLegacyInsn(opc))
4641cf9926bSpatrick return PPCLegacyInsn::NOINSN;
4651cf9926bSpatrick return static_cast<PPCLegacyInsn>(opc);
4661cf9926bSpatrick }
4671cf9926bSpatrick
getPCRelativeForm(PPCLegacyInsn insn)4681cf9926bSpatrick static PPCPrefixedInsn getPCRelativeForm(PPCLegacyInsn insn) {
4691cf9926bSpatrick switch (insn) {
4701cf9926bSpatrick #define PCREL_OPT(Legacy, PCRel, InsnMask) \
4711cf9926bSpatrick case PPCLegacyInsn::Legacy: \
4721cf9926bSpatrick return PPCPrefixedInsn::PCRel
4731cf9926bSpatrick #include "PPCInsns.def"
4741cf9926bSpatrick #undef PCREL_OPT
4751cf9926bSpatrick }
4761cf9926bSpatrick return PPCPrefixedInsn::NOINSN;
4771cf9926bSpatrick }
4781cf9926bSpatrick
getInsnMask(PPCLegacyInsn insn)4791cf9926bSpatrick static LegacyToPrefixMask getInsnMask(PPCLegacyInsn insn) {
4801cf9926bSpatrick switch (insn) {
4811cf9926bSpatrick #define PCREL_OPT(Legacy, PCRel, InsnMask) \
4821cf9926bSpatrick case PPCLegacyInsn::Legacy: \
4831cf9926bSpatrick return LegacyToPrefixMask::InsnMask
4841cf9926bSpatrick #include "PPCInsns.def"
4851cf9926bSpatrick #undef PCREL_OPT
4861cf9926bSpatrick }
4871cf9926bSpatrick return LegacyToPrefixMask::NOMASK;
4881cf9926bSpatrick }
getPCRelativeForm(uint32_t encoding)4891cf9926bSpatrick static uint64_t getPCRelativeForm(uint32_t encoding) {
4901cf9926bSpatrick PPCLegacyInsn origInsn = getPPCLegacyInsn(encoding);
4911cf9926bSpatrick PPCPrefixedInsn pcrelInsn = getPCRelativeForm(origInsn);
4921cf9926bSpatrick if (pcrelInsn == PPCPrefixedInsn::NOINSN)
4931cf9926bSpatrick return UINT64_C(-1);
4941cf9926bSpatrick LegacyToPrefixMask origInsnMask = getInsnMask(origInsn);
4951cf9926bSpatrick uint64_t pcrelEncoding =
4961cf9926bSpatrick (uint64_t)pcrelInsn | (encoding & (uint64_t)origInsnMask);
4971cf9926bSpatrick
4981cf9926bSpatrick // If the mask requires moving bit 28 to bit 5, do that now.
4991cf9926bSpatrick if (origInsnMask == LegacyToPrefixMask::ST_STX28_TO5)
5001cf9926bSpatrick pcrelEncoding |= (encoding & 0x8) << 23;
5011cf9926bSpatrick return pcrelEncoding;
5021cf9926bSpatrick }
5031cf9926bSpatrick
isInstructionUpdateForm(uint32_t encoding)504ece8a530Spatrick static bool isInstructionUpdateForm(uint32_t encoding) {
505ece8a530Spatrick switch (getPrimaryOpCode(encoding)) {
506ece8a530Spatrick default:
507ece8a530Spatrick return false;
508ece8a530Spatrick case LBZU:
509ece8a530Spatrick case LHAU:
510ece8a530Spatrick case LHZU:
511ece8a530Spatrick case LWZU:
512ece8a530Spatrick case LFSU:
513ece8a530Spatrick case LFDU:
514ece8a530Spatrick case STBU:
515ece8a530Spatrick case STHU:
516ece8a530Spatrick case STWU:
517ece8a530Spatrick case STFSU:
518ece8a530Spatrick case STFDU:
519ece8a530Spatrick return true;
520ece8a530Spatrick // LWA has the same opcode as LD, and the DS bits is what differentiates
521ece8a530Spatrick // between LD/LDU/LWA
522ece8a530Spatrick case LD:
523ece8a530Spatrick case STD:
524ece8a530Spatrick return (encoding & 3) == 1;
525ece8a530Spatrick }
526ece8a530Spatrick }
527ece8a530Spatrick
5281cf9926bSpatrick // Compute the total displacement between the prefixed instruction that gets
5291cf9926bSpatrick // to the start of the data and the load/store instruction that has the offset
5301cf9926bSpatrick // into the data structure.
5311cf9926bSpatrick // For example:
5321cf9926bSpatrick // paddi 3, 0, 1000, 1
5331cf9926bSpatrick // lwz 3, 20(3)
5341cf9926bSpatrick // Should add up to 1020 for total displacement.
getTotalDisp(uint64_t prefixedInsn,uint32_t accessInsn)5351cf9926bSpatrick static int64_t getTotalDisp(uint64_t prefixedInsn, uint32_t accessInsn) {
5361cf9926bSpatrick int64_t disp34 = llvm::SignExtend64(
5371cf9926bSpatrick ((prefixedInsn & 0x3ffff00000000) >> 16) | (prefixedInsn & 0xffff), 34);
5381cf9926bSpatrick int32_t disp16 = llvm::SignExtend32(accessInsn & 0xffff, 16);
5391cf9926bSpatrick // For DS and DQ form instructions, we need to mask out the XO bits.
5401cf9926bSpatrick if (isDQFormInstruction(accessInsn))
5411cf9926bSpatrick disp16 &= ~0xf;
5421cf9926bSpatrick else if (isDSFormInstruction(getPPCLegacyInsn(accessInsn)))
5431cf9926bSpatrick disp16 &= ~0x3;
5441cf9926bSpatrick return disp34 + disp16;
5451cf9926bSpatrick }
5461cf9926bSpatrick
547ece8a530Spatrick // There are a number of places when we either want to read or write an
548ece8a530Spatrick // instruction when handling a half16 relocation type. On big-endian the buffer
549ece8a530Spatrick // pointer is pointing into the middle of the word we want to extract, and on
550ece8a530Spatrick // little-endian it is pointing to the start of the word. These 2 helpers are to
551ece8a530Spatrick // simplify reading and writing in that context.
writeFromHalf16(uint8_t * loc,uint32_t insn)552ece8a530Spatrick static void writeFromHalf16(uint8_t *loc, uint32_t insn) {
553ece8a530Spatrick write32(config->isLE ? loc : loc - 2, insn);
554ece8a530Spatrick }
555ece8a530Spatrick
readFromHalf16(const uint8_t * loc)556ece8a530Spatrick static uint32_t readFromHalf16(const uint8_t *loc) {
557ece8a530Spatrick return read32(config->isLE ? loc : loc - 2);
558ece8a530Spatrick }
559ece8a530Spatrick
readPrefixedInstruction(const uint8_t * loc)560bb684c34Spatrick static uint64_t readPrefixedInstruction(const uint8_t *loc) {
561bb684c34Spatrick uint64_t fullInstr = read64(loc);
562bb684c34Spatrick return config->isLE ? (fullInstr << 32 | fullInstr >> 32) : fullInstr;
563bb684c34Spatrick }
564bb684c34Spatrick
PPC64()565ece8a530Spatrick PPC64::PPC64() {
566ece8a530Spatrick copyRel = R_PPC64_COPY;
567ece8a530Spatrick gotRel = R_PPC64_GLOB_DAT;
568ece8a530Spatrick pltRel = R_PPC64_JMP_SLOT;
569ece8a530Spatrick relativeRel = R_PPC64_RELATIVE;
570ece8a530Spatrick iRelativeRel = R_PPC64_IRELATIVE;
571ece8a530Spatrick symbolicRel = R_PPC64_ADDR64;
5727be36224Skettenis #ifdef __OpenBSD__
5737be36224Skettenis pltHeaderSize = 52;
5747be36224Skettenis #else
575ece8a530Spatrick pltHeaderSize = 60;
5767be36224Skettenis #endif
577ece8a530Spatrick pltEntrySize = 4;
578ece8a530Spatrick ipltEntrySize = 16; // PPC64PltCallStub::size
579ece8a530Spatrick gotHeaderEntriesNum = 1;
580ece8a530Spatrick gotPltHeaderEntriesNum = 2;
581ece8a530Spatrick needsThunks = true;
582ece8a530Spatrick
583ece8a530Spatrick tlsModuleIndexRel = R_PPC64_DTPMOD64;
584ece8a530Spatrick tlsOffsetRel = R_PPC64_DTPREL64;
585ece8a530Spatrick
586ece8a530Spatrick tlsGotRel = R_PPC64_TPREL64;
587ece8a530Spatrick
588ece8a530Spatrick needsMoreStackNonSplit = false;
589ece8a530Spatrick
590ece8a530Spatrick // We need 64K pages (at least under glibc/Linux, the loader won't
591ece8a530Spatrick // set different permissions on a finer granularity than that).
592ece8a530Spatrick defaultMaxPageSize = 65536;
593ece8a530Spatrick
594ece8a530Spatrick // The PPC64 ELF ABI v1 spec, says:
595ece8a530Spatrick //
596ece8a530Spatrick // It is normally desirable to put segments with different characteristics
597ece8a530Spatrick // in separate 256 Mbyte portions of the address space, to give the
598ece8a530Spatrick // operating system full paging flexibility in the 64-bit address space.
599ece8a530Spatrick //
600ece8a530Spatrick // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
601ece8a530Spatrick // use 0x10000000 as the starting address.
602ece8a530Spatrick defaultImageBase = 0x10000000;
603ece8a530Spatrick
604ece8a530Spatrick write32(trapInstr.data(), 0x7fe00008);
605ece8a530Spatrick }
606ece8a530Spatrick
getTlsGdRelaxSkip(RelType type) const607ece8a530Spatrick int PPC64::getTlsGdRelaxSkip(RelType type) const {
608ece8a530Spatrick // A __tls_get_addr call instruction is marked with 2 relocations:
609ece8a530Spatrick //
610ece8a530Spatrick // R_PPC64_TLSGD / R_PPC64_TLSLD: marker relocation
611ece8a530Spatrick // R_PPC64_REL24: __tls_get_addr
612ece8a530Spatrick //
613ece8a530Spatrick // After the relaxation we no longer call __tls_get_addr and should skip both
614ece8a530Spatrick // relocations to not create a false dependence on __tls_get_addr being
615ece8a530Spatrick // defined.
616ece8a530Spatrick if (type == R_PPC64_TLSGD || type == R_PPC64_TLSLD)
617ece8a530Spatrick return 2;
618ece8a530Spatrick return 1;
619ece8a530Spatrick }
620ece8a530Spatrick
getEFlags(InputFile * file)621ece8a530Spatrick static uint32_t getEFlags(InputFile *file) {
622*05edf1c1Srobert if (file->ekind == ELF64BEKind)
6231cf9926bSpatrick return cast<ObjFile<ELF64BE>>(file)->getObj().getHeader().e_flags;
6241cf9926bSpatrick return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader().e_flags;
625ece8a530Spatrick }
626ece8a530Spatrick
627ece8a530Spatrick // This file implements v2 ABI. This function makes sure that all
628ece8a530Spatrick // object files have v2 or an unspecified version as an ABI version.
calcEFlags() const629ece8a530Spatrick uint32_t PPC64::calcEFlags() const {
630*05edf1c1Srobert for (InputFile *f : ctx.objectFiles) {
631ece8a530Spatrick uint32_t flag = getEFlags(f);
632ece8a530Spatrick if (flag == 1)
633ece8a530Spatrick error(toString(f) + ": ABI version 1 is not supported");
634ece8a530Spatrick else if (flag > 2)
635ece8a530Spatrick error(toString(f) + ": unrecognized e_flags: " + Twine(flag));
636ece8a530Spatrick }
637ece8a530Spatrick return 2;
638ece8a530Spatrick }
639ece8a530Spatrick
relaxGot(uint8_t * loc,const Relocation & rel,uint64_t val) const640bb684c34Spatrick void PPC64::relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) const {
641bb684c34Spatrick switch (rel.type) {
642ece8a530Spatrick case R_PPC64_TOC16_HA:
643ece8a530Spatrick // Convert "addis reg, 2, .LC0@toc@h" to "addis reg, 2, var@toc@h" or "nop".
644bb684c34Spatrick relocate(loc, rel, val);
645ece8a530Spatrick break;
646ece8a530Spatrick case R_PPC64_TOC16_LO_DS: {
647ece8a530Spatrick // Convert "ld reg, .LC0@toc@l(reg)" to "addi reg, reg, var@toc@l" or
648ece8a530Spatrick // "addi reg, 2, var@toc".
649ece8a530Spatrick uint32_t insn = readFromHalf16(loc);
650ece8a530Spatrick if (getPrimaryOpCode(insn) != LD)
651ece8a530Spatrick error("expected a 'ld' for got-indirect to toc-relative relaxing");
652ece8a530Spatrick writeFromHalf16(loc, (insn & 0x03ffffff) | 0x38000000);
653bb684c34Spatrick relocateNoSym(loc, R_PPC64_TOC16_LO, val);
654ece8a530Spatrick break;
655ece8a530Spatrick }
6561cf9926bSpatrick case R_PPC64_GOT_PCREL34: {
6571cf9926bSpatrick // Clear the first 8 bits of the prefix and the first 6 bits of the
6581cf9926bSpatrick // instruction (the primary opcode).
6591cf9926bSpatrick uint64_t insn = readPrefixedInstruction(loc);
6601cf9926bSpatrick if ((insn & 0xfc000000) != 0xe4000000)
6611cf9926bSpatrick error("expected a 'pld' for got-indirect to pc-relative relaxing");
6621cf9926bSpatrick insn &= ~0xff000000fc000000;
6631cf9926bSpatrick
6641cf9926bSpatrick // Replace the cleared bits with the values for PADDI (0x600000038000000);
6651cf9926bSpatrick insn |= 0x600000038000000;
6661cf9926bSpatrick writePrefixedInstruction(loc, insn);
6671cf9926bSpatrick relocate(loc, rel, val);
6681cf9926bSpatrick break;
6691cf9926bSpatrick }
6701cf9926bSpatrick case R_PPC64_PCREL_OPT: {
6711cf9926bSpatrick // We can only relax this if the R_PPC64_GOT_PCREL34 at this offset can
6721cf9926bSpatrick // be relaxed. The eligibility for the relaxation needs to be determined
6731cf9926bSpatrick // on that relocation since this one does not relocate a symbol.
6741cf9926bSpatrick uint64_t insn = readPrefixedInstruction(loc);
6751cf9926bSpatrick uint32_t accessInsn = read32(loc + rel.addend);
6761cf9926bSpatrick uint64_t pcRelInsn = getPCRelativeForm(accessInsn);
6771cf9926bSpatrick
6781cf9926bSpatrick // This error is not necessary for correctness but is emitted for now
6791cf9926bSpatrick // to ensure we don't miss these opportunities in real code. It can be
6801cf9926bSpatrick // removed at a later date.
6811cf9926bSpatrick if (pcRelInsn == UINT64_C(-1)) {
6821cf9926bSpatrick errorOrWarn(
6831cf9926bSpatrick "unrecognized instruction for R_PPC64_PCREL_OPT relaxation: 0x" +
6841cf9926bSpatrick Twine::utohexstr(accessInsn));
6851cf9926bSpatrick break;
6861cf9926bSpatrick }
6871cf9926bSpatrick
6881cf9926bSpatrick int64_t totalDisp = getTotalDisp(insn, accessInsn);
6891cf9926bSpatrick if (!isInt<34>(totalDisp))
6901cf9926bSpatrick break; // Displacement doesn't fit.
6911cf9926bSpatrick // Convert the PADDI to the prefixed version of accessInsn and convert
6921cf9926bSpatrick // accessInsn to a nop.
6931cf9926bSpatrick writePrefixedInstruction(loc, pcRelInsn |
6941cf9926bSpatrick ((totalDisp & 0x3ffff0000) << 16) |
6951cf9926bSpatrick (totalDisp & 0xffff));
6961cf9926bSpatrick write32(loc + rel.addend, NOP); // nop accessInsn.
6971cf9926bSpatrick break;
6981cf9926bSpatrick }
699ece8a530Spatrick default:
700ece8a530Spatrick llvm_unreachable("unexpected relocation type");
701ece8a530Spatrick }
702ece8a530Spatrick }
703ece8a530Spatrick
relaxTlsGdToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const704bb684c34Spatrick void PPC64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
705bb684c34Spatrick uint64_t val) const {
706ece8a530Spatrick // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement.
707ece8a530Spatrick // The general dynamic code sequence for a global `x` will look like:
708ece8a530Spatrick // Instruction Relocation Symbol
709ece8a530Spatrick // addis r3, r2, x@got@tlsgd@ha R_PPC64_GOT_TLSGD16_HA x
710ece8a530Spatrick // addi r3, r3, x@got@tlsgd@l R_PPC64_GOT_TLSGD16_LO x
711ece8a530Spatrick // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x
712ece8a530Spatrick // R_PPC64_REL24 __tls_get_addr
713ece8a530Spatrick // nop None None
714ece8a530Spatrick
715ece8a530Spatrick // Relaxing to local exec entails converting:
716ece8a530Spatrick // addis r3, r2, x@got@tlsgd@ha into nop
717ece8a530Spatrick // addi r3, r3, x@got@tlsgd@l into addis r3, r13, x@tprel@ha
718ece8a530Spatrick // bl __tls_get_addr(x@tlsgd) into nop
719ece8a530Spatrick // nop into addi r3, r3, x@tprel@l
720ece8a530Spatrick
721bb684c34Spatrick switch (rel.type) {
722ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HA:
7231cf9926bSpatrick writeFromHalf16(loc, NOP);
724ece8a530Spatrick break;
725ece8a530Spatrick case R_PPC64_GOT_TLSGD16:
726ece8a530Spatrick case R_PPC64_GOT_TLSGD16_LO:
727ece8a530Spatrick writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13
728bb684c34Spatrick relocateNoSym(loc, R_PPC64_TPREL16_HA, val);
729ece8a530Spatrick break;
7301cf9926bSpatrick case R_PPC64_GOT_TLSGD_PCREL34:
7311cf9926bSpatrick // Relax from paddi r3, 0, x@got@tlsgd@pcrel, 1 to
7321cf9926bSpatrick // paddi r3, r13, x@tprel, 0
7331cf9926bSpatrick writePrefixedInstruction(loc, 0x06000000386d0000);
7341cf9926bSpatrick relocateNoSym(loc, R_PPC64_TPREL34, val);
7351cf9926bSpatrick break;
7361cf9926bSpatrick case R_PPC64_TLSGD: {
7371cf9926bSpatrick // PC Relative Relaxation:
7381cf9926bSpatrick // Relax from bl __tls_get_addr@notoc(x@tlsgd) to
7391cf9926bSpatrick // nop
7401cf9926bSpatrick // TOC Relaxation:
7411cf9926bSpatrick // Relax from bl __tls_get_addr(x@tlsgd)
7421cf9926bSpatrick // nop
7431cf9926bSpatrick // to
7441cf9926bSpatrick // nop
7451cf9926bSpatrick // addi r3, r3, x@tprel@l
7461cf9926bSpatrick const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
7471cf9926bSpatrick if (locAsInt % 4 == 0) {
7481cf9926bSpatrick write32(loc, NOP); // nop
749ece8a530Spatrick write32(loc + 4, 0x38630000); // addi r3, r3
750ece8a530Spatrick // Since we are relocating a half16 type relocation and Loc + 4 points to
751ece8a530Spatrick // the start of an instruction we need to advance the buffer by an extra
752ece8a530Spatrick // 2 bytes on BE.
753bb684c34Spatrick relocateNoSym(loc + 4 + (config->ekind == ELF64BEKind ? 2 : 0),
754ece8a530Spatrick R_PPC64_TPREL16_LO, val);
7551cf9926bSpatrick } else if (locAsInt % 4 == 1) {
7561cf9926bSpatrick write32(loc - 1, NOP);
7571cf9926bSpatrick } else {
7581cf9926bSpatrick errorOrWarn("R_PPC64_TLSGD has unexpected byte alignment");
7591cf9926bSpatrick }
760ece8a530Spatrick break;
7611cf9926bSpatrick }
762ece8a530Spatrick default:
763ece8a530Spatrick llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
764ece8a530Spatrick }
765ece8a530Spatrick }
766ece8a530Spatrick
relaxTlsLdToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const767bb684c34Spatrick void PPC64::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
768bb684c34Spatrick uint64_t val) const {
769ece8a530Spatrick // Reference: 3.7.4.3 of the 64-bit ELF V2 abi supplement.
770ece8a530Spatrick // The local dynamic code sequence for a global `x` will look like:
771ece8a530Spatrick // Instruction Relocation Symbol
772ece8a530Spatrick // addis r3, r2, x@got@tlsld@ha R_PPC64_GOT_TLSLD16_HA x
773ece8a530Spatrick // addi r3, r3, x@got@tlsld@l R_PPC64_GOT_TLSLD16_LO x
774ece8a530Spatrick // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSLD x
775ece8a530Spatrick // R_PPC64_REL24 __tls_get_addr
776ece8a530Spatrick // nop None None
777ece8a530Spatrick
778ece8a530Spatrick // Relaxing to local exec entails converting:
779ece8a530Spatrick // addis r3, r2, x@got@tlsld@ha into nop
780ece8a530Spatrick // addi r3, r3, x@got@tlsld@l into addis r3, r13, 0
781ece8a530Spatrick // bl __tls_get_addr(x@tlsgd) into nop
782ece8a530Spatrick // nop into addi r3, r3, 4096
783ece8a530Spatrick
784bb684c34Spatrick switch (rel.type) {
785ece8a530Spatrick case R_PPC64_GOT_TLSLD16_HA:
7861cf9926bSpatrick writeFromHalf16(loc, NOP);
787ece8a530Spatrick break;
788ece8a530Spatrick case R_PPC64_GOT_TLSLD16_LO:
789ece8a530Spatrick writeFromHalf16(loc, 0x3c6d0000); // addis r3, r13, 0
790ece8a530Spatrick break;
7911cf9926bSpatrick case R_PPC64_GOT_TLSLD_PCREL34:
7921cf9926bSpatrick // Relax from paddi r3, 0, x1@got@tlsld@pcrel, 1 to
7931cf9926bSpatrick // paddi r3, r13, 0x1000, 0
7941cf9926bSpatrick writePrefixedInstruction(loc, 0x06000000386d1000);
795ece8a530Spatrick break;
7961cf9926bSpatrick case R_PPC64_TLSLD: {
7971cf9926bSpatrick // PC Relative Relaxation:
7981cf9926bSpatrick // Relax from bl __tls_get_addr@notoc(x@tlsld)
7991cf9926bSpatrick // to
8001cf9926bSpatrick // nop
8011cf9926bSpatrick // TOC Relaxation:
8021cf9926bSpatrick // Relax from bl __tls_get_addr(x@tlsld)
8031cf9926bSpatrick // nop
8041cf9926bSpatrick // to
8051cf9926bSpatrick // nop
8061cf9926bSpatrick // addi r3, r3, 4096
8071cf9926bSpatrick const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
8081cf9926bSpatrick if (locAsInt % 4 == 0) {
8091cf9926bSpatrick write32(loc, NOP);
8101cf9926bSpatrick write32(loc + 4, 0x38631000); // addi r3, r3, 4096
8111cf9926bSpatrick } else if (locAsInt % 4 == 1) {
8121cf9926bSpatrick write32(loc - 1, NOP);
8131cf9926bSpatrick } else {
8141cf9926bSpatrick errorOrWarn("R_PPC64_TLSLD has unexpected byte alignment");
8151cf9926bSpatrick }
8161cf9926bSpatrick break;
8171cf9926bSpatrick }
818ece8a530Spatrick case R_PPC64_DTPREL16:
819ece8a530Spatrick case R_PPC64_DTPREL16_HA:
820ece8a530Spatrick case R_PPC64_DTPREL16_HI:
821ece8a530Spatrick case R_PPC64_DTPREL16_DS:
822ece8a530Spatrick case R_PPC64_DTPREL16_LO:
823ece8a530Spatrick case R_PPC64_DTPREL16_LO_DS:
8241cf9926bSpatrick case R_PPC64_DTPREL34:
825bb684c34Spatrick relocate(loc, rel, val);
826ece8a530Spatrick break;
827ece8a530Spatrick default:
828ece8a530Spatrick llvm_unreachable("unsupported relocation for TLS LD to LE relaxation");
829ece8a530Spatrick }
830ece8a530Spatrick }
831ece8a530Spatrick
getPPCDFormOp(unsigned secondaryOp)832bb684c34Spatrick unsigned elf::getPPCDFormOp(unsigned secondaryOp) {
833ece8a530Spatrick switch (secondaryOp) {
834ece8a530Spatrick case LBZX:
835ece8a530Spatrick return LBZ;
836ece8a530Spatrick case LHZX:
837ece8a530Spatrick return LHZ;
838ece8a530Spatrick case LWZX:
839ece8a530Spatrick return LWZ;
840ece8a530Spatrick case LDX:
841ece8a530Spatrick return LD;
842ece8a530Spatrick case STBX:
843ece8a530Spatrick return STB;
844ece8a530Spatrick case STHX:
845ece8a530Spatrick return STH;
846ece8a530Spatrick case STWX:
847ece8a530Spatrick return STW;
848ece8a530Spatrick case STDX:
849ece8a530Spatrick return STD;
850ece8a530Spatrick case ADD:
851ece8a530Spatrick return ADDI;
852ece8a530Spatrick default:
853ece8a530Spatrick return 0;
854ece8a530Spatrick }
855ece8a530Spatrick }
856ece8a530Spatrick
relaxTlsIeToLe(uint8_t * loc,const Relocation & rel,uint64_t val) const857bb684c34Spatrick void PPC64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
858bb684c34Spatrick uint64_t val) const {
859ece8a530Spatrick // The initial exec code sequence for a global `x` will look like:
860ece8a530Spatrick // Instruction Relocation Symbol
861ece8a530Spatrick // addis r9, r2, x@got@tprel@ha R_PPC64_GOT_TPREL16_HA x
862ece8a530Spatrick // ld r9, x@got@tprel@l(r9) R_PPC64_GOT_TPREL16_LO_DS x
863ece8a530Spatrick // add r9, r9, x@tls R_PPC64_TLS x
864ece8a530Spatrick
865ece8a530Spatrick // Relaxing to local exec entails converting:
866ece8a530Spatrick // addis r9, r2, x@got@tprel@ha into nop
867ece8a530Spatrick // ld r9, x@got@tprel@l(r9) into addis r9, r13, x@tprel@ha
868ece8a530Spatrick // add r9, r9, x@tls into addi r9, r9, x@tprel@l
869ece8a530Spatrick
870ece8a530Spatrick // x@tls R_PPC64_TLS is a relocation which does not compute anything,
871ece8a530Spatrick // it is replaced with r13 (thread pointer).
872ece8a530Spatrick
873ece8a530Spatrick // The add instruction in the initial exec sequence has multiple variations
874ece8a530Spatrick // that need to be handled. If we are building an address it will use an add
875ece8a530Spatrick // instruction, if we are accessing memory it will use any of the X-form
876ece8a530Spatrick // indexed load or store instructions.
877ece8a530Spatrick
878ece8a530Spatrick unsigned offset = (config->ekind == ELF64BEKind) ? 2 : 0;
879bb684c34Spatrick switch (rel.type) {
880ece8a530Spatrick case R_PPC64_GOT_TPREL16_HA:
8811cf9926bSpatrick write32(loc - offset, NOP);
882ece8a530Spatrick break;
883ece8a530Spatrick case R_PPC64_GOT_TPREL16_LO_DS:
884ece8a530Spatrick case R_PPC64_GOT_TPREL16_DS: {
885ece8a530Spatrick uint32_t regNo = read32(loc - offset) & 0x03E00000; // bits 6-10
886ece8a530Spatrick write32(loc - offset, 0x3C0D0000 | regNo); // addis RegNo, r13
887bb684c34Spatrick relocateNoSym(loc, R_PPC64_TPREL16_HA, val);
888ece8a530Spatrick break;
889ece8a530Spatrick }
8901cf9926bSpatrick case R_PPC64_GOT_TPREL_PCREL34: {
8911cf9926bSpatrick const uint64_t pldRT = readPrefixedInstruction(loc) & 0x0000000003e00000;
8921cf9926bSpatrick // paddi RT(from pld), r13, symbol@tprel, 0
8931cf9926bSpatrick writePrefixedInstruction(loc, 0x06000000380d0000 | pldRT);
8941cf9926bSpatrick relocateNoSym(loc, R_PPC64_TPREL34, val);
8951cf9926bSpatrick break;
8961cf9926bSpatrick }
897ece8a530Spatrick case R_PPC64_TLS: {
8981cf9926bSpatrick const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
8991cf9926bSpatrick if (locAsInt % 4 == 0) {
900ece8a530Spatrick uint32_t primaryOp = getPrimaryOpCode(read32(loc));
901ece8a530Spatrick if (primaryOp != 31)
902ece8a530Spatrick error("unrecognized instruction for IE to LE R_PPC64_TLS");
903ece8a530Spatrick uint32_t secondaryOp = (read32(loc) & 0x000007FE) >> 1; // bits 21-30
904ece8a530Spatrick uint32_t dFormOp = getPPCDFormOp(secondaryOp);
905ece8a530Spatrick if (dFormOp == 0)
906ece8a530Spatrick error("unrecognized instruction for IE to LE R_PPC64_TLS");
907ece8a530Spatrick write32(loc, ((dFormOp << 26) | (read32(loc) & 0x03FFFFFF)));
908bb684c34Spatrick relocateNoSym(loc + offset, R_PPC64_TPREL16_LO, val);
9091cf9926bSpatrick } else if (locAsInt % 4 == 1) {
9101cf9926bSpatrick // If the offset is not 4 byte aligned then we have a PCRel type reloc.
9111cf9926bSpatrick // This version of the relocation is offset by one byte from the
9121cf9926bSpatrick // instruction it references.
9131cf9926bSpatrick uint32_t tlsInstr = read32(loc - 1);
9141cf9926bSpatrick uint32_t primaryOp = getPrimaryOpCode(tlsInstr);
9151cf9926bSpatrick if (primaryOp != 31)
9161cf9926bSpatrick errorOrWarn("unrecognized instruction for IE to LE R_PPC64_TLS");
9171cf9926bSpatrick uint32_t secondaryOp = (tlsInstr & 0x000007FE) >> 1; // bits 21-30
9181cf9926bSpatrick // The add is a special case and should be turned into a nop. The paddi
9191cf9926bSpatrick // that comes before it will already have computed the address of the
9201cf9926bSpatrick // symbol.
9211cf9926bSpatrick if (secondaryOp == 266) {
9221cf9926bSpatrick // Check if the add uses the same result register as the input register.
9231cf9926bSpatrick uint32_t rt = (tlsInstr & 0x03E00000) >> 21; // bits 6-10
9241cf9926bSpatrick uint32_t ra = (tlsInstr & 0x001F0000) >> 16; // bits 11-15
9251cf9926bSpatrick if (ra == rt) {
9261cf9926bSpatrick write32(loc - 1, NOP);
9271cf9926bSpatrick } else {
9281cf9926bSpatrick // mr rt, ra
9291cf9926bSpatrick write32(loc - 1, 0x7C000378 | (rt << 16) | (ra << 21) | (ra << 11));
9301cf9926bSpatrick }
9311cf9926bSpatrick } else {
9321cf9926bSpatrick uint32_t dFormOp = getPPCDFormOp(secondaryOp);
9331cf9926bSpatrick if (dFormOp == 0)
9341cf9926bSpatrick errorOrWarn("unrecognized instruction for IE to LE R_PPC64_TLS");
9351cf9926bSpatrick write32(loc - 1, ((dFormOp << 26) | (tlsInstr & 0x03FF0000)));
9361cf9926bSpatrick }
9371cf9926bSpatrick } else {
9381cf9926bSpatrick errorOrWarn("R_PPC64_TLS must be either 4 byte aligned or one byte "
9391cf9926bSpatrick "offset from 4 byte aligned");
9401cf9926bSpatrick }
941ece8a530Spatrick break;
942ece8a530Spatrick }
943ece8a530Spatrick default:
944ece8a530Spatrick llvm_unreachable("unknown relocation for IE to LE");
945ece8a530Spatrick break;
946ece8a530Spatrick }
947ece8a530Spatrick }
948ece8a530Spatrick
getRelExpr(RelType type,const Symbol & s,const uint8_t * loc) const949ece8a530Spatrick RelExpr PPC64::getRelExpr(RelType type, const Symbol &s,
950ece8a530Spatrick const uint8_t *loc) const {
951ece8a530Spatrick switch (type) {
952ece8a530Spatrick case R_PPC64_NONE:
953ece8a530Spatrick return R_NONE;
954ece8a530Spatrick case R_PPC64_ADDR16:
955ece8a530Spatrick case R_PPC64_ADDR16_DS:
956ece8a530Spatrick case R_PPC64_ADDR16_HA:
957ece8a530Spatrick case R_PPC64_ADDR16_HI:
9581cf9926bSpatrick case R_PPC64_ADDR16_HIGH:
959ece8a530Spatrick case R_PPC64_ADDR16_HIGHER:
960ece8a530Spatrick case R_PPC64_ADDR16_HIGHERA:
961ece8a530Spatrick case R_PPC64_ADDR16_HIGHEST:
962ece8a530Spatrick case R_PPC64_ADDR16_HIGHESTA:
963ece8a530Spatrick case R_PPC64_ADDR16_LO:
964ece8a530Spatrick case R_PPC64_ADDR16_LO_DS:
965ece8a530Spatrick case R_PPC64_ADDR32:
966ece8a530Spatrick case R_PPC64_ADDR64:
967ece8a530Spatrick return R_ABS;
968ece8a530Spatrick case R_PPC64_GOT16:
969ece8a530Spatrick case R_PPC64_GOT16_DS:
970ece8a530Spatrick case R_PPC64_GOT16_HA:
971ece8a530Spatrick case R_PPC64_GOT16_HI:
972ece8a530Spatrick case R_PPC64_GOT16_LO:
973ece8a530Spatrick case R_PPC64_GOT16_LO_DS:
974ece8a530Spatrick return R_GOT_OFF;
975ece8a530Spatrick case R_PPC64_TOC16:
976ece8a530Spatrick case R_PPC64_TOC16_DS:
977ece8a530Spatrick case R_PPC64_TOC16_HI:
978ece8a530Spatrick case R_PPC64_TOC16_LO:
979ece8a530Spatrick return R_GOTREL;
980bb684c34Spatrick case R_PPC64_GOT_PCREL34:
9811cf9926bSpatrick case R_PPC64_GOT_TPREL_PCREL34:
9821cf9926bSpatrick case R_PPC64_PCREL_OPT:
983bb684c34Spatrick return R_GOT_PC;
984ece8a530Spatrick case R_PPC64_TOC16_HA:
985ece8a530Spatrick case R_PPC64_TOC16_LO_DS:
986ece8a530Spatrick return config->tocOptimize ? R_PPC64_RELAX_TOC : R_GOTREL;
987ece8a530Spatrick case R_PPC64_TOC:
988ece8a530Spatrick return R_PPC64_TOCBASE;
989ece8a530Spatrick case R_PPC64_REL14:
990ece8a530Spatrick case R_PPC64_REL24:
991ece8a530Spatrick return R_PPC64_CALL_PLT;
992bb684c34Spatrick case R_PPC64_REL24_NOTOC:
993bb684c34Spatrick return R_PLT_PC;
994ece8a530Spatrick case R_PPC64_REL16_LO:
995ece8a530Spatrick case R_PPC64_REL16_HA:
996ece8a530Spatrick case R_PPC64_REL16_HI:
997ece8a530Spatrick case R_PPC64_REL32:
998ece8a530Spatrick case R_PPC64_REL64:
999bb684c34Spatrick case R_PPC64_PCREL34:
1000ece8a530Spatrick return R_PC;
1001ece8a530Spatrick case R_PPC64_GOT_TLSGD16:
1002ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HA:
1003ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HI:
1004ece8a530Spatrick case R_PPC64_GOT_TLSGD16_LO:
1005ece8a530Spatrick return R_TLSGD_GOT;
10061cf9926bSpatrick case R_PPC64_GOT_TLSGD_PCREL34:
10071cf9926bSpatrick return R_TLSGD_PC;
1008ece8a530Spatrick case R_PPC64_GOT_TLSLD16:
1009ece8a530Spatrick case R_PPC64_GOT_TLSLD16_HA:
1010ece8a530Spatrick case R_PPC64_GOT_TLSLD16_HI:
1011ece8a530Spatrick case R_PPC64_GOT_TLSLD16_LO:
1012ece8a530Spatrick return R_TLSLD_GOT;
10131cf9926bSpatrick case R_PPC64_GOT_TLSLD_PCREL34:
10141cf9926bSpatrick return R_TLSLD_PC;
1015ece8a530Spatrick case R_PPC64_GOT_TPREL16_HA:
1016ece8a530Spatrick case R_PPC64_GOT_TPREL16_LO_DS:
1017ece8a530Spatrick case R_PPC64_GOT_TPREL16_DS:
1018ece8a530Spatrick case R_PPC64_GOT_TPREL16_HI:
1019ece8a530Spatrick return R_GOT_OFF;
1020ece8a530Spatrick case R_PPC64_GOT_DTPREL16_HA:
1021ece8a530Spatrick case R_PPC64_GOT_DTPREL16_LO_DS:
1022ece8a530Spatrick case R_PPC64_GOT_DTPREL16_DS:
1023ece8a530Spatrick case R_PPC64_GOT_DTPREL16_HI:
1024ece8a530Spatrick return R_TLSLD_GOT_OFF;
1025ece8a530Spatrick case R_PPC64_TPREL16:
1026ece8a530Spatrick case R_PPC64_TPREL16_HA:
1027ece8a530Spatrick case R_PPC64_TPREL16_LO:
1028ece8a530Spatrick case R_PPC64_TPREL16_HI:
1029ece8a530Spatrick case R_PPC64_TPREL16_DS:
1030ece8a530Spatrick case R_PPC64_TPREL16_LO_DS:
1031ece8a530Spatrick case R_PPC64_TPREL16_HIGHER:
1032ece8a530Spatrick case R_PPC64_TPREL16_HIGHERA:
1033ece8a530Spatrick case R_PPC64_TPREL16_HIGHEST:
1034ece8a530Spatrick case R_PPC64_TPREL16_HIGHESTA:
10351cf9926bSpatrick case R_PPC64_TPREL34:
10361cf9926bSpatrick return R_TPREL;
1037ece8a530Spatrick case R_PPC64_DTPREL16:
1038ece8a530Spatrick case R_PPC64_DTPREL16_DS:
1039ece8a530Spatrick case R_PPC64_DTPREL16_HA:
1040ece8a530Spatrick case R_PPC64_DTPREL16_HI:
1041ece8a530Spatrick case R_PPC64_DTPREL16_HIGHER:
1042ece8a530Spatrick case R_PPC64_DTPREL16_HIGHERA:
1043ece8a530Spatrick case R_PPC64_DTPREL16_HIGHEST:
1044ece8a530Spatrick case R_PPC64_DTPREL16_HIGHESTA:
1045ece8a530Spatrick case R_PPC64_DTPREL16_LO:
1046ece8a530Spatrick case R_PPC64_DTPREL16_LO_DS:
1047ece8a530Spatrick case R_PPC64_DTPREL64:
10481cf9926bSpatrick case R_PPC64_DTPREL34:
1049ece8a530Spatrick return R_DTPREL;
1050ece8a530Spatrick case R_PPC64_TLSGD:
1051ece8a530Spatrick return R_TLSDESC_CALL;
1052ece8a530Spatrick case R_PPC64_TLSLD:
1053ece8a530Spatrick return R_TLSLD_HINT;
1054ece8a530Spatrick case R_PPC64_TLS:
1055ece8a530Spatrick return R_TLSIE_HINT;
1056ece8a530Spatrick default:
1057ece8a530Spatrick error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
1058ece8a530Spatrick ") against symbol " + toString(s));
1059ece8a530Spatrick return R_NONE;
1060ece8a530Spatrick }
1061ece8a530Spatrick }
1062ece8a530Spatrick
getDynRel(RelType type) const1063ece8a530Spatrick RelType PPC64::getDynRel(RelType type) const {
1064ece8a530Spatrick if (type == R_PPC64_ADDR64 || type == R_PPC64_TOC)
1065ece8a530Spatrick return R_PPC64_ADDR64;
1066ece8a530Spatrick return R_PPC64_NONE;
1067ece8a530Spatrick }
1068ece8a530Spatrick
getImplicitAddend(const uint8_t * buf,RelType type) const1069*05edf1c1Srobert int64_t PPC64::getImplicitAddend(const uint8_t *buf, RelType type) const {
1070*05edf1c1Srobert switch (type) {
1071*05edf1c1Srobert case R_PPC64_NONE:
1072*05edf1c1Srobert case R_PPC64_GLOB_DAT:
1073*05edf1c1Srobert case R_PPC64_JMP_SLOT:
1074*05edf1c1Srobert return 0;
1075*05edf1c1Srobert case R_PPC64_REL32:
1076*05edf1c1Srobert return SignExtend64<32>(read32(buf));
1077*05edf1c1Srobert case R_PPC64_ADDR64:
1078*05edf1c1Srobert case R_PPC64_REL64:
1079*05edf1c1Srobert case R_PPC64_RELATIVE:
1080*05edf1c1Srobert case R_PPC64_IRELATIVE:
1081*05edf1c1Srobert case R_PPC64_DTPMOD64:
1082*05edf1c1Srobert case R_PPC64_DTPREL64:
1083*05edf1c1Srobert case R_PPC64_TPREL64:
1084*05edf1c1Srobert return read64(buf);
1085*05edf1c1Srobert default:
1086*05edf1c1Srobert internalLinkerError(getErrorLocation(buf),
1087*05edf1c1Srobert "cannot read addend for relocation " + toString(type));
1088*05edf1c1Srobert return 0;
1089*05edf1c1Srobert }
1090*05edf1c1Srobert }
1091*05edf1c1Srobert
writeGotHeader(uint8_t * buf) const1092ece8a530Spatrick void PPC64::writeGotHeader(uint8_t *buf) const {
1093ece8a530Spatrick write64(buf, getPPC64TocBase());
1094ece8a530Spatrick }
1095ece8a530Spatrick
writePltHeader(uint8_t * buf) const1096ece8a530Spatrick void PPC64::writePltHeader(uint8_t *buf) const {
10977be36224Skettenis int64_t gotPltOffset = in.gotPlt->getVA() - (in.plt->getVA() + 8);
10987be36224Skettenis
1099ece8a530Spatrick // The generic resolver stub goes first.
1100ece8a530Spatrick write32(buf + 0, 0x7c0802a6); // mflr r0
1101ece8a530Spatrick write32(buf + 4, 0x429f0005); // bcl 20,4*cr7+so,8 <_glink+0x8>
1102ece8a530Spatrick write32(buf + 8, 0x7d6802a6); // mflr r11
1103ece8a530Spatrick write32(buf + 12, 0x7c0803a6); // mtlr r0
1104ece8a530Spatrick write32(buf + 16, 0x7d8b6050); // subf r12, r11, r12
11057be36224Skettenis #ifdef __OpenBSD__
11067be36224Skettenis write32(buf + 20, 0x380cffd4); // subi r0,r12,44
11077be36224Skettenis #else
1108ece8a530Spatrick write32(buf + 20, 0x380cffcc); // subi r0,r12,52
11097be36224Skettenis #endif
1110ece8a530Spatrick write32(buf + 24, 0x7800f082); // srdi r0,r0,62,2
11117be36224Skettenis #ifdef __OpenBSD__
11127be36224Skettenis write32(buf + 28, 0x3d6b0000 | ha(gotPltOffset)); // addis r11,r11,offset@ha
11137be36224Skettenis write32(buf + 32, 0x396b0000 | lo(gotPltOffset)); // addi r11,r11,offset@l
11147be36224Skettenis #else
1115ece8a530Spatrick write32(buf + 28, 0xe98b002c); // ld r12,44(r11)
1116ece8a530Spatrick write32(buf + 32, 0x7d6c5a14); // add r11,r12,r11
11177be36224Skettenis #endif
1118ece8a530Spatrick write32(buf + 36, 0xe98b0000); // ld r12,0(r11)
1119ece8a530Spatrick write32(buf + 40, 0xe96b0008); // ld r11,8(r11)
1120ece8a530Spatrick write32(buf + 44, 0x7d8903a6); // mtctr r12
1121ece8a530Spatrick write32(buf + 48, 0x4e800420); // bctr
1122ece8a530Spatrick
11237be36224Skettenis #ifndef __OpenBSD__
1124ece8a530Spatrick // The 'bcl' instruction will set the link register to the address of the
1125ece8a530Spatrick // following instruction ('mflr r11'). Here we store the offset from that
1126ece8a530Spatrick // instruction to the first entry in the GotPlt section.
1127ece8a530Spatrick write64(buf + 52, gotPltOffset);
11287be36224Skettenis #endif
1129ece8a530Spatrick }
1130ece8a530Spatrick
writePlt(uint8_t * buf,const Symbol & sym,uint64_t) const1131ece8a530Spatrick void PPC64::writePlt(uint8_t *buf, const Symbol &sym,
1132ece8a530Spatrick uint64_t /*pltEntryAddr*/) const {
1133*05edf1c1Srobert int32_t offset = pltHeaderSize + sym.getPltIdx() * pltEntrySize;
1134ece8a530Spatrick // bl __glink_PLTresolve
1135ece8a530Spatrick write32(buf, 0x48000000 | ((-offset) & 0x03FFFFFc));
1136ece8a530Spatrick }
1137ece8a530Spatrick
writeIplt(uint8_t * buf,const Symbol & sym,uint64_t) const1138ece8a530Spatrick void PPC64::writeIplt(uint8_t *buf, const Symbol &sym,
1139ece8a530Spatrick uint64_t /*pltEntryAddr*/) const {
1140ece8a530Spatrick writePPC64LoadAndBranch(buf, sym.getGotPltVA() - getPPC64TocBase());
1141ece8a530Spatrick }
1142ece8a530Spatrick
toAddr16Rel(RelType type,uint64_t val)1143ece8a530Spatrick static std::pair<RelType, uint64_t> toAddr16Rel(RelType type, uint64_t val) {
1144ece8a530Spatrick // Relocations relative to the toc-base need to be adjusted by the Toc offset.
1145ece8a530Spatrick uint64_t tocBiasedVal = val - ppc64TocOffset;
1146ece8a530Spatrick // Relocations relative to dtv[dtpmod] need to be adjusted by the DTP offset.
1147ece8a530Spatrick uint64_t dtpBiasedVal = val - dynamicThreadPointerOffset;
1148ece8a530Spatrick
1149ece8a530Spatrick switch (type) {
1150ece8a530Spatrick // TOC biased relocation.
1151ece8a530Spatrick case R_PPC64_GOT16:
1152ece8a530Spatrick case R_PPC64_GOT_TLSGD16:
1153ece8a530Spatrick case R_PPC64_GOT_TLSLD16:
1154ece8a530Spatrick case R_PPC64_TOC16:
1155ece8a530Spatrick return {R_PPC64_ADDR16, tocBiasedVal};
1156ece8a530Spatrick case R_PPC64_GOT16_DS:
1157ece8a530Spatrick case R_PPC64_TOC16_DS:
1158ece8a530Spatrick case R_PPC64_GOT_TPREL16_DS:
1159ece8a530Spatrick case R_PPC64_GOT_DTPREL16_DS:
1160ece8a530Spatrick return {R_PPC64_ADDR16_DS, tocBiasedVal};
1161ece8a530Spatrick case R_PPC64_GOT16_HA:
1162ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HA:
1163ece8a530Spatrick case R_PPC64_GOT_TLSLD16_HA:
1164ece8a530Spatrick case R_PPC64_GOT_TPREL16_HA:
1165ece8a530Spatrick case R_PPC64_GOT_DTPREL16_HA:
1166ece8a530Spatrick case R_PPC64_TOC16_HA:
1167ece8a530Spatrick return {R_PPC64_ADDR16_HA, tocBiasedVal};
1168ece8a530Spatrick case R_PPC64_GOT16_HI:
1169ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HI:
1170ece8a530Spatrick case R_PPC64_GOT_TLSLD16_HI:
1171ece8a530Spatrick case R_PPC64_GOT_TPREL16_HI:
1172ece8a530Spatrick case R_PPC64_GOT_DTPREL16_HI:
1173ece8a530Spatrick case R_PPC64_TOC16_HI:
1174ece8a530Spatrick return {R_PPC64_ADDR16_HI, tocBiasedVal};
1175ece8a530Spatrick case R_PPC64_GOT16_LO:
1176ece8a530Spatrick case R_PPC64_GOT_TLSGD16_LO:
1177ece8a530Spatrick case R_PPC64_GOT_TLSLD16_LO:
1178ece8a530Spatrick case R_PPC64_TOC16_LO:
1179ece8a530Spatrick return {R_PPC64_ADDR16_LO, tocBiasedVal};
1180ece8a530Spatrick case R_PPC64_GOT16_LO_DS:
1181ece8a530Spatrick case R_PPC64_TOC16_LO_DS:
1182ece8a530Spatrick case R_PPC64_GOT_TPREL16_LO_DS:
1183ece8a530Spatrick case R_PPC64_GOT_DTPREL16_LO_DS:
1184ece8a530Spatrick return {R_PPC64_ADDR16_LO_DS, tocBiasedVal};
1185ece8a530Spatrick
1186ece8a530Spatrick // Dynamic Thread pointer biased relocation types.
1187ece8a530Spatrick case R_PPC64_DTPREL16:
1188ece8a530Spatrick return {R_PPC64_ADDR16, dtpBiasedVal};
1189ece8a530Spatrick case R_PPC64_DTPREL16_DS:
1190ece8a530Spatrick return {R_PPC64_ADDR16_DS, dtpBiasedVal};
1191ece8a530Spatrick case R_PPC64_DTPREL16_HA:
1192ece8a530Spatrick return {R_PPC64_ADDR16_HA, dtpBiasedVal};
1193ece8a530Spatrick case R_PPC64_DTPREL16_HI:
1194ece8a530Spatrick return {R_PPC64_ADDR16_HI, dtpBiasedVal};
1195ece8a530Spatrick case R_PPC64_DTPREL16_HIGHER:
1196ece8a530Spatrick return {R_PPC64_ADDR16_HIGHER, dtpBiasedVal};
1197ece8a530Spatrick case R_PPC64_DTPREL16_HIGHERA:
1198ece8a530Spatrick return {R_PPC64_ADDR16_HIGHERA, dtpBiasedVal};
1199ece8a530Spatrick case R_PPC64_DTPREL16_HIGHEST:
1200ece8a530Spatrick return {R_PPC64_ADDR16_HIGHEST, dtpBiasedVal};
1201ece8a530Spatrick case R_PPC64_DTPREL16_HIGHESTA:
1202ece8a530Spatrick return {R_PPC64_ADDR16_HIGHESTA, dtpBiasedVal};
1203ece8a530Spatrick case R_PPC64_DTPREL16_LO:
1204ece8a530Spatrick return {R_PPC64_ADDR16_LO, dtpBiasedVal};
1205ece8a530Spatrick case R_PPC64_DTPREL16_LO_DS:
1206ece8a530Spatrick return {R_PPC64_ADDR16_LO_DS, dtpBiasedVal};
1207ece8a530Spatrick case R_PPC64_DTPREL64:
1208ece8a530Spatrick return {R_PPC64_ADDR64, dtpBiasedVal};
1209ece8a530Spatrick
1210ece8a530Spatrick default:
1211ece8a530Spatrick return {type, val};
1212ece8a530Spatrick }
1213ece8a530Spatrick }
1214ece8a530Spatrick
isTocOptType(RelType type)1215ece8a530Spatrick static bool isTocOptType(RelType type) {
1216ece8a530Spatrick switch (type) {
1217ece8a530Spatrick case R_PPC64_GOT16_HA:
1218ece8a530Spatrick case R_PPC64_GOT16_LO_DS:
1219ece8a530Spatrick case R_PPC64_TOC16_HA:
1220ece8a530Spatrick case R_PPC64_TOC16_LO_DS:
1221ece8a530Spatrick case R_PPC64_TOC16_LO:
1222ece8a530Spatrick return true;
1223ece8a530Spatrick default:
1224ece8a530Spatrick return false;
1225ece8a530Spatrick }
1226ece8a530Spatrick }
1227ece8a530Spatrick
relocate(uint8_t * loc,const Relocation & rel,uint64_t val) const1228bb684c34Spatrick void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
1229bb684c34Spatrick RelType type = rel.type;
1230ece8a530Spatrick bool shouldTocOptimize = isTocOptType(type);
1231ece8a530Spatrick // For dynamic thread pointer relative, toc-relative, and got-indirect
1232ece8a530Spatrick // relocations, proceed in terms of the corresponding ADDR16 relocation type.
1233ece8a530Spatrick std::tie(type, val) = toAddr16Rel(type, val);
1234ece8a530Spatrick
1235ece8a530Spatrick switch (type) {
1236ece8a530Spatrick case R_PPC64_ADDR14: {
1237bb684c34Spatrick checkAlignment(loc, val, 4, rel);
1238ece8a530Spatrick // Preserve the AA/LK bits in the branch instruction
1239ece8a530Spatrick uint8_t aalk = loc[3];
1240ece8a530Spatrick write16(loc + 2, (aalk & 3) | (val & 0xfffc));
1241ece8a530Spatrick break;
1242ece8a530Spatrick }
1243ece8a530Spatrick case R_PPC64_ADDR16:
1244bb684c34Spatrick checkIntUInt(loc, val, 16, rel);
1245ece8a530Spatrick write16(loc, val);
1246ece8a530Spatrick break;
1247ece8a530Spatrick case R_PPC64_ADDR32:
1248bb684c34Spatrick checkIntUInt(loc, val, 32, rel);
1249ece8a530Spatrick write32(loc, val);
1250ece8a530Spatrick break;
1251ece8a530Spatrick case R_PPC64_ADDR16_DS:
1252ece8a530Spatrick case R_PPC64_TPREL16_DS: {
1253bb684c34Spatrick checkInt(loc, val, 16, rel);
1254ece8a530Spatrick // DQ-form instructions use bits 28-31 as part of the instruction encoding
1255ece8a530Spatrick // DS-form instructions only use bits 30-31.
1256ece8a530Spatrick uint16_t mask = isDQFormInstruction(readFromHalf16(loc)) ? 0xf : 0x3;
1257bb684c34Spatrick checkAlignment(loc, lo(val), mask + 1, rel);
1258ece8a530Spatrick write16(loc, (read16(loc) & mask) | lo(val));
1259ece8a530Spatrick } break;
1260ece8a530Spatrick case R_PPC64_ADDR16_HA:
1261ece8a530Spatrick case R_PPC64_REL16_HA:
1262ece8a530Spatrick case R_PPC64_TPREL16_HA:
1263ece8a530Spatrick if (config->tocOptimize && shouldTocOptimize && ha(val) == 0)
12641cf9926bSpatrick writeFromHalf16(loc, NOP);
12651cf9926bSpatrick else {
12661cf9926bSpatrick checkInt(loc, val + 0x8000, 32, rel);
1267ece8a530Spatrick write16(loc, ha(val));
12681cf9926bSpatrick }
1269ece8a530Spatrick break;
1270ece8a530Spatrick case R_PPC64_ADDR16_HI:
1271ece8a530Spatrick case R_PPC64_REL16_HI:
1272ece8a530Spatrick case R_PPC64_TPREL16_HI:
12731cf9926bSpatrick checkInt(loc, val, 32, rel);
12741cf9926bSpatrick write16(loc, hi(val));
12751cf9926bSpatrick break;
12761cf9926bSpatrick case R_PPC64_ADDR16_HIGH:
1277ece8a530Spatrick write16(loc, hi(val));
1278ece8a530Spatrick break;
1279ece8a530Spatrick case R_PPC64_ADDR16_HIGHER:
1280ece8a530Spatrick case R_PPC64_TPREL16_HIGHER:
1281ece8a530Spatrick write16(loc, higher(val));
1282ece8a530Spatrick break;
1283ece8a530Spatrick case R_PPC64_ADDR16_HIGHERA:
1284ece8a530Spatrick case R_PPC64_TPREL16_HIGHERA:
1285ece8a530Spatrick write16(loc, highera(val));
1286ece8a530Spatrick break;
1287ece8a530Spatrick case R_PPC64_ADDR16_HIGHEST:
1288ece8a530Spatrick case R_PPC64_TPREL16_HIGHEST:
1289ece8a530Spatrick write16(loc, highest(val));
1290ece8a530Spatrick break;
1291ece8a530Spatrick case R_PPC64_ADDR16_HIGHESTA:
1292ece8a530Spatrick case R_PPC64_TPREL16_HIGHESTA:
1293ece8a530Spatrick write16(loc, highesta(val));
1294ece8a530Spatrick break;
1295ece8a530Spatrick case R_PPC64_ADDR16_LO:
1296ece8a530Spatrick case R_PPC64_REL16_LO:
1297ece8a530Spatrick case R_PPC64_TPREL16_LO:
1298ece8a530Spatrick // When the high-adjusted part of a toc relocation evaluates to 0, it is
1299ece8a530Spatrick // changed into a nop. The lo part then needs to be updated to use the
1300ece8a530Spatrick // toc-pointer register r2, as the base register.
1301ece8a530Spatrick if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
1302ece8a530Spatrick uint32_t insn = readFromHalf16(loc);
1303ece8a530Spatrick if (isInstructionUpdateForm(insn))
1304ece8a530Spatrick error(getErrorLocation(loc) +
1305ece8a530Spatrick "can't toc-optimize an update instruction: 0x" +
1306ece8a530Spatrick utohexstr(insn));
1307ece8a530Spatrick writeFromHalf16(loc, (insn & 0xffe00000) | 0x00020000 | lo(val));
1308ece8a530Spatrick } else {
1309ece8a530Spatrick write16(loc, lo(val));
1310ece8a530Spatrick }
1311ece8a530Spatrick break;
1312ece8a530Spatrick case R_PPC64_ADDR16_LO_DS:
1313ece8a530Spatrick case R_PPC64_TPREL16_LO_DS: {
1314ece8a530Spatrick // DQ-form instructions use bits 28-31 as part of the instruction encoding
1315ece8a530Spatrick // DS-form instructions only use bits 30-31.
1316ece8a530Spatrick uint32_t insn = readFromHalf16(loc);
1317ece8a530Spatrick uint16_t mask = isDQFormInstruction(insn) ? 0xf : 0x3;
1318bb684c34Spatrick checkAlignment(loc, lo(val), mask + 1, rel);
1319ece8a530Spatrick if (config->tocOptimize && shouldTocOptimize && ha(val) == 0) {
1320ece8a530Spatrick // When the high-adjusted part of a toc relocation evaluates to 0, it is
1321ece8a530Spatrick // changed into a nop. The lo part then needs to be updated to use the toc
1322ece8a530Spatrick // pointer register r2, as the base register.
1323ece8a530Spatrick if (isInstructionUpdateForm(insn))
1324ece8a530Spatrick error(getErrorLocation(loc) +
1325ece8a530Spatrick "Can't toc-optimize an update instruction: 0x" +
1326ece8a530Spatrick Twine::utohexstr(insn));
1327ece8a530Spatrick insn &= 0xffe00000 | mask;
1328ece8a530Spatrick writeFromHalf16(loc, insn | 0x00020000 | lo(val));
1329ece8a530Spatrick } else {
1330ece8a530Spatrick write16(loc, (read16(loc) & mask) | lo(val));
1331ece8a530Spatrick }
1332ece8a530Spatrick } break;
1333ece8a530Spatrick case R_PPC64_TPREL16:
1334bb684c34Spatrick checkInt(loc, val, 16, rel);
1335ece8a530Spatrick write16(loc, val);
1336ece8a530Spatrick break;
1337ece8a530Spatrick case R_PPC64_REL32:
1338bb684c34Spatrick checkInt(loc, val, 32, rel);
1339ece8a530Spatrick write32(loc, val);
1340ece8a530Spatrick break;
1341ece8a530Spatrick case R_PPC64_ADDR64:
1342ece8a530Spatrick case R_PPC64_REL64:
1343ece8a530Spatrick case R_PPC64_TOC:
1344ece8a530Spatrick write64(loc, val);
1345ece8a530Spatrick break;
1346ece8a530Spatrick case R_PPC64_REL14: {
1347ece8a530Spatrick uint32_t mask = 0x0000FFFC;
1348bb684c34Spatrick checkInt(loc, val, 16, rel);
1349bb684c34Spatrick checkAlignment(loc, val, 4, rel);
1350ece8a530Spatrick write32(loc, (read32(loc) & ~mask) | (val & mask));
1351ece8a530Spatrick break;
1352ece8a530Spatrick }
1353bb684c34Spatrick case R_PPC64_REL24:
1354bb684c34Spatrick case R_PPC64_REL24_NOTOC: {
1355ece8a530Spatrick uint32_t mask = 0x03FFFFFC;
1356bb684c34Spatrick checkInt(loc, val, 26, rel);
1357bb684c34Spatrick checkAlignment(loc, val, 4, rel);
1358ece8a530Spatrick write32(loc, (read32(loc) & ~mask) | (val & mask));
1359ece8a530Spatrick break;
1360ece8a530Spatrick }
1361ece8a530Spatrick case R_PPC64_DTPREL64:
1362ece8a530Spatrick write64(loc, val - dynamicThreadPointerOffset);
1363ece8a530Spatrick break;
13641cf9926bSpatrick case R_PPC64_DTPREL34:
13651cf9926bSpatrick // The Dynamic Thread Vector actually points 0x8000 bytes past the start
13661cf9926bSpatrick // of the TLS block. Therefore, in the case of R_PPC64_DTPREL34 we first
13671cf9926bSpatrick // need to subtract that value then fallthrough to the general case.
13681cf9926bSpatrick val -= dynamicThreadPointerOffset;
1369*05edf1c1Srobert [[fallthrough]];
13701cf9926bSpatrick case R_PPC64_PCREL34:
13711cf9926bSpatrick case R_PPC64_GOT_PCREL34:
13721cf9926bSpatrick case R_PPC64_GOT_TLSGD_PCREL34:
13731cf9926bSpatrick case R_PPC64_GOT_TLSLD_PCREL34:
13741cf9926bSpatrick case R_PPC64_GOT_TPREL_PCREL34:
13751cf9926bSpatrick case R_PPC64_TPREL34: {
1376bb684c34Spatrick const uint64_t si0Mask = 0x00000003ffff0000;
1377bb684c34Spatrick const uint64_t si1Mask = 0x000000000000ffff;
1378bb684c34Spatrick const uint64_t fullMask = 0x0003ffff0000ffff;
1379bb684c34Spatrick checkInt(loc, val, 34, rel);
1380bb684c34Spatrick
1381bb684c34Spatrick uint64_t instr = readPrefixedInstruction(loc) & ~fullMask;
1382bb684c34Spatrick writePrefixedInstruction(loc, instr | ((val & si0Mask) << 16) |
1383bb684c34Spatrick (val & si1Mask));
1384bb684c34Spatrick break;
1385bb684c34Spatrick }
13861cf9926bSpatrick // If we encounter a PCREL_OPT relocation that we won't optimize.
13871cf9926bSpatrick case R_PPC64_PCREL_OPT:
1388bb684c34Spatrick break;
1389ece8a530Spatrick default:
1390ece8a530Spatrick llvm_unreachable("unknown relocation");
1391ece8a530Spatrick }
1392ece8a530Spatrick }
1393ece8a530Spatrick
needsThunk(RelExpr expr,RelType type,const InputFile * file,uint64_t branchAddr,const Symbol & s,int64_t a) const1394ece8a530Spatrick bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
1395ece8a530Spatrick uint64_t branchAddr, const Symbol &s, int64_t a) const {
1396bb684c34Spatrick if (type != R_PPC64_REL14 && type != R_PPC64_REL24 &&
1397bb684c34Spatrick type != R_PPC64_REL24_NOTOC)
1398ece8a530Spatrick return false;
1399ece8a530Spatrick
1400ece8a530Spatrick // If a function is in the Plt it needs to be called with a call-stub.
1401ece8a530Spatrick if (s.isInPlt())
1402ece8a530Spatrick return true;
1403ece8a530Spatrick
1404bb684c34Spatrick // This check looks at the st_other bits of the callee with relocation
1405bb684c34Spatrick // R_PPC64_REL14 or R_PPC64_REL24. If the value is 1, then the callee
1406bb684c34Spatrick // clobbers the TOC and we need an R2 save stub.
1407bb684c34Spatrick if (type != R_PPC64_REL24_NOTOC && (s.stOther >> 5) == 1)
1408bb684c34Spatrick return true;
1409bb684c34Spatrick
14101cf9926bSpatrick if (type == R_PPC64_REL24_NOTOC && (s.stOther >> 5) > 1)
14111cf9926bSpatrick return true;
14121cf9926bSpatrick
1413*05edf1c1Srobert // An undefined weak symbol not in a PLT does not need a thunk. If it is
1414*05edf1c1Srobert // hidden, its binding has been converted to local, so we just check
1415*05edf1c1Srobert // isUndefined() here. A undefined non-weak symbol has been errored.
1416*05edf1c1Srobert if (s.isUndefined())
1417ece8a530Spatrick return false;
1418ece8a530Spatrick
1419ece8a530Spatrick // If the offset exceeds the range of the branch type then it will need
1420ece8a530Spatrick // a range-extending thunk.
1421ece8a530Spatrick // See the comment in getRelocTargetVA() about R_PPC64_CALL.
1422ece8a530Spatrick return !inBranchRange(type, branchAddr,
1423ece8a530Spatrick s.getVA(a) +
1424ece8a530Spatrick getPPC64GlobalEntryToLocalEntryOffset(s.stOther));
1425ece8a530Spatrick }
1426ece8a530Spatrick
getThunkSectionSpacing() const1427ece8a530Spatrick uint32_t PPC64::getThunkSectionSpacing() const {
1428ece8a530Spatrick // See comment in Arch/ARM.cpp for a more detailed explanation of
1429ece8a530Spatrick // getThunkSectionSpacing(). For PPC64 we pick the constant here based on
1430ece8a530Spatrick // R_PPC64_REL24, which is used by unconditional branch instructions.
1431ece8a530Spatrick // 0x2000000 = (1 << 24-1) * 4
1432ece8a530Spatrick return 0x2000000;
1433ece8a530Spatrick }
1434ece8a530Spatrick
inBranchRange(RelType type,uint64_t src,uint64_t dst) const1435ece8a530Spatrick bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
1436ece8a530Spatrick int64_t offset = dst - src;
1437ece8a530Spatrick if (type == R_PPC64_REL14)
1438ece8a530Spatrick return isInt<16>(offset);
1439bb684c34Spatrick if (type == R_PPC64_REL24 || type == R_PPC64_REL24_NOTOC)
1440ece8a530Spatrick return isInt<26>(offset);
1441ece8a530Spatrick llvm_unreachable("unsupported relocation type used in branch");
1442ece8a530Spatrick }
1443ece8a530Spatrick
adjustTlsExpr(RelType type,RelExpr expr) const14441cf9926bSpatrick RelExpr PPC64::adjustTlsExpr(RelType type, RelExpr expr) const {
14451cf9926bSpatrick if (type != R_PPC64_GOT_TLSGD_PCREL34 && expr == R_RELAX_TLS_GD_TO_IE)
1446ece8a530Spatrick return R_RELAX_TLS_GD_TO_IE_GOT_OFF;
1447ece8a530Spatrick if (expr == R_RELAX_TLS_LD_TO_LE)
1448ece8a530Spatrick return R_RELAX_TLS_LD_TO_LE_ABS;
1449ece8a530Spatrick return expr;
1450ece8a530Spatrick }
1451ece8a530Spatrick
adjustGotPcExpr(RelType type,int64_t addend,const uint8_t * loc) const14521cf9926bSpatrick RelExpr PPC64::adjustGotPcExpr(RelType type, int64_t addend,
14531cf9926bSpatrick const uint8_t *loc) const {
14541cf9926bSpatrick if ((type == R_PPC64_GOT_PCREL34 || type == R_PPC64_PCREL_OPT) &&
14551cf9926bSpatrick config->pcRelOptimize) {
14561cf9926bSpatrick // It only makes sense to optimize pld since paddi means that the address
14571cf9926bSpatrick // of the object in the GOT is required rather than the object itself.
14581cf9926bSpatrick if ((readPrefixedInstruction(loc) & 0xfc000000) == 0xe4000000)
14591cf9926bSpatrick return R_PPC64_RELAX_GOT_PC;
14601cf9926bSpatrick }
14611cf9926bSpatrick return R_GOT_PC;
14621cf9926bSpatrick }
14631cf9926bSpatrick
1464ece8a530Spatrick // Reference: 3.7.4.1 of the 64-bit ELF V2 abi supplement.
1465ece8a530Spatrick // The general dynamic code sequence for a global `x` uses 4 instructions.
1466ece8a530Spatrick // Instruction Relocation Symbol
1467ece8a530Spatrick // addis r3, r2, x@got@tlsgd@ha R_PPC64_GOT_TLSGD16_HA x
1468ece8a530Spatrick // addi r3, r3, x@got@tlsgd@l R_PPC64_GOT_TLSGD16_LO x
1469ece8a530Spatrick // bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x
1470ece8a530Spatrick // R_PPC64_REL24 __tls_get_addr
1471ece8a530Spatrick // nop None None
1472ece8a530Spatrick //
1473ece8a530Spatrick // Relaxing to initial-exec entails:
1474ece8a530Spatrick // 1) Convert the addis/addi pair that builds the address of the tls_index
1475ece8a530Spatrick // struct for 'x' to an addis/ld pair that loads an offset from a got-entry.
1476ece8a530Spatrick // 2) Convert the call to __tls_get_addr to a nop.
1477ece8a530Spatrick // 3) Convert the nop following the call to an add of the loaded offset to the
1478ece8a530Spatrick // thread pointer.
1479ece8a530Spatrick // Since the nop must directly follow the call, the R_PPC64_TLSGD relocation is
1480ece8a530Spatrick // used as the relaxation hint for both steps 2 and 3.
relaxTlsGdToIe(uint8_t * loc,const Relocation & rel,uint64_t val) const1481bb684c34Spatrick void PPC64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
1482bb684c34Spatrick uint64_t val) const {
1483bb684c34Spatrick switch (rel.type) {
1484ece8a530Spatrick case R_PPC64_GOT_TLSGD16_HA:
1485ece8a530Spatrick // This is relaxed from addis rT, r2, sym@got@tlsgd@ha to
1486ece8a530Spatrick // addis rT, r2, sym@got@tprel@ha.
1487bb684c34Spatrick relocateNoSym(loc, R_PPC64_GOT_TPREL16_HA, val);
1488ece8a530Spatrick return;
1489ece8a530Spatrick case R_PPC64_GOT_TLSGD16:
1490ece8a530Spatrick case R_PPC64_GOT_TLSGD16_LO: {
1491ece8a530Spatrick // Relax from addi r3, rA, sym@got@tlsgd@l to
1492ece8a530Spatrick // ld r3, sym@got@tprel@l(rA)
1493ece8a530Spatrick uint32_t ra = (readFromHalf16(loc) & (0x1f << 16));
1494ece8a530Spatrick writeFromHalf16(loc, 0xe8600000 | ra);
1495bb684c34Spatrick relocateNoSym(loc, R_PPC64_GOT_TPREL16_LO_DS, val);
1496ece8a530Spatrick return;
1497ece8a530Spatrick }
14981cf9926bSpatrick case R_PPC64_GOT_TLSGD_PCREL34: {
14991cf9926bSpatrick // Relax from paddi r3, 0, sym@got@tlsgd@pcrel, 1 to
15001cf9926bSpatrick // pld r3, sym@got@tprel@pcrel
15011cf9926bSpatrick writePrefixedInstruction(loc, 0x04100000e4600000);
15021cf9926bSpatrick relocateNoSym(loc, R_PPC64_GOT_TPREL_PCREL34, val);
1503ece8a530Spatrick return;
15041cf9926bSpatrick }
15051cf9926bSpatrick case R_PPC64_TLSGD: {
15061cf9926bSpatrick // PC Relative Relaxation:
15071cf9926bSpatrick // Relax from bl __tls_get_addr@notoc(x@tlsgd) to
15081cf9926bSpatrick // nop
15091cf9926bSpatrick // TOC Relaxation:
15101cf9926bSpatrick // Relax from bl __tls_get_addr(x@tlsgd)
15111cf9926bSpatrick // nop
15121cf9926bSpatrick // to
15131cf9926bSpatrick // nop
15141cf9926bSpatrick // add r3, r3, r13
15151cf9926bSpatrick const uintptr_t locAsInt = reinterpret_cast<uintptr_t>(loc);
15161cf9926bSpatrick if (locAsInt % 4 == 0) {
15171cf9926bSpatrick write32(loc, NOP); // bl __tls_get_addr(sym@tlsgd) --> nop
15181cf9926bSpatrick write32(loc + 4, 0x7c636A14); // nop --> add r3, r3, r13
15191cf9926bSpatrick } else if (locAsInt % 4 == 1) {
15201cf9926bSpatrick // bl __tls_get_addr(sym@tlsgd) --> add r3, r3, r13
15211cf9926bSpatrick write32(loc - 1, 0x7c636a14);
15221cf9926bSpatrick } else {
15231cf9926bSpatrick errorOrWarn("R_PPC64_TLSGD has unexpected byte alignment");
15241cf9926bSpatrick }
15251cf9926bSpatrick return;
15261cf9926bSpatrick }
1527ece8a530Spatrick default:
1528ece8a530Spatrick llvm_unreachable("unsupported relocation for TLS GD to IE relaxation");
1529ece8a530Spatrick }
1530ece8a530Spatrick }
1531ece8a530Spatrick
relocateAlloc(InputSectionBase & sec,uint8_t * buf) const1532*05edf1c1Srobert void PPC64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
1533*05edf1c1Srobert uint64_t secAddr = sec.getOutputSection()->addr;
1534*05edf1c1Srobert if (auto *s = dyn_cast<InputSection>(&sec))
1535*05edf1c1Srobert secAddr += s->outSecOff;
1536*05edf1c1Srobert uint64_t lastPPCRelaxedRelocOff = -1;
1537*05edf1c1Srobert for (const Relocation &rel : sec.relocs()) {
1538*05edf1c1Srobert uint8_t *loc = buf + rel.offset;
1539*05edf1c1Srobert const uint64_t val =
1540*05edf1c1Srobert sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
1541*05edf1c1Srobert secAddr + rel.offset, *rel.sym, rel.expr);
1542*05edf1c1Srobert switch (rel.expr) {
1543*05edf1c1Srobert case R_PPC64_RELAX_GOT_PC: {
1544*05edf1c1Srobert // The R_PPC64_PCREL_OPT relocation must appear immediately after
1545*05edf1c1Srobert // R_PPC64_GOT_PCREL34 in the relocations table at the same offset.
1546*05edf1c1Srobert // We can only relax R_PPC64_PCREL_OPT if we have also relaxed
1547*05edf1c1Srobert // the associated R_PPC64_GOT_PCREL34 since only the latter has an
1548*05edf1c1Srobert // associated symbol. So save the offset when relaxing R_PPC64_GOT_PCREL34
1549*05edf1c1Srobert // and only relax the other if the saved offset matches.
1550*05edf1c1Srobert if (rel.type == R_PPC64_GOT_PCREL34)
1551*05edf1c1Srobert lastPPCRelaxedRelocOff = rel.offset;
1552*05edf1c1Srobert if (rel.type == R_PPC64_PCREL_OPT && rel.offset != lastPPCRelaxedRelocOff)
1553*05edf1c1Srobert break;
1554*05edf1c1Srobert relaxGot(loc, rel, val);
1555*05edf1c1Srobert break;
1556*05edf1c1Srobert }
1557*05edf1c1Srobert case R_PPC64_RELAX_TOC:
1558*05edf1c1Srobert // rel.sym refers to the STT_SECTION symbol associated to the .toc input
1559*05edf1c1Srobert // section. If an R_PPC64_TOC16_LO (.toc + addend) references the TOC
1560*05edf1c1Srobert // entry, there may be R_PPC64_TOC16_HA not paired with
1561*05edf1c1Srobert // R_PPC64_TOC16_LO_DS. Don't relax. This loses some relaxation
1562*05edf1c1Srobert // opportunities but is safe.
1563*05edf1c1Srobert if (ppc64noTocRelax.count({rel.sym, rel.addend}) ||
1564*05edf1c1Srobert !tryRelaxPPC64TocIndirection(rel, loc))
1565*05edf1c1Srobert relocate(loc, rel, val);
1566*05edf1c1Srobert break;
1567*05edf1c1Srobert case R_PPC64_CALL:
1568*05edf1c1Srobert // If this is a call to __tls_get_addr, it may be part of a TLS
1569*05edf1c1Srobert // sequence that has been relaxed and turned into a nop. In this
1570*05edf1c1Srobert // case, we don't want to handle it as a call.
1571*05edf1c1Srobert if (read32(loc) == 0x60000000) // nop
1572*05edf1c1Srobert break;
1573*05edf1c1Srobert
1574*05edf1c1Srobert // Patch a nop (0x60000000) to a ld.
1575*05edf1c1Srobert if (rel.sym->needsTocRestore) {
1576*05edf1c1Srobert // gcc/gfortran 5.4, 6.3 and earlier versions do not add nop for
1577*05edf1c1Srobert // recursive calls even if the function is preemptible. This is not
1578*05edf1c1Srobert // wrong in the common case where the function is not preempted at
1579*05edf1c1Srobert // runtime. Just ignore.
1580*05edf1c1Srobert if ((rel.offset + 8 > sec.content().size() ||
1581*05edf1c1Srobert read32(loc + 4) != 0x60000000) &&
1582*05edf1c1Srobert rel.sym->file != sec.file) {
1583*05edf1c1Srobert // Use substr(6) to remove the "__plt_" prefix.
1584*05edf1c1Srobert errorOrWarn(getErrorLocation(loc) + "call to " +
1585*05edf1c1Srobert lld::toString(*rel.sym).substr(6) +
1586*05edf1c1Srobert " lacks nop, can't restore toc");
1587*05edf1c1Srobert break;
1588*05edf1c1Srobert }
1589*05edf1c1Srobert write32(loc + 4, 0xe8410018); // ld %r2, 24(%r1)
1590*05edf1c1Srobert }
1591*05edf1c1Srobert relocate(loc, rel, val);
1592*05edf1c1Srobert break;
1593*05edf1c1Srobert case R_RELAX_TLS_GD_TO_IE:
1594*05edf1c1Srobert case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
1595*05edf1c1Srobert relaxTlsGdToIe(loc, rel, val);
1596*05edf1c1Srobert break;
1597*05edf1c1Srobert case R_RELAX_TLS_GD_TO_LE:
1598*05edf1c1Srobert relaxTlsGdToLe(loc, rel, val);
1599*05edf1c1Srobert break;
1600*05edf1c1Srobert case R_RELAX_TLS_LD_TO_LE_ABS:
1601*05edf1c1Srobert relaxTlsLdToLe(loc, rel, val);
1602*05edf1c1Srobert break;
1603*05edf1c1Srobert case R_RELAX_TLS_IE_TO_LE:
1604*05edf1c1Srobert relaxTlsIeToLe(loc, rel, val);
1605*05edf1c1Srobert break;
1606*05edf1c1Srobert default:
1607*05edf1c1Srobert relocate(loc, rel, val);
1608*05edf1c1Srobert break;
1609*05edf1c1Srobert }
1610*05edf1c1Srobert }
1611*05edf1c1Srobert }
1612*05edf1c1Srobert
1613ece8a530Spatrick // The prologue for a split-stack function is expected to look roughly
1614ece8a530Spatrick // like this:
1615ece8a530Spatrick // .Lglobal_entry_point:
1616ece8a530Spatrick // # TOC pointer initialization.
1617ece8a530Spatrick // ...
1618ece8a530Spatrick // .Llocal_entry_point:
1619ece8a530Spatrick // # load the __private_ss member of the threads tcbhead.
1620ece8a530Spatrick // ld r0,-0x7000-64(r13)
1621ece8a530Spatrick // # subtract the functions stack size from the stack pointer.
1622ece8a530Spatrick // addis r12, r1, ha(-stack-frame size)
1623ece8a530Spatrick // addi r12, r12, l(-stack-frame size)
1624ece8a530Spatrick // # compare needed to actual and branch to allocate_more_stack if more
1625ece8a530Spatrick // # space is needed, otherwise fallthrough to 'normal' function body.
1626ece8a530Spatrick // cmpld cr7,r12,r0
1627ece8a530Spatrick // blt- cr7, .Lallocate_more_stack
1628ece8a530Spatrick //
1629ece8a530Spatrick // -) The allocate_more_stack block might be placed after the split-stack
1630ece8a530Spatrick // prologue and the `blt-` replaced with a `bge+ .Lnormal_func_body`
1631ece8a530Spatrick // instead.
1632ece8a530Spatrick // -) If either the addis or addi is not needed due to the stack size being
1633ece8a530Spatrick // smaller then 32K or a multiple of 64K they will be replaced with a nop,
1634ece8a530Spatrick // but there will always be 2 instructions the linker can overwrite for the
1635ece8a530Spatrick // adjusted stack size.
1636ece8a530Spatrick //
1637ece8a530Spatrick // The linkers job here is to increase the stack size used in the addis/addi
1638ece8a530Spatrick // pair by split-stack-size-adjust.
1639ece8a530Spatrick // addis r12, r1, ha(-stack-frame size - split-stack-adjust-size)
1640ece8a530Spatrick // addi r12, r12, l(-stack-frame size - split-stack-adjust-size)
adjustPrologueForCrossSplitStack(uint8_t * loc,uint8_t * end,uint8_t stOther) const1641ece8a530Spatrick bool PPC64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
1642ece8a530Spatrick uint8_t stOther) const {
1643ece8a530Spatrick // If the caller has a global entry point adjust the buffer past it. The start
1644ece8a530Spatrick // of the split-stack prologue will be at the local entry point.
1645ece8a530Spatrick loc += getPPC64GlobalEntryToLocalEntryOffset(stOther);
1646ece8a530Spatrick
1647ece8a530Spatrick // At the very least we expect to see a load of some split-stack data from the
1648ece8a530Spatrick // tcb, and 2 instructions that calculate the ending stack address this
1649ece8a530Spatrick // function will require. If there is not enough room for at least 3
1650ece8a530Spatrick // instructions it can't be a split-stack prologue.
1651ece8a530Spatrick if (loc + 12 >= end)
1652ece8a530Spatrick return false;
1653ece8a530Spatrick
1654ece8a530Spatrick // First instruction must be `ld r0, -0x7000-64(r13)`
1655ece8a530Spatrick if (read32(loc) != 0xe80d8fc0)
1656ece8a530Spatrick return false;
1657ece8a530Spatrick
1658ece8a530Spatrick int16_t hiImm = 0;
1659ece8a530Spatrick int16_t loImm = 0;
1660ece8a530Spatrick // First instruction can be either an addis if the frame size is larger then
1661ece8a530Spatrick // 32K, or an addi if the size is less then 32K.
1662ece8a530Spatrick int32_t firstInstr = read32(loc + 4);
1663ece8a530Spatrick if (getPrimaryOpCode(firstInstr) == 15) {
1664ece8a530Spatrick hiImm = firstInstr & 0xFFFF;
1665ece8a530Spatrick } else if (getPrimaryOpCode(firstInstr) == 14) {
1666ece8a530Spatrick loImm = firstInstr & 0xFFFF;
1667ece8a530Spatrick } else {
1668ece8a530Spatrick return false;
1669ece8a530Spatrick }
1670ece8a530Spatrick
1671ece8a530Spatrick // Second instruction is either an addi or a nop. If the first instruction was
1672ece8a530Spatrick // an addi then LoImm is set and the second instruction must be a nop.
1673ece8a530Spatrick uint32_t secondInstr = read32(loc + 8);
1674ece8a530Spatrick if (!loImm && getPrimaryOpCode(secondInstr) == 14) {
1675ece8a530Spatrick loImm = secondInstr & 0xFFFF;
16761cf9926bSpatrick } else if (secondInstr != NOP) {
1677ece8a530Spatrick return false;
1678ece8a530Spatrick }
1679ece8a530Spatrick
1680ece8a530Spatrick // The register operands of the first instruction should be the stack-pointer
1681ece8a530Spatrick // (r1) as the input (RA) and r12 as the output (RT). If the second
1682ece8a530Spatrick // instruction is not a nop, then it should use r12 as both input and output.
1683ece8a530Spatrick auto checkRegOperands = [](uint32_t instr, uint8_t expectedRT,
1684ece8a530Spatrick uint8_t expectedRA) {
1685ece8a530Spatrick return ((instr & 0x3E00000) >> 21 == expectedRT) &&
1686ece8a530Spatrick ((instr & 0x1F0000) >> 16 == expectedRA);
1687ece8a530Spatrick };
1688ece8a530Spatrick if (!checkRegOperands(firstInstr, 12, 1))
1689ece8a530Spatrick return false;
16901cf9926bSpatrick if (secondInstr != NOP && !checkRegOperands(secondInstr, 12, 12))
1691ece8a530Spatrick return false;
1692ece8a530Spatrick
1693ece8a530Spatrick int32_t stackFrameSize = (hiImm * 65536) + loImm;
1694ece8a530Spatrick // Check that the adjusted size doesn't overflow what we can represent with 2
1695ece8a530Spatrick // instructions.
1696ece8a530Spatrick if (stackFrameSize < config->splitStackAdjustSize + INT32_MIN) {
1697ece8a530Spatrick error(getErrorLocation(loc) + "split-stack prologue adjustment overflows");
1698ece8a530Spatrick return false;
1699ece8a530Spatrick }
1700ece8a530Spatrick
1701ece8a530Spatrick int32_t adjustedStackFrameSize =
1702ece8a530Spatrick stackFrameSize - config->splitStackAdjustSize;
1703ece8a530Spatrick
1704ece8a530Spatrick loImm = adjustedStackFrameSize & 0xFFFF;
1705ece8a530Spatrick hiImm = (adjustedStackFrameSize + 0x8000) >> 16;
1706ece8a530Spatrick if (hiImm) {
1707ece8a530Spatrick write32(loc + 4, 0x3D810000 | (uint16_t)hiImm);
1708ece8a530Spatrick // If the low immediate is zero the second instruction will be a nop.
17091cf9926bSpatrick secondInstr = loImm ? 0x398C0000 | (uint16_t)loImm : NOP;
1710ece8a530Spatrick write32(loc + 8, secondInstr);
1711ece8a530Spatrick } else {
1712ece8a530Spatrick // addi r12, r1, imm
1713ece8a530Spatrick write32(loc + 4, (0x39810000) | (uint16_t)loImm);
17141cf9926bSpatrick write32(loc + 8, NOP);
1715ece8a530Spatrick }
1716ece8a530Spatrick
1717ece8a530Spatrick return true;
1718ece8a530Spatrick }
1719ece8a530Spatrick
getPPC64TargetInfo()1720bb684c34Spatrick TargetInfo *elf::getPPC64TargetInfo() {
1721ece8a530Spatrick static PPC64 target;
1722ece8a530Spatrick return ⌖
1723ece8a530Spatrick }
1724