1 //===- RelocationResolver.cpp ------------------------------------*- C++ -*-===// 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 // This file defines utilities to resolve relocations in object files. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Object/RelocationResolver.h" 14 15 namespace llvm { 16 namespace object { 17 18 static int64_t getELFAddend(RelocationRef R) { 19 Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); 20 handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) { 21 report_fatal_error(EI.message()); 22 }); 23 return *AddendOrErr; 24 } 25 26 static bool supportsX86_64(uint64_t Type) { 27 switch (Type) { 28 case ELF::R_X86_64_NONE: 29 case ELF::R_X86_64_64: 30 case ELF::R_X86_64_DTPOFF32: 31 case ELF::R_X86_64_DTPOFF64: 32 case ELF::R_X86_64_PC32: 33 case ELF::R_X86_64_PC64: 34 case ELF::R_X86_64_32: 35 case ELF::R_X86_64_32S: 36 return true; 37 default: 38 return false; 39 } 40 } 41 42 static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) { 43 switch (R.getType()) { 44 case ELF::R_X86_64_NONE: 45 return A; 46 case ELF::R_X86_64_64: 47 case ELF::R_X86_64_DTPOFF32: 48 case ELF::R_X86_64_DTPOFF64: 49 return S + getELFAddend(R); 50 case ELF::R_X86_64_PC32: 51 case ELF::R_X86_64_PC64: 52 return S + getELFAddend(R) - R.getOffset(); 53 case ELF::R_X86_64_32: 54 case ELF::R_X86_64_32S: 55 return (S + getELFAddend(R)) & 0xFFFFFFFF; 56 default: 57 llvm_unreachable("Invalid relocation type"); 58 } 59 } 60 61 static bool supportsAArch64(uint64_t Type) { 62 switch (Type) { 63 case ELF::R_AARCH64_ABS32: 64 case ELF::R_AARCH64_ABS64: 65 return true; 66 default: 67 return false; 68 } 69 } 70 71 static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) { 72 switch (R.getType()) { 73 case ELF::R_AARCH64_ABS32: 74 return (S + getELFAddend(R)) & 0xFFFFFFFF; 75 case ELF::R_AARCH64_ABS64: 76 return S + getELFAddend(R); 77 default: 78 llvm_unreachable("Invalid relocation type"); 79 } 80 } 81 82 static bool supportsBPF(uint64_t Type) { 83 switch (Type) { 84 case ELF::R_BPF_64_32: 85 case ELF::R_BPF_64_64: 86 return true; 87 default: 88 return false; 89 } 90 } 91 92 static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) { 93 switch (R.getType()) { 94 case ELF::R_BPF_64_32: 95 return (S + A) & 0xFFFFFFFF; 96 case ELF::R_BPF_64_64: 97 return S + A; 98 default: 99 llvm_unreachable("Invalid relocation type"); 100 } 101 } 102 103 static bool supportsMips64(uint64_t Type) { 104 switch (Type) { 105 case ELF::R_MIPS_32: 106 case ELF::R_MIPS_64: 107 case ELF::R_MIPS_TLS_DTPREL64: 108 case ELF::R_MIPS_PC32: 109 return true; 110 default: 111 return false; 112 } 113 } 114 115 static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) { 116 switch (R.getType()) { 117 case ELF::R_MIPS_32: 118 return (S + getELFAddend(R)) & 0xFFFFFFFF; 119 case ELF::R_MIPS_64: 120 return S + getELFAddend(R); 121 case ELF::R_MIPS_TLS_DTPREL64: 122 return S + getELFAddend(R) - 0x8000; 123 case ELF::R_MIPS_PC32: 124 return S + getELFAddend(R) - R.getOffset(); 125 default: 126 llvm_unreachable("Invalid relocation type"); 127 } 128 } 129 130 static bool supportsMSP430(uint64_t Type) { 131 switch (Type) { 132 case ELF::R_MSP430_32: 133 case ELF::R_MSP430_16_BYTE: 134 return true; 135 default: 136 return false; 137 } 138 } 139 140 static uint64_t resolveMSP430(RelocationRef R, uint64_t S, uint64_t A) { 141 switch (R.getType()) { 142 case ELF::R_MSP430_32: 143 return (S + getELFAddend(R)) & 0xFFFFFFFF; 144 case ELF::R_MSP430_16_BYTE: 145 return (S + getELFAddend(R)) & 0xFFFF; 146 default: 147 llvm_unreachable("Invalid relocation type"); 148 } 149 } 150 151 static bool supportsPPC64(uint64_t Type) { 152 switch (Type) { 153 case ELF::R_PPC64_ADDR32: 154 case ELF::R_PPC64_ADDR64: 155 case ELF::R_PPC64_REL32: 156 case ELF::R_PPC64_REL64: 157 return true; 158 default: 159 return false; 160 } 161 } 162 163 static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) { 164 switch (R.getType()) { 165 case ELF::R_PPC64_ADDR32: 166 return (S + getELFAddend(R)) & 0xFFFFFFFF; 167 case ELF::R_PPC64_ADDR64: 168 return S + getELFAddend(R); 169 case ELF::R_PPC64_REL32: 170 return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; 171 case ELF::R_PPC64_REL64: 172 return S + getELFAddend(R) - R.getOffset(); 173 default: 174 llvm_unreachable("Invalid relocation type"); 175 } 176 } 177 178 static bool supportsSystemZ(uint64_t Type) { 179 switch (Type) { 180 case ELF::R_390_32: 181 case ELF::R_390_64: 182 return true; 183 default: 184 return false; 185 } 186 } 187 188 static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) { 189 switch (R.getType()) { 190 case ELF::R_390_32: 191 return (S + getELFAddend(R)) & 0xFFFFFFFF; 192 case ELF::R_390_64: 193 return S + getELFAddend(R); 194 default: 195 llvm_unreachable("Invalid relocation type"); 196 } 197 } 198 199 static bool supportsSparc64(uint64_t Type) { 200 switch (Type) { 201 case ELF::R_SPARC_32: 202 case ELF::R_SPARC_64: 203 case ELF::R_SPARC_UA32: 204 case ELF::R_SPARC_UA64: 205 return true; 206 default: 207 return false; 208 } 209 } 210 211 static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) { 212 switch (R.getType()) { 213 case ELF::R_SPARC_32: 214 case ELF::R_SPARC_64: 215 case ELF::R_SPARC_UA32: 216 case ELF::R_SPARC_UA64: 217 return S + getELFAddend(R); 218 default: 219 llvm_unreachable("Invalid relocation type"); 220 } 221 } 222 223 static bool supportsAmdgpu(uint64_t Type) { 224 switch (Type) { 225 case ELF::R_AMDGPU_ABS32: 226 case ELF::R_AMDGPU_ABS64: 227 return true; 228 default: 229 return false; 230 } 231 } 232 233 static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) { 234 switch (R.getType()) { 235 case ELF::R_AMDGPU_ABS32: 236 case ELF::R_AMDGPU_ABS64: 237 return S + getELFAddend(R); 238 default: 239 llvm_unreachable("Invalid relocation type"); 240 } 241 } 242 243 static bool supportsX86(uint64_t Type) { 244 switch (Type) { 245 case ELF::R_386_NONE: 246 case ELF::R_386_32: 247 case ELF::R_386_PC32: 248 return true; 249 default: 250 return false; 251 } 252 } 253 254 static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) { 255 switch (R.getType()) { 256 case ELF::R_386_NONE: 257 return A; 258 case ELF::R_386_32: 259 return S + A; 260 case ELF::R_386_PC32: 261 return S - R.getOffset() + A; 262 default: 263 llvm_unreachable("Invalid relocation type"); 264 } 265 } 266 267 static bool supportsPPC32(uint64_t Type) { 268 switch (Type) { 269 case ELF::R_PPC_ADDR32: 270 case ELF::R_PPC_REL32: 271 return true; 272 default: 273 return false; 274 } 275 } 276 277 static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) { 278 switch (R.getType()) { 279 case ELF::R_PPC_ADDR32: 280 return (S + getELFAddend(R)) & 0xFFFFFFFF; 281 case ELF::R_PPC_REL32: 282 return (S + getELFAddend(R) - R.getOffset()) & 0xFFFFFFFF; 283 } 284 llvm_unreachable("Invalid relocation type"); 285 } 286 287 static bool supportsARM(uint64_t Type) { 288 return Type == ELF::R_ARM_ABS32; 289 } 290 291 static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) { 292 if (R.getType() == ELF::R_ARM_ABS32) 293 return (S + A) & 0xFFFFFFFF; 294 llvm_unreachable("Invalid relocation type"); 295 } 296 297 static bool supportsAVR(uint64_t Type) { 298 switch (Type) { 299 case ELF::R_AVR_16: 300 case ELF::R_AVR_32: 301 return true; 302 default: 303 return false; 304 } 305 } 306 307 static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) { 308 switch (R.getType()) { 309 case ELF::R_AVR_16: 310 return (S + getELFAddend(R)) & 0xFFFF; 311 case ELF::R_AVR_32: 312 return (S + getELFAddend(R)) & 0xFFFFFFFF; 313 default: 314 llvm_unreachable("Invalid relocation type"); 315 } 316 } 317 318 static bool supportsLanai(uint64_t Type) { 319 return Type == ELF::R_LANAI_32; 320 } 321 322 static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) { 323 if (R.getType() == ELF::R_LANAI_32) 324 return (S + getELFAddend(R)) & 0xFFFFFFFF; 325 llvm_unreachable("Invalid relocation type"); 326 } 327 328 static bool supportsMips32(uint64_t Type) { 329 switch (Type) { 330 case ELF::R_MIPS_32: 331 case ELF::R_MIPS_TLS_DTPREL32: 332 return true; 333 default: 334 return false; 335 } 336 } 337 338 static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) { 339 // FIXME: Take in account implicit addends to get correct results. 340 uint32_t Rel = R.getType(); 341 if (Rel == ELF::R_MIPS_32) 342 return (S + A) & 0xFFFFFFFF; 343 if (Rel == ELF::R_MIPS_TLS_DTPREL32) 344 return (S + A) & 0xFFFFFFFF; 345 llvm_unreachable("Invalid relocation type"); 346 } 347 348 static bool supportsSparc32(uint64_t Type) { 349 switch (Type) { 350 case ELF::R_SPARC_32: 351 case ELF::R_SPARC_UA32: 352 return true; 353 default: 354 return false; 355 } 356 } 357 358 static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) { 359 uint32_t Rel = R.getType(); 360 if (Rel == ELF::R_SPARC_32 || Rel == ELF::R_SPARC_UA32) 361 return S + getELFAddend(R); 362 return A; 363 } 364 365 static bool supportsHexagon(uint64_t Type) { 366 return Type == ELF::R_HEX_32; 367 } 368 369 static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) { 370 if (R.getType() == ELF::R_HEX_32) 371 return S + getELFAddend(R); 372 llvm_unreachable("Invalid relocation type"); 373 } 374 375 static bool supportsRISCV(uint64_t Type) { 376 switch (Type) { 377 case ELF::R_RISCV_NONE: 378 case ELF::R_RISCV_32: 379 case ELF::R_RISCV_32_PCREL: 380 case ELF::R_RISCV_64: 381 case ELF::R_RISCV_SET6: 382 case ELF::R_RISCV_SUB6: 383 case ELF::R_RISCV_ADD8: 384 case ELF::R_RISCV_SUB8: 385 case ELF::R_RISCV_ADD16: 386 case ELF::R_RISCV_SUB16: 387 case ELF::R_RISCV_ADD32: 388 case ELF::R_RISCV_SUB32: 389 case ELF::R_RISCV_ADD64: 390 case ELF::R_RISCV_SUB64: 391 return true; 392 default: 393 return false; 394 } 395 } 396 397 static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) { 398 int64_t RA = getELFAddend(R); 399 switch (R.getType()) { 400 case ELF::R_RISCV_NONE: 401 return A; 402 case ELF::R_RISCV_32: 403 return (S + RA) & 0xFFFFFFFF; 404 case ELF::R_RISCV_32_PCREL: 405 return (S + RA - R.getOffset()) & 0xFFFFFFFF; 406 case ELF::R_RISCV_64: 407 return S + RA; 408 case ELF::R_RISCV_SET6: 409 return (A & 0xC0) | ((S + RA) & 0x3F); 410 case ELF::R_RISCV_SUB6: 411 return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F); 412 case ELF::R_RISCV_ADD8: 413 return (A + (S + RA)) & 0xFF; 414 case ELF::R_RISCV_SUB8: 415 return (A - (S + RA)) & 0xFF; 416 case ELF::R_RISCV_ADD16: 417 return (A + (S + RA)) & 0xFFFF; 418 case ELF::R_RISCV_SUB16: 419 return (A - (S + RA)) & 0xFFFF; 420 case ELF::R_RISCV_ADD32: 421 return (A + (S + RA)) & 0xFFFFFFFF; 422 case ELF::R_RISCV_SUB32: 423 return (A - (S + RA)) & 0xFFFFFFFF; 424 case ELF::R_RISCV_ADD64: 425 return (A + (S + RA)); 426 case ELF::R_RISCV_SUB64: 427 return (A - (S + RA)); 428 default: 429 llvm_unreachable("Invalid relocation type"); 430 } 431 } 432 433 static bool supportsCOFFX86(uint64_t Type) { 434 switch (Type) { 435 case COFF::IMAGE_REL_I386_SECREL: 436 case COFF::IMAGE_REL_I386_DIR32: 437 return true; 438 default: 439 return false; 440 } 441 } 442 443 static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) { 444 switch (R.getType()) { 445 case COFF::IMAGE_REL_I386_SECREL: 446 case COFF::IMAGE_REL_I386_DIR32: 447 return (S + A) & 0xFFFFFFFF; 448 default: 449 llvm_unreachable("Invalid relocation type"); 450 } 451 } 452 453 static bool supportsCOFFX86_64(uint64_t Type) { 454 switch (Type) { 455 case COFF::IMAGE_REL_AMD64_SECREL: 456 case COFF::IMAGE_REL_AMD64_ADDR64: 457 return true; 458 default: 459 return false; 460 } 461 } 462 463 static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) { 464 switch (R.getType()) { 465 case COFF::IMAGE_REL_AMD64_SECREL: 466 return (S + A) & 0xFFFFFFFF; 467 case COFF::IMAGE_REL_AMD64_ADDR64: 468 return S + A; 469 default: 470 llvm_unreachable("Invalid relocation type"); 471 } 472 } 473 474 static bool supportsCOFFARM(uint64_t Type) { 475 switch (Type) { 476 case COFF::IMAGE_REL_ARM_SECREL: 477 case COFF::IMAGE_REL_ARM_ADDR32: 478 return true; 479 default: 480 return false; 481 } 482 } 483 484 static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) { 485 switch (R.getType()) { 486 case COFF::IMAGE_REL_ARM_SECREL: 487 case COFF::IMAGE_REL_ARM_ADDR32: 488 return (S + A) & 0xFFFFFFFF; 489 default: 490 llvm_unreachable("Invalid relocation type"); 491 } 492 } 493 494 static bool supportsCOFFARM64(uint64_t Type) { 495 switch (Type) { 496 case COFF::IMAGE_REL_ARM64_SECREL: 497 case COFF::IMAGE_REL_ARM64_ADDR64: 498 return true; 499 default: 500 return false; 501 } 502 } 503 504 static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) { 505 switch (R.getType()) { 506 case COFF::IMAGE_REL_ARM64_SECREL: 507 return (S + A) & 0xFFFFFFFF; 508 case COFF::IMAGE_REL_ARM64_ADDR64: 509 return S + A; 510 default: 511 llvm_unreachable("Invalid relocation type"); 512 } 513 } 514 515 static bool supportsMachOX86_64(uint64_t Type) { 516 return Type == MachO::X86_64_RELOC_UNSIGNED; 517 } 518 519 static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) { 520 if (R.getType() == MachO::X86_64_RELOC_UNSIGNED) 521 return S; 522 llvm_unreachable("Invalid relocation type"); 523 } 524 525 static bool supportsWasm32(uint64_t Type) { 526 switch (Type) { 527 case wasm::R_WASM_FUNCTION_INDEX_LEB: 528 case wasm::R_WASM_TABLE_INDEX_SLEB: 529 case wasm::R_WASM_TABLE_INDEX_I32: 530 case wasm::R_WASM_MEMORY_ADDR_LEB: 531 case wasm::R_WASM_MEMORY_ADDR_SLEB: 532 case wasm::R_WASM_MEMORY_ADDR_I32: 533 case wasm::R_WASM_TYPE_INDEX_LEB: 534 case wasm::R_WASM_GLOBAL_INDEX_LEB: 535 case wasm::R_WASM_FUNCTION_OFFSET_I32: 536 case wasm::R_WASM_SECTION_OFFSET_I32: 537 case wasm::R_WASM_EVENT_INDEX_LEB: 538 case wasm::R_WASM_GLOBAL_INDEX_I32: 539 return true; 540 default: 541 return false; 542 } 543 } 544 545 static bool supportsWasm64(uint64_t Type) { 546 switch (Type) { 547 case wasm::R_WASM_MEMORY_ADDR_LEB64: 548 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 549 case wasm::R_WASM_MEMORY_ADDR_I64: 550 case wasm::R_WASM_TABLE_INDEX_SLEB64: 551 case wasm::R_WASM_TABLE_INDEX_I64: 552 return true; 553 default: 554 return supportsWasm32(Type); 555 } 556 } 557 558 static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) { 559 switch (R.getType()) { 560 case wasm::R_WASM_FUNCTION_INDEX_LEB: 561 case wasm::R_WASM_TABLE_INDEX_SLEB: 562 case wasm::R_WASM_TABLE_INDEX_I32: 563 case wasm::R_WASM_MEMORY_ADDR_LEB: 564 case wasm::R_WASM_MEMORY_ADDR_SLEB: 565 case wasm::R_WASM_MEMORY_ADDR_I32: 566 case wasm::R_WASM_TYPE_INDEX_LEB: 567 case wasm::R_WASM_GLOBAL_INDEX_LEB: 568 case wasm::R_WASM_FUNCTION_OFFSET_I32: 569 case wasm::R_WASM_SECTION_OFFSET_I32: 570 case wasm::R_WASM_EVENT_INDEX_LEB: 571 case wasm::R_WASM_GLOBAL_INDEX_I32: 572 // For wasm section, its offset at 0 -- ignoring Value 573 return A; 574 default: 575 llvm_unreachable("Invalid relocation type"); 576 } 577 } 578 579 static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) { 580 switch (R.getType()) { 581 case wasm::R_WASM_MEMORY_ADDR_LEB64: 582 case wasm::R_WASM_MEMORY_ADDR_SLEB64: 583 case wasm::R_WASM_MEMORY_ADDR_I64: 584 case wasm::R_WASM_TABLE_INDEX_SLEB64: 585 case wasm::R_WASM_TABLE_INDEX_I64: 586 // For wasm section, its offset at 0 -- ignoring Value 587 return A; 588 default: 589 return resolveWasm32(R, S, A); 590 } 591 } 592 593 std::pair<bool (*)(uint64_t), RelocationResolver> 594 getRelocationResolver(const ObjectFile &Obj) { 595 if (Obj.isCOFF()) { 596 switch (Obj.getArch()) { 597 case Triple::x86_64: 598 return {supportsCOFFX86_64, resolveCOFFX86_64}; 599 case Triple::x86: 600 return {supportsCOFFX86, resolveCOFFX86}; 601 case Triple::arm: 602 case Triple::thumb: 603 return {supportsCOFFARM, resolveCOFFARM}; 604 case Triple::aarch64: 605 return {supportsCOFFARM64, resolveCOFFARM64}; 606 default: 607 return {nullptr, nullptr}; 608 } 609 } else if (Obj.isELF()) { 610 if (Obj.getBytesInAddress() == 8) { 611 switch (Obj.getArch()) { 612 case Triple::x86_64: 613 return {supportsX86_64, resolveX86_64}; 614 case Triple::aarch64: 615 case Triple::aarch64_be: 616 return {supportsAArch64, resolveAArch64}; 617 case Triple::bpfel: 618 case Triple::bpfeb: 619 return {supportsBPF, resolveBPF}; 620 case Triple::mips64el: 621 case Triple::mips64: 622 return {supportsMips64, resolveMips64}; 623 case Triple::ppc64le: 624 case Triple::ppc64: 625 return {supportsPPC64, resolvePPC64}; 626 case Triple::systemz: 627 return {supportsSystemZ, resolveSystemZ}; 628 case Triple::sparcv9: 629 return {supportsSparc64, resolveSparc64}; 630 case Triple::amdgcn: 631 return {supportsAmdgpu, resolveAmdgpu}; 632 case Triple::riscv64: 633 return {supportsRISCV, resolveRISCV}; 634 default: 635 return {nullptr, nullptr}; 636 } 637 } 638 639 // 32-bit object file 640 assert(Obj.getBytesInAddress() == 4 && 641 "Invalid word size in object file"); 642 643 switch (Obj.getArch()) { 644 case Triple::x86: 645 return {supportsX86, resolveX86}; 646 case Triple::ppc: 647 return {supportsPPC32, resolvePPC32}; 648 case Triple::arm: 649 case Triple::armeb: 650 return {supportsARM, resolveARM}; 651 case Triple::avr: 652 return {supportsAVR, resolveAVR}; 653 case Triple::lanai: 654 return {supportsLanai, resolveLanai}; 655 case Triple::mipsel: 656 case Triple::mips: 657 return {supportsMips32, resolveMips32}; 658 case Triple::msp430: 659 return {supportsMSP430, resolveMSP430}; 660 case Triple::sparc: 661 return {supportsSparc32, resolveSparc32}; 662 case Triple::hexagon: 663 return {supportsHexagon, resolveHexagon}; 664 case Triple::riscv32: 665 return {supportsRISCV, resolveRISCV}; 666 default: 667 return {nullptr, nullptr}; 668 } 669 } else if (Obj.isMachO()) { 670 if (Obj.getArch() == Triple::x86_64) 671 return {supportsMachOX86_64, resolveMachOX86_64}; 672 return {nullptr, nullptr}; 673 } else if (Obj.isWasm()) { 674 if (Obj.getArch() == Triple::wasm32) 675 return {supportsWasm32, resolveWasm32}; 676 if (Obj.getArch() == Triple::wasm64) 677 return {supportsWasm64, resolveWasm64}; 678 return {nullptr, nullptr}; 679 } 680 681 llvm_unreachable("Invalid object file"); 682 } 683 684 } // namespace object 685 } // namespace llvm 686