1 //===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/PPCFixupKinds.h" 10 #include "MCTargetDesc/PPCMCAsmInfo.h" 11 #include "MCTargetDesc/PPCMCTargetDesc.h" 12 #include "llvm/MC/MCContext.h" 13 #include "llvm/MC/MCELFObjectWriter.h" 14 #include "llvm/MC/MCExpr.h" 15 #include "llvm/MC/MCObjectWriter.h" 16 #include "llvm/MC/MCSymbolELF.h" 17 #include "llvm/MC/MCValue.h" 18 #include "llvm/Support/ErrorHandling.h" 19 20 using namespace llvm; 21 22 namespace { 23 class PPCELFObjectWriter : public MCELFObjectTargetWriter { 24 public: 25 PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); 26 27 protected: 28 unsigned getRelocType(const MCFixup &Fixup, const MCValue &Target, 29 bool IsPCRel) const override; 30 31 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override; 32 }; 33 } 34 35 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 36 : MCELFObjectTargetWriter(Is64Bit, OSABI, 37 Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 38 /*HasRelocationAddend*/ true) {} 39 40 unsigned PPCELFObjectWriter::getRelocType(const MCFixup &Fixup, 41 const MCValue &Target, 42 bool IsPCRel) const { 43 SMLoc Loc = Fixup.getValue()->getLoc(); 44 auto Spec = static_cast<PPCMCExpr::Specifier>(Target.getSpecifier()); 45 switch (Spec) { 46 case PPC::S_DTPMOD: 47 case PPC::S_DTPREL: 48 case PPC::S_DTPREL_HA: 49 case PPC::S_DTPREL_HI: 50 case PPC::S_DTPREL_HIGH: 51 case PPC::S_DTPREL_HIGHA: 52 case PPC::S_DTPREL_HIGHER: 53 case PPC::S_DTPREL_HIGHERA: 54 case PPC::S_DTPREL_HIGHEST: 55 case PPC::S_DTPREL_HIGHESTA: 56 case PPC::S_DTPREL_LO: 57 case PPC::S_GOT_DTPREL: 58 case PPC::S_GOT_DTPREL_HA: 59 case PPC::S_GOT_DTPREL_HI: 60 case PPC::S_GOT_DTPREL_LO: 61 case PPC::S_GOT_TLSGD: 62 case PPC::S_GOT_TLSGD_HA: 63 case PPC::S_GOT_TLSGD_HI: 64 case PPC::S_GOT_TLSGD_LO: 65 case PPC::S_GOT_TLSGD_PCREL: 66 case PPC::S_GOT_TLSLD: 67 case PPC::S_GOT_TLSLD_HA: 68 case PPC::S_GOT_TLSLD_HI: 69 case PPC::S_GOT_TLSLD_LO: 70 case PPC::S_GOT_TPREL: 71 case PPC::S_GOT_TPREL_HA: 72 case PPC::S_GOT_TPREL_HI: 73 case PPC::S_GOT_TPREL_LO: 74 case PPC::S_GOT_TPREL_PCREL: 75 case PPC::S_TLS: 76 case PPC::S_TLSGD: 77 case PPC::S_TLSLD: 78 case PPC::S_TLS_PCREL: 79 case PPC::S_TPREL: 80 case PPC::S_TPREL_HA: 81 case PPC::S_TPREL_HI: 82 case PPC::S_TPREL_HIGH: 83 case PPC::S_TPREL_HIGHA: 84 case PPC::S_TPREL_HIGHER: 85 case PPC::S_TPREL_HIGHERA: 86 case PPC::S_TPREL_HIGHEST: 87 case PPC::S_TPREL_HIGHESTA: 88 case PPC::S_TPREL_LO: 89 if (auto *SA = Target.getAddSym()) 90 cast<MCSymbolELF>(SA)->setType(ELF::STT_TLS); 91 break; 92 default: 93 break; 94 } 95 96 // determine the type of the relocation 97 unsigned Type = 0; 98 if (IsPCRel) { 99 switch (Fixup.getKind()) { 100 default: 101 llvm_unreachable("Unimplemented"); 102 case PPC::fixup_ppc_br24: 103 case PPC::fixup_ppc_br24abs: 104 case PPC::fixup_ppc_br24_notoc: 105 switch (Spec) { 106 default: 107 reportError(Loc, "unsupported relocation type"); 108 break; 109 case PPC::S_None: 110 Type = ELF::R_PPC_REL24; 111 break; 112 case PPC::S_PLT: 113 Type = ELF::R_PPC_PLTREL24; 114 break; 115 case PPC::S_LOCAL: 116 Type = ELF::R_PPC_LOCAL24PC; 117 break; 118 case PPC::S_NOTOC: 119 Type = ELF::R_PPC64_REL24_NOTOC; 120 break; 121 } 122 break; 123 case PPC::fixup_ppc_brcond14: 124 case PPC::fixup_ppc_brcond14abs: 125 Type = ELF::R_PPC_REL14; 126 break; 127 case PPC::fixup_ppc_half16: 128 switch (Spec) { 129 default: 130 reportError(Loc, "unsupported relocation type"); 131 return ELF::R_PPC_NONE; 132 case PPC::S_None: 133 return ELF::R_PPC_REL16; 134 case PPC::S_LO: 135 return ELF::R_PPC_REL16_LO; 136 case PPC::S_HI: 137 return ELF::R_PPC_REL16_HI; 138 case PPC::S_HA: 139 return ELF::R_PPC_REL16_HA; 140 } 141 break; 142 case PPC::fixup_ppc_half16ds: 143 case PPC::fixup_ppc_half16dq: 144 reportError(Loc, "unsupported relocation type"); 145 break; 146 case PPC::fixup_ppc_pcrel34: 147 switch (Spec) { 148 default: 149 reportError(Loc, "unsupported relocation type"); 150 break; 151 case PPC::S_PCREL: 152 Type = ELF::R_PPC64_PCREL34; 153 break; 154 case PPC::S_GOT_PCREL: 155 Type = ELF::R_PPC64_GOT_PCREL34; 156 break; 157 case PPC::S_GOT_TLSGD_PCREL: 158 Type = ELF::R_PPC64_GOT_TLSGD_PCREL34; 159 break; 160 case PPC::S_GOT_TLSLD_PCREL: 161 Type = ELF::R_PPC64_GOT_TLSLD_PCREL34; 162 break; 163 case PPC::S_GOT_TPREL_PCREL: 164 Type = ELF::R_PPC64_GOT_TPREL_PCREL34; 165 break; 166 } 167 break; 168 case FK_Data_4: 169 Type = ELF::R_PPC_REL32; 170 break; 171 case FK_Data_8: 172 Type = ELF::R_PPC64_REL64; 173 break; 174 } 175 } else { 176 switch (Fixup.getKind()) { 177 default: 178 llvm_unreachable("invalid fixup kind!"); 179 case PPC::fixup_ppc_br24abs: 180 Type = ELF::R_PPC_ADDR24; 181 break; 182 case PPC::fixup_ppc_brcond14abs: 183 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 184 break; 185 case PPC::fixup_ppc_half16: 186 switch (Spec) { 187 default: 188 reportError(Loc, "unsupported relocation type"); 189 break; 190 case PPC::S_LO: 191 return ELF::R_PPC_ADDR16_LO; 192 case PPC::S_HI: 193 return ELF::R_PPC_ADDR16_HI; 194 case PPC::S_HA: 195 return ELF::R_PPC_ADDR16_HA; 196 case PPC::S_HIGH: 197 return ELF::R_PPC64_ADDR16_HIGH; 198 case PPC::S_HIGHA: 199 return ELF::R_PPC64_ADDR16_HIGHA; 200 case PPC::S_HIGHER: 201 return ELF::R_PPC64_ADDR16_HIGHER; 202 case PPC::S_HIGHERA: 203 return ELF::R_PPC64_ADDR16_HIGHERA; 204 case PPC::S_HIGHEST: 205 return ELF::R_PPC64_ADDR16_HIGHEST; 206 case PPC::S_HIGHESTA: 207 return ELF::R_PPC64_ADDR16_HIGHESTA; 208 209 case PPC::S_None: 210 Type = ELF::R_PPC_ADDR16; 211 break; 212 case PPC::S_GOT: 213 Type = ELF::R_PPC_GOT16; 214 break; 215 case PPC::S_GOT_LO: 216 Type = ELF::R_PPC_GOT16_LO; 217 break; 218 case PPC::S_GOT_HI: 219 Type = ELF::R_PPC_GOT16_HI; 220 break; 221 case PPC::S_GOT_HA: 222 Type = ELF::R_PPC_GOT16_HA; 223 break; 224 case PPC::S_TOC: 225 Type = ELF::R_PPC64_TOC16; 226 break; 227 case PPC::S_TOC_LO: 228 Type = ELF::R_PPC64_TOC16_LO; 229 break; 230 case PPC::S_TOC_HI: 231 Type = ELF::R_PPC64_TOC16_HI; 232 break; 233 case PPC::S_TOC_HA: 234 Type = ELF::R_PPC64_TOC16_HA; 235 break; 236 case PPC::S_TPREL: 237 Type = ELF::R_PPC_TPREL16; 238 break; 239 case PPC::S_TPREL_LO: 240 Type = ELF::R_PPC_TPREL16_LO; 241 break; 242 case PPC::S_TPREL_HI: 243 Type = ELF::R_PPC_TPREL16_HI; 244 break; 245 case PPC::S_TPREL_HA: 246 Type = ELF::R_PPC_TPREL16_HA; 247 break; 248 case PPC::S_TPREL_HIGH: 249 Type = ELF::R_PPC64_TPREL16_HIGH; 250 break; 251 case PPC::S_TPREL_HIGHA: 252 Type = ELF::R_PPC64_TPREL16_HIGHA; 253 break; 254 case PPC::S_TPREL_HIGHER: 255 Type = ELF::R_PPC64_TPREL16_HIGHER; 256 break; 257 case PPC::S_TPREL_HIGHERA: 258 Type = ELF::R_PPC64_TPREL16_HIGHERA; 259 break; 260 case PPC::S_TPREL_HIGHEST: 261 Type = ELF::R_PPC64_TPREL16_HIGHEST; 262 break; 263 case PPC::S_TPREL_HIGHESTA: 264 Type = ELF::R_PPC64_TPREL16_HIGHESTA; 265 break; 266 case PPC::S_DTPREL: 267 Type = ELF::R_PPC64_DTPREL16; 268 break; 269 case PPC::S_DTPREL_LO: 270 Type = ELF::R_PPC64_DTPREL16_LO; 271 break; 272 case PPC::S_DTPREL_HI: 273 Type = ELF::R_PPC64_DTPREL16_HI; 274 break; 275 case PPC::S_DTPREL_HA: 276 Type = ELF::R_PPC64_DTPREL16_HA; 277 break; 278 case PPC::S_DTPREL_HIGH: 279 Type = ELF::R_PPC64_DTPREL16_HIGH; 280 break; 281 case PPC::S_DTPREL_HIGHA: 282 Type = ELF::R_PPC64_DTPREL16_HIGHA; 283 break; 284 case PPC::S_DTPREL_HIGHER: 285 Type = ELF::R_PPC64_DTPREL16_HIGHER; 286 break; 287 case PPC::S_DTPREL_HIGHERA: 288 Type = ELF::R_PPC64_DTPREL16_HIGHERA; 289 break; 290 case PPC::S_DTPREL_HIGHEST: 291 Type = ELF::R_PPC64_DTPREL16_HIGHEST; 292 break; 293 case PPC::S_DTPREL_HIGHESTA: 294 Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 295 break; 296 case PPC::S_GOT_TLSGD: 297 if (is64Bit()) 298 Type = ELF::R_PPC64_GOT_TLSGD16; 299 else 300 Type = ELF::R_PPC_GOT_TLSGD16; 301 break; 302 case PPC::S_GOT_TLSGD_LO: 303 Type = ELF::R_PPC64_GOT_TLSGD16_LO; 304 break; 305 case PPC::S_GOT_TLSGD_HI: 306 Type = ELF::R_PPC64_GOT_TLSGD16_HI; 307 break; 308 case PPC::S_GOT_TLSGD_HA: 309 Type = ELF::R_PPC64_GOT_TLSGD16_HA; 310 break; 311 case PPC::S_GOT_TLSLD: 312 if (is64Bit()) 313 Type = ELF::R_PPC64_GOT_TLSLD16; 314 else 315 Type = ELF::R_PPC_GOT_TLSLD16; 316 break; 317 case PPC::S_GOT_TLSLD_LO: 318 Type = ELF::R_PPC64_GOT_TLSLD16_LO; 319 break; 320 case PPC::S_GOT_TLSLD_HI: 321 Type = ELF::R_PPC64_GOT_TLSLD16_HI; 322 break; 323 case PPC::S_GOT_TLSLD_HA: 324 Type = ELF::R_PPC64_GOT_TLSLD16_HA; 325 break; 326 case PPC::S_GOT_TPREL: 327 /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 328 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 329 Type = ELF::R_PPC64_GOT_TPREL16_DS; 330 break; 331 case PPC::S_GOT_TPREL_LO: 332 /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 333 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 334 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 335 break; 336 case PPC::S_GOT_TPREL_HI: 337 Type = ELF::R_PPC64_GOT_TPREL16_HI; 338 break; 339 case PPC::S_GOT_DTPREL: 340 /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 341 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 342 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 343 break; 344 case PPC::S_GOT_DTPREL_LO: 345 /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 346 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 347 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 348 break; 349 case PPC::S_GOT_TPREL_HA: 350 Type = ELF::R_PPC64_GOT_TPREL16_HA; 351 break; 352 case PPC::S_GOT_DTPREL_HI: 353 Type = ELF::R_PPC64_GOT_DTPREL16_HI; 354 break; 355 case PPC::S_GOT_DTPREL_HA: 356 Type = ELF::R_PPC64_GOT_DTPREL16_HA; 357 break; 358 } 359 break; 360 case PPC::fixup_ppc_half16ds: 361 case PPC::fixup_ppc_half16dq: 362 switch (Spec) { 363 default: 364 reportError(Loc, "unsupported relocation type"); 365 break; 366 case PPC::S_LO: 367 return ELF::R_PPC64_ADDR16_LO_DS; 368 case PPC::S_None: 369 Type = ELF::R_PPC64_ADDR16_DS; 370 break; 371 case PPC::S_GOT: 372 Type = ELF::R_PPC64_GOT16_DS; 373 break; 374 case PPC::S_GOT_LO: 375 Type = ELF::R_PPC64_GOT16_LO_DS; 376 break; 377 case PPC::S_TOC: 378 Type = ELF::R_PPC64_TOC16_DS; 379 break; 380 case PPC::S_TOC_LO: 381 Type = ELF::R_PPC64_TOC16_LO_DS; 382 break; 383 case PPC::S_TPREL: 384 Type = ELF::R_PPC64_TPREL16_DS; 385 break; 386 case PPC::S_TPREL_LO: 387 Type = ELF::R_PPC64_TPREL16_LO_DS; 388 break; 389 case PPC::S_DTPREL: 390 Type = ELF::R_PPC64_DTPREL16_DS; 391 break; 392 case PPC::S_DTPREL_LO: 393 Type = ELF::R_PPC64_DTPREL16_LO_DS; 394 break; 395 case PPC::S_GOT_TPREL: 396 Type = ELF::R_PPC64_GOT_TPREL16_DS; 397 break; 398 case PPC::S_GOT_TPREL_LO: 399 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 400 break; 401 case PPC::S_GOT_DTPREL: 402 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 403 break; 404 case PPC::S_GOT_DTPREL_LO: 405 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 406 break; 407 } 408 break; 409 case PPC::fixup_ppc_nofixup: 410 switch (Spec) { 411 default: 412 reportError(Loc, "unsupported relocation type"); 413 break; 414 case PPC::S_TLSGD: 415 if (is64Bit()) 416 Type = ELF::R_PPC64_TLSGD; 417 else 418 Type = ELF::R_PPC_TLSGD; 419 break; 420 case PPC::S_TLSLD: 421 if (is64Bit()) 422 Type = ELF::R_PPC64_TLSLD; 423 else 424 Type = ELF::R_PPC_TLSLD; 425 break; 426 case PPC::S_TLS: 427 if (is64Bit()) 428 Type = ELF::R_PPC64_TLS; 429 else 430 Type = ELF::R_PPC_TLS; 431 break; 432 case PPC::S_TLS_PCREL: 433 Type = ELF::R_PPC64_TLS; 434 break; 435 } 436 break; 437 case PPC::fixup_ppc_imm34: 438 switch (Spec) { 439 default: 440 reportError(Loc, "unsupported relocation type"); 441 break; 442 case PPC::S_DTPREL: 443 Type = ELF::R_PPC64_DTPREL34; 444 break; 445 case PPC::S_TPREL: 446 Type = ELF::R_PPC64_TPREL34; 447 break; 448 } 449 break; 450 case FK_Data_8: 451 switch (Spec) { 452 default: 453 reportError(Loc, "unsupported relocation type"); 454 break; 455 case PPC::S_TOCBASE: 456 Type = ELF::R_PPC64_TOC; 457 break; 458 case PPC::S_None: 459 Type = ELF::R_PPC64_ADDR64; 460 break; 461 case PPC::S_DTPMOD: 462 Type = ELF::R_PPC64_DTPMOD64; 463 break; 464 case PPC::S_TPREL: 465 Type = ELF::R_PPC64_TPREL64; 466 break; 467 case PPC::S_DTPREL: 468 Type = ELF::R_PPC64_DTPREL64; 469 break; 470 } 471 break; 472 case FK_Data_4: 473 switch (Spec) { 474 case PPC::S_DTPREL: 475 Type = ELF::R_PPC_DTPREL32; 476 break; 477 default: 478 Type = ELF::R_PPC_ADDR32; 479 } 480 break; 481 case FK_Data_2: 482 Type = ELF::R_PPC_ADDR16; 483 break; 484 } 485 } 486 return Type; 487 } 488 489 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCValue &V, 490 unsigned Type) const { 491 switch (Type) { 492 default: 493 return false; 494 495 case ELF::R_PPC_REL24: 496 case ELF::R_PPC64_REL24_NOTOC: { 497 // If the target symbol has a local entry point, we must keep the 498 // target symbol to preserve that information for the linker. 499 // The "other" values are stored in the last 6 bits of the second byte. 500 // The traditional defines for STO values assume the full byte and thus 501 // the shift to pack it. 502 unsigned Other = cast<MCSymbolELF>(V.getAddSym())->getOther() << 2; 503 return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 504 } 505 506 case ELF::R_PPC64_GOT16: 507 case ELF::R_PPC64_GOT16_DS: 508 case ELF::R_PPC64_GOT16_LO: 509 case ELF::R_PPC64_GOT16_LO_DS: 510 case ELF::R_PPC64_GOT16_HI: 511 case ELF::R_PPC64_GOT16_HA: 512 return true; 513 } 514 } 515 516 std::unique_ptr<MCObjectTargetWriter> 517 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { 518 return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); 519 } 520