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/PPCMCExpr.h" 11 #include "MCTargetDesc/PPCMCTargetDesc.h" 12 #include "llvm/ADT/STLExtras.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(MCContext &Ctx, const MCValue &Target, 29 const MCFixup &Fixup, bool IsPCRel) const override; 30 31 bool needsRelocateWithSymbol(const MCSymbol &Sym, 32 unsigned Type) const override; 33 }; 34 } 35 36 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 37 : MCELFObjectTargetWriter(Is64Bit, OSABI, 38 Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 39 /*HasRelocationAddend*/ true) {} 40 41 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, 42 const MCFixup &Fixup) { 43 const MCExpr *Expr = Fixup.getValue(); 44 45 if (Expr->getKind() != MCExpr::Target) 46 return Target.getAccessVariant(); 47 48 switch (cast<PPCMCExpr>(Expr)->getKind()) { 49 case PPCMCExpr::VK_PPC_None: 50 return MCSymbolRefExpr::VK_None; 51 case PPCMCExpr::VK_PPC_LO: 52 return MCSymbolRefExpr::VK_PPC_LO; 53 case PPCMCExpr::VK_PPC_HI: 54 return MCSymbolRefExpr::VK_PPC_HI; 55 case PPCMCExpr::VK_PPC_HA: 56 return MCSymbolRefExpr::VK_PPC_HA; 57 case PPCMCExpr::VK_PPC_HIGH: 58 return MCSymbolRefExpr::VK_PPC_HIGH; 59 case PPCMCExpr::VK_PPC_HIGHA: 60 return MCSymbolRefExpr::VK_PPC_HIGHA; 61 case PPCMCExpr::VK_PPC_HIGHERA: 62 return MCSymbolRefExpr::VK_PPC_HIGHERA; 63 case PPCMCExpr::VK_PPC_HIGHER: 64 return MCSymbolRefExpr::VK_PPC_HIGHER; 65 case PPCMCExpr::VK_PPC_HIGHEST: 66 return MCSymbolRefExpr::VK_PPC_HIGHEST; 67 case PPCMCExpr::VK_PPC_HIGHESTA: 68 return MCSymbolRefExpr::VK_PPC_HIGHESTA; 69 } 70 llvm_unreachable("unknown PPCMCExpr kind"); 71 } 72 73 unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 74 const MCFixup &Fixup, 75 bool IsPCRel) const { 76 MCFixupKind Kind = Fixup.getKind(); 77 if (Kind >= FirstLiteralRelocationKind) 78 return Kind - FirstLiteralRelocationKind; 79 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); 80 81 // determine the type of the relocation 82 unsigned Type; 83 if (IsPCRel) { 84 switch (Fixup.getTargetKind()) { 85 default: 86 llvm_unreachable("Unimplemented"); 87 case PPC::fixup_ppc_br24: 88 case PPC::fixup_ppc_br24abs: 89 case PPC::fixup_ppc_br24_notoc: 90 switch (Modifier) { 91 default: llvm_unreachable("Unsupported Modifier"); 92 case MCSymbolRefExpr::VK_None: 93 Type = ELF::R_PPC_REL24; 94 break; 95 case MCSymbolRefExpr::VK_PLT: 96 Type = ELF::R_PPC_PLTREL24; 97 break; 98 case MCSymbolRefExpr::VK_PPC_LOCAL: 99 Type = ELF::R_PPC_LOCAL24PC; 100 break; 101 case MCSymbolRefExpr::VK_PPC_NOTOC: 102 Type = ELF::R_PPC64_REL24_NOTOC; 103 break; 104 } 105 break; 106 case PPC::fixup_ppc_brcond14: 107 case PPC::fixup_ppc_brcond14abs: 108 Type = ELF::R_PPC_REL14; 109 break; 110 case PPC::fixup_ppc_half16: 111 switch (Modifier) { 112 default: llvm_unreachable("Unsupported Modifier"); 113 case MCSymbolRefExpr::VK_None: 114 Type = ELF::R_PPC_REL16; 115 break; 116 case MCSymbolRefExpr::VK_PPC_LO: 117 Type = ELF::R_PPC_REL16_LO; 118 break; 119 case MCSymbolRefExpr::VK_PPC_HI: 120 Type = ELF::R_PPC_REL16_HI; 121 break; 122 case MCSymbolRefExpr::VK_PPC_HA: 123 Type = ELF::R_PPC_REL16_HA; 124 break; 125 } 126 break; 127 case PPC::fixup_ppc_half16ds: 128 case PPC::fixup_ppc_half16dq: 129 Target.print(errs()); 130 errs() << '\n'; 131 report_fatal_error("Invalid PC-relative half16ds relocation"); 132 case PPC::fixup_ppc_pcrel34: 133 switch (Modifier) { 134 default: 135 llvm_unreachable("Unsupported Modifier for fixup_ppc_pcrel34"); 136 case MCSymbolRefExpr::VK_PCREL: 137 Type = ELF::R_PPC64_PCREL34; 138 break; 139 case MCSymbolRefExpr::VK_PPC_GOT_PCREL: 140 Type = ELF::R_PPC64_GOT_PCREL34; 141 break; 142 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: 143 Type = ELF::R_PPC64_GOT_TLSGD_PCREL34; 144 break; 145 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL: 146 Type = ELF::R_PPC64_GOT_TLSLD_PCREL34; 147 break; 148 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: 149 Type = ELF::R_PPC64_GOT_TPREL_PCREL34; 150 break; 151 } 152 break; 153 case FK_Data_4: 154 case FK_PCRel_4: 155 Type = ELF::R_PPC_REL32; 156 break; 157 case FK_Data_8: 158 case FK_PCRel_8: 159 Type = ELF::R_PPC64_REL64; 160 break; 161 } 162 } else { 163 switch (Fixup.getTargetKind()) { 164 default: llvm_unreachable("invalid fixup kind!"); 165 case PPC::fixup_ppc_br24abs: 166 Type = ELF::R_PPC_ADDR24; 167 break; 168 case PPC::fixup_ppc_brcond14abs: 169 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 170 break; 171 case PPC::fixup_ppc_half16: 172 switch (Modifier) { 173 default: llvm_unreachable("Unsupported Modifier"); 174 case MCSymbolRefExpr::VK_None: 175 Type = ELF::R_PPC_ADDR16; 176 break; 177 case MCSymbolRefExpr::VK_PPC_LO: 178 Type = ELF::R_PPC_ADDR16_LO; 179 break; 180 case MCSymbolRefExpr::VK_PPC_HI: 181 Type = ELF::R_PPC_ADDR16_HI; 182 break; 183 case MCSymbolRefExpr::VK_PPC_HA: 184 Type = ELF::R_PPC_ADDR16_HA; 185 break; 186 case MCSymbolRefExpr::VK_PPC_HIGH: 187 Type = ELF::R_PPC64_ADDR16_HIGH; 188 break; 189 case MCSymbolRefExpr::VK_PPC_HIGHA: 190 Type = ELF::R_PPC64_ADDR16_HIGHA; 191 break; 192 case MCSymbolRefExpr::VK_PPC_HIGHER: 193 Type = ELF::R_PPC64_ADDR16_HIGHER; 194 break; 195 case MCSymbolRefExpr::VK_PPC_HIGHERA: 196 Type = ELF::R_PPC64_ADDR16_HIGHERA; 197 break; 198 case MCSymbolRefExpr::VK_PPC_HIGHEST: 199 Type = ELF::R_PPC64_ADDR16_HIGHEST; 200 break; 201 case MCSymbolRefExpr::VK_PPC_HIGHESTA: 202 Type = ELF::R_PPC64_ADDR16_HIGHESTA; 203 break; 204 case MCSymbolRefExpr::VK_GOT: 205 Type = ELF::R_PPC_GOT16; 206 break; 207 case MCSymbolRefExpr::VK_PPC_GOT_LO: 208 Type = ELF::R_PPC_GOT16_LO; 209 break; 210 case MCSymbolRefExpr::VK_PPC_GOT_HI: 211 Type = ELF::R_PPC_GOT16_HI; 212 break; 213 case MCSymbolRefExpr::VK_PPC_GOT_HA: 214 Type = ELF::R_PPC_GOT16_HA; 215 break; 216 case MCSymbolRefExpr::VK_PPC_TOC: 217 Type = ELF::R_PPC64_TOC16; 218 break; 219 case MCSymbolRefExpr::VK_PPC_TOC_LO: 220 Type = ELF::R_PPC64_TOC16_LO; 221 break; 222 case MCSymbolRefExpr::VK_PPC_TOC_HI: 223 Type = ELF::R_PPC64_TOC16_HI; 224 break; 225 case MCSymbolRefExpr::VK_PPC_TOC_HA: 226 Type = ELF::R_PPC64_TOC16_HA; 227 break; 228 case MCSymbolRefExpr::VK_TPREL: 229 Type = ELF::R_PPC_TPREL16; 230 break; 231 case MCSymbolRefExpr::VK_PPC_TPREL_LO: 232 Type = ELF::R_PPC_TPREL16_LO; 233 break; 234 case MCSymbolRefExpr::VK_PPC_TPREL_HI: 235 Type = ELF::R_PPC_TPREL16_HI; 236 break; 237 case MCSymbolRefExpr::VK_PPC_TPREL_HA: 238 Type = ELF::R_PPC_TPREL16_HA; 239 break; 240 case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: 241 Type = ELF::R_PPC64_TPREL16_HIGH; 242 break; 243 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: 244 Type = ELF::R_PPC64_TPREL16_HIGHA; 245 break; 246 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 247 Type = ELF::R_PPC64_TPREL16_HIGHER; 248 break; 249 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 250 Type = ELF::R_PPC64_TPREL16_HIGHERA; 251 break; 252 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 253 Type = ELF::R_PPC64_TPREL16_HIGHEST; 254 break; 255 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 256 Type = ELF::R_PPC64_TPREL16_HIGHESTA; 257 break; 258 case MCSymbolRefExpr::VK_DTPREL: 259 Type = ELF::R_PPC64_DTPREL16; 260 break; 261 case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 262 Type = ELF::R_PPC64_DTPREL16_LO; 263 break; 264 case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 265 Type = ELF::R_PPC64_DTPREL16_HI; 266 break; 267 case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 268 Type = ELF::R_PPC64_DTPREL16_HA; 269 break; 270 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: 271 Type = ELF::R_PPC64_DTPREL16_HIGH; 272 break; 273 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: 274 Type = ELF::R_PPC64_DTPREL16_HIGHA; 275 break; 276 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 277 Type = ELF::R_PPC64_DTPREL16_HIGHER; 278 break; 279 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 280 Type = ELF::R_PPC64_DTPREL16_HIGHERA; 281 break; 282 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 283 Type = ELF::R_PPC64_DTPREL16_HIGHEST; 284 break; 285 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 286 Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 287 break; 288 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 289 if (is64Bit()) 290 Type = ELF::R_PPC64_GOT_TLSGD16; 291 else 292 Type = ELF::R_PPC_GOT_TLSGD16; 293 break; 294 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 295 Type = ELF::R_PPC64_GOT_TLSGD16_LO; 296 break; 297 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 298 Type = ELF::R_PPC64_GOT_TLSGD16_HI; 299 break; 300 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 301 Type = ELF::R_PPC64_GOT_TLSGD16_HA; 302 break; 303 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 304 if (is64Bit()) 305 Type = ELF::R_PPC64_GOT_TLSLD16; 306 else 307 Type = ELF::R_PPC_GOT_TLSLD16; 308 break; 309 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 310 Type = ELF::R_PPC64_GOT_TLSLD16_LO; 311 break; 312 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 313 Type = ELF::R_PPC64_GOT_TLSLD16_HI; 314 break; 315 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 316 Type = ELF::R_PPC64_GOT_TLSLD16_HA; 317 break; 318 case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 319 /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 320 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 321 Type = ELF::R_PPC64_GOT_TPREL16_DS; 322 break; 323 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 324 /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 325 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 326 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 327 break; 328 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 329 Type = ELF::R_PPC64_GOT_TPREL16_HI; 330 break; 331 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 332 /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 333 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 334 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 335 break; 336 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 337 /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 338 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 339 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 340 break; 341 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 342 Type = ELF::R_PPC64_GOT_TPREL16_HA; 343 break; 344 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 345 Type = ELF::R_PPC64_GOT_DTPREL16_HI; 346 break; 347 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 348 Type = ELF::R_PPC64_GOT_DTPREL16_HA; 349 break; 350 } 351 break; 352 case PPC::fixup_ppc_half16ds: 353 case PPC::fixup_ppc_half16dq: 354 switch (Modifier) { 355 default: llvm_unreachable("Unsupported Modifier"); 356 case MCSymbolRefExpr::VK_None: 357 Type = ELF::R_PPC64_ADDR16_DS; 358 break; 359 case MCSymbolRefExpr::VK_PPC_LO: 360 Type = ELF::R_PPC64_ADDR16_LO_DS; 361 break; 362 case MCSymbolRefExpr::VK_GOT: 363 Type = ELF::R_PPC64_GOT16_DS; 364 break; 365 case MCSymbolRefExpr::VK_PPC_GOT_LO: 366 Type = ELF::R_PPC64_GOT16_LO_DS; 367 break; 368 case MCSymbolRefExpr::VK_PPC_TOC: 369 Type = ELF::R_PPC64_TOC16_DS; 370 break; 371 case MCSymbolRefExpr::VK_PPC_TOC_LO: 372 Type = ELF::R_PPC64_TOC16_LO_DS; 373 break; 374 case MCSymbolRefExpr::VK_TPREL: 375 Type = ELF::R_PPC64_TPREL16_DS; 376 break; 377 case MCSymbolRefExpr::VK_PPC_TPREL_LO: 378 Type = ELF::R_PPC64_TPREL16_LO_DS; 379 break; 380 case MCSymbolRefExpr::VK_DTPREL: 381 Type = ELF::R_PPC64_DTPREL16_DS; 382 break; 383 case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 384 Type = ELF::R_PPC64_DTPREL16_LO_DS; 385 break; 386 case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 387 Type = ELF::R_PPC64_GOT_TPREL16_DS; 388 break; 389 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 390 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 391 break; 392 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 393 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 394 break; 395 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 396 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 397 break; 398 } 399 break; 400 case PPC::fixup_ppc_nofixup: 401 switch (Modifier) { 402 default: llvm_unreachable("Unsupported Modifier"); 403 case MCSymbolRefExpr::VK_PPC_TLSGD: 404 if (is64Bit()) 405 Type = ELF::R_PPC64_TLSGD; 406 else 407 Type = ELF::R_PPC_TLSGD; 408 break; 409 case MCSymbolRefExpr::VK_PPC_TLSLD: 410 if (is64Bit()) 411 Type = ELF::R_PPC64_TLSLD; 412 else 413 Type = ELF::R_PPC_TLSLD; 414 break; 415 case MCSymbolRefExpr::VK_PPC_TLS: 416 if (is64Bit()) 417 Type = ELF::R_PPC64_TLS; 418 else 419 Type = ELF::R_PPC_TLS; 420 break; 421 case MCSymbolRefExpr::VK_PPC_TLS_PCREL: 422 Type = ELF::R_PPC64_TLS; 423 break; 424 } 425 break; 426 case PPC::fixup_ppc_imm34: 427 switch (Modifier) { 428 default: 429 report_fatal_error("Unsupported Modifier for fixup_ppc_imm34."); 430 case MCSymbolRefExpr::VK_DTPREL: 431 Type = ELF::R_PPC64_DTPREL34; 432 break; 433 case MCSymbolRefExpr::VK_TPREL: 434 Type = ELF::R_PPC64_TPREL34; 435 break; 436 } 437 break; 438 case FK_Data_8: 439 switch (Modifier) { 440 default: llvm_unreachable("Unsupported Modifier"); 441 case MCSymbolRefExpr::VK_PPC_TOCBASE: 442 Type = ELF::R_PPC64_TOC; 443 break; 444 case MCSymbolRefExpr::VK_None: 445 Type = ELF::R_PPC64_ADDR64; 446 break; 447 case MCSymbolRefExpr::VK_PPC_DTPMOD: 448 Type = ELF::R_PPC64_DTPMOD64; 449 break; 450 case MCSymbolRefExpr::VK_TPREL: 451 Type = ELF::R_PPC64_TPREL64; 452 break; 453 case MCSymbolRefExpr::VK_DTPREL: 454 Type = ELF::R_PPC64_DTPREL64; 455 break; 456 } 457 break; 458 case FK_Data_4: 459 Type = ELF::R_PPC_ADDR32; 460 break; 461 case FK_Data_2: 462 Type = ELF::R_PPC_ADDR16; 463 break; 464 } 465 } 466 return Type; 467 } 468 469 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 470 unsigned Type) const { 471 switch (Type) { 472 default: 473 return false; 474 475 case ELF::R_PPC_REL24: 476 case ELF::R_PPC64_REL24_NOTOC: 477 // If the target symbol has a local entry point, we must keep the 478 // target symbol to preserve that information for the linker. 479 // The "other" values are stored in the last 6 bits of the second byte. 480 // The traditional defines for STO values assume the full byte and thus 481 // the shift to pack it. 482 unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2; 483 return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 484 } 485 } 486 487 std::unique_ptr<MCObjectTargetWriter> 488 llvm::createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) { 489 return std::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI); 490 } 491