1 //===- PPC64.cpp ----------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Symbols.h" 11 #include "SyntheticSections.h" 12 #include "Target.h" 13 #include "lld/Common/ErrorHandler.h" 14 #include "llvm/Support/Endian.h" 15 16 using namespace llvm; 17 using namespace llvm::object; 18 using namespace llvm::support::endian; 19 using namespace llvm::ELF; 20 using namespace lld; 21 using namespace lld::elf; 22 23 static uint64_t PPC64TocOffset = 0x8000; 24 25 uint64_t elf::getPPC64TocBase() { 26 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The 27 // TOC starts where the first of these sections starts. We always create a 28 // .got when we see a relocation that uses it, so for us the start is always 29 // the .got. 30 uint64_t TocVA = InX::Got->getVA(); 31 32 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 33 // thus permitting a full 64 Kbytes segment. Note that the glibc startup 34 // code (crt1.o) assumes that you can get from the TOC base to the 35 // start of the .toc section with only a single (signed) 16-bit relocation. 36 return TocVA + PPC64TocOffset; 37 } 38 39 namespace { 40 class PPC64 final : public TargetInfo { 41 public: 42 PPC64(); 43 uint32_t calcEFlags() const override; 44 RelExpr getRelExpr(RelType Type, const Symbol &S, 45 const uint8_t *Loc) const override; 46 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, 47 int32_t Index, unsigned RelOff) const override; 48 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 49 void writeGotHeader(uint8_t *Buf) const override; 50 }; 51 } // namespace 52 53 // Relocation masks following the #lo(value), #hi(value), #ha(value), 54 // #higher(value), #highera(value), #highest(value), and #highesta(value) 55 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi 56 // document. 57 static uint16_t applyPPCLo(uint64_t V) { return V; } 58 static uint16_t applyPPCHi(uint64_t V) { return V >> 16; } 59 static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; } 60 static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; } 61 static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; } 62 static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; } 63 static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; } 64 65 PPC64::PPC64() { 66 GotRel = R_PPC64_GLOB_DAT; 67 RelativeRel = R_PPC64_RELATIVE; 68 GotEntrySize = 8; 69 GotPltEntrySize = 8; 70 PltEntrySize = 32; 71 PltHeaderSize = 0; 72 GotBaseSymInGotPlt = false; 73 GotBaseSymOff = 0x8000; 74 75 if (Config->EKind == ELF64LEKind) { 76 GotHeaderEntriesNum = 1; 77 GotPltHeaderEntriesNum = 2; 78 PltRel = R_PPC64_JMP_SLOT; 79 } else { 80 PltRel = R_PPC64_GLOB_DAT; 81 } 82 83 // We need 64K pages (at least under glibc/Linux, the loader won't 84 // set different permissions on a finer granularity than that). 85 DefaultMaxPageSize = 65536; 86 87 // The PPC64 ELF ABI v1 spec, says: 88 // 89 // It is normally desirable to put segments with different characteristics 90 // in separate 256 Mbyte portions of the address space, to give the 91 // operating system full paging flexibility in the 64-bit address space. 92 // 93 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers 94 // use 0x10000000 as the starting address. 95 DefaultImageBase = 0x10000000; 96 97 TrapInstr = 0x7fe00008; 98 } 99 100 static uint32_t getEFlags(InputFile *File) { 101 // Get the e_flag from the input file and if it is unspecified, then set it to 102 // the e_flag appropriate for the ABI. 103 104 // We are currently handling both ELF64LE and ELF64BE but eventually will 105 // remove BE support once v2 ABI support is complete. 106 switch (Config->EKind) { 107 case ELF64BEKind: 108 if (uint32_t EFlags = 109 cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags) 110 return EFlags; 111 return 1; 112 case ELF64LEKind: 113 if (uint32_t EFlags = 114 cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags) 115 return EFlags; 116 return 2; 117 default: 118 llvm_unreachable("unknown Config->EKind"); 119 } 120 } 121 122 uint32_t PPC64::calcEFlags() const { 123 assert(!ObjectFiles.empty()); 124 uint32_t Ret = getEFlags(ObjectFiles[0]); 125 126 // Verify that all input files have the same e_flags. 127 for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) { 128 if (Ret == getEFlags(F)) 129 continue; 130 error("incompatible e_flags: " + toString(F)); 131 return 0; 132 } 133 return Ret; 134 } 135 136 RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S, 137 const uint8_t *Loc) const { 138 switch (Type) { 139 case R_PPC64_TOC16: 140 case R_PPC64_TOC16_DS: 141 case R_PPC64_TOC16_HA: 142 case R_PPC64_TOC16_HI: 143 case R_PPC64_TOC16_LO: 144 case R_PPC64_TOC16_LO_DS: 145 return R_GOTREL; 146 case R_PPC64_TOC: 147 return R_PPC_TOC; 148 case R_PPC64_REL24: 149 return R_PPC_PLT_OPD; 150 case R_PPC64_REL16_LO: 151 case R_PPC64_REL16_HA: 152 return R_PC; 153 default: 154 return R_ABS; 155 } 156 } 157 158 void PPC64::writeGotHeader(uint8_t *Buf) const { 159 if (Config->EKind == ELF64LEKind) 160 write64(Buf, getPPC64TocBase()); 161 } 162 163 void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, 164 uint64_t PltEntryAddr, int32_t Index, 165 unsigned RelOff) const { 166 uint64_t Off = GotPltEntryAddr - getPPC64TocBase(); 167 168 if (Config->EKind == ELF64LEKind) { 169 // The most-common form of the plt stub. This assumes that the toc-pointer 170 // register is properly initalized, and that the stub must save the toc 171 // pointer value to the stack-save slot reserved for it (sp + 24). 172 // There are 2 other variants but we don't have to emit those until we add 173 // support for R_PPC64_REL24_NOTOC and R_PPC64_TOCSAVE relocations. 174 // We are missing a super simple optimization, where if the upper 16 bits of 175 // the offset are zero, then we can omit the addis instruction, and load 176 // r2 + lo-offset directly into r12. I decided to leave this out in the 177 // spirit of keeping it simple until we can link actual non-trivial 178 // programs. 179 write32(Buf + 0, 0xf8410018); // std r2,24(r1) 180 write32(Buf + 4, 0x3d820000 | applyPPCHa(Off)); // addis r12,r2, X@plt@to@ha 181 write32(Buf + 8, 0xe98c0000 | applyPPCLo(Off)); // ld r12,X@plt@toc@l(r12) 182 write32(Buf + 12, 0x7d8903a6); // mtctr r12 183 write32(Buf + 16, 0x4e800420); // bctr 184 } else { 185 // FIXME: What we should do, in theory, is get the offset of the function 186 // descriptor in the .opd section, and use that as the offset from %r2 (the 187 // TOC-base pointer). Instead, we have the GOT-entry offset, and that will 188 // be a pointer to the function descriptor in the .opd section. Using 189 // this scheme is simpler, but requires an extra indirection per PLT dispatch. 190 write32(Buf, 0xf8410028); // std %r2, 40(%r1) 191 write32(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha 192 write32(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11) 193 write32(Buf + 12, 0xe96c0000); // ld %r11,0(%r12) 194 write32(Buf + 16, 0x7d6903a6); // mtctr %r11 195 write32(Buf + 20, 0xe84c0008); // ld %r2,8(%r12) 196 write32(Buf + 24, 0xe96c0010); // ld %r11,16(%r12) 197 write32(Buf + 28, 0x4e800420); // bctr 198 } 199 } 200 201 static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) { 202 uint64_t V = Val - PPC64TocOffset; 203 switch (Type) { 204 case R_PPC64_TOC16: 205 return {R_PPC64_ADDR16, V}; 206 case R_PPC64_TOC16_DS: 207 return {R_PPC64_ADDR16_DS, V}; 208 case R_PPC64_TOC16_HA: 209 return {R_PPC64_ADDR16_HA, V}; 210 case R_PPC64_TOC16_HI: 211 return {R_PPC64_ADDR16_HI, V}; 212 case R_PPC64_TOC16_LO: 213 return {R_PPC64_ADDR16_LO, V}; 214 case R_PPC64_TOC16_LO_DS: 215 return {R_PPC64_ADDR16_LO_DS, V}; 216 default: 217 return {Type, Val}; 218 } 219 } 220 221 void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 222 // For a TOC-relative relocation, proceed in terms of the corresponding 223 // ADDR16 relocation type. 224 std::tie(Type, Val) = toAddr16Rel(Type, Val); 225 226 switch (Type) { 227 case R_PPC64_ADDR14: { 228 checkAlignment(Loc, Val, 4, Type); 229 // Preserve the AA/LK bits in the branch instruction 230 uint8_t AALK = Loc[3]; 231 write16(Loc + 2, (AALK & 3) | (Val & 0xfffc)); 232 break; 233 } 234 case R_PPC64_ADDR16: 235 checkInt(Loc, Val, 16, Type); 236 write16(Loc, Val); 237 break; 238 case R_PPC64_ADDR16_DS: 239 checkInt(Loc, Val, 16, Type); 240 write16(Loc, (read16(Loc) & 3) | (Val & ~3)); 241 break; 242 case R_PPC64_ADDR16_HA: 243 case R_PPC64_REL16_HA: 244 write16(Loc, applyPPCHa(Val)); 245 break; 246 case R_PPC64_ADDR16_HI: 247 case R_PPC64_REL16_HI: 248 write16(Loc, applyPPCHi(Val)); 249 break; 250 case R_PPC64_ADDR16_HIGHER: 251 write16(Loc, applyPPCHigher(Val)); 252 break; 253 case R_PPC64_ADDR16_HIGHERA: 254 write16(Loc, applyPPCHighera(Val)); 255 break; 256 case R_PPC64_ADDR16_HIGHEST: 257 write16(Loc, applyPPCHighest(Val)); 258 break; 259 case R_PPC64_ADDR16_HIGHESTA: 260 write16(Loc, applyPPCHighesta(Val)); 261 break; 262 case R_PPC64_ADDR16_LO: 263 case R_PPC64_REL16_LO: 264 write16(Loc, applyPPCLo(Val)); 265 break; 266 case R_PPC64_ADDR16_LO_DS: 267 write16(Loc, (read16(Loc) & 3) | (applyPPCLo(Val) & ~3)); 268 break; 269 case R_PPC64_ADDR32: 270 case R_PPC64_REL32: 271 checkInt(Loc, Val, 32, Type); 272 write32(Loc, Val); 273 break; 274 case R_PPC64_ADDR64: 275 case R_PPC64_REL64: 276 case R_PPC64_TOC: 277 write64(Loc, Val); 278 break; 279 case R_PPC64_REL24: { 280 uint32_t Mask = 0x03FFFFFC; 281 checkInt(Loc, Val, 24, Type); 282 write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask)); 283 break; 284 } 285 default: 286 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); 287 } 288 } 289 290 TargetInfo *elf::getPPC64TargetInfo() { 291 static PPC64 Target; 292 return &Target; 293 } 294