diff options
author | Ash Logan <ash@heyquark.com> | 2025-02-27 13:58:38 +0000 |
---|---|---|
committer | Anna Wilcox <awilcox@wilcox-tech.com> | 2025-05-04 17:51:21 +0000 |
commit | a63a3d152e1128c76c359ebef570c7b6e752d284 (patch) | |
tree | 7af27cf7f2eddc2638c35929083b88c31c216e9a | |
parent | 3ce000829d8d4f900fdaedee646ca8bca3a2cbbe (diff) | |
download | packages-a63a3d152e1128c76c359ebef570c7b6e752d284.tar.gz packages-a63a3d152e1128c76c359ebef570c7b6e752d284.tar.bz2 packages-a63a3d152e1128c76c359ebef570c7b6e752d284.tar.xz packages-a63a3d152e1128c76c359ebef570c7b6e752d284.zip |
user/llvm18: Add support for additional relocation types in RuntimeDyld
* The REL24 relocation is used in JIT'd code for library calls.
Implementing this allows the ExecutionEngine tests, clang-repl, and
llvmpipe to all start working.
* Implement a bunch of "easy" relocations while we're here. These are
not really tested.
* Anna's existing patch leaked a "delta" variable into the switch scope,
so add braces to contain that. Also, the PPC ELF ABI doesn't specify
an overflow check for REL32 (unlike ppc64), so remove it and allow
truncation.
* Add mention of the problematic relocation type to the LLVM error
message, so if other relocation types (like the PLT/GOT relocs) end up
being needed later, this is obvious from user reports.
Partially resolves #1233
-rw-r--r-- | user/llvm18/APKBUILD | 28 | ||||
-rw-r--r-- | user/llvm18/dyld-elf-ppc32-2.patch | 176 | ||||
-rw-r--r-- | user/llvm18/dyld-elf-ppc32.patch | 8 |
3 files changed, 183 insertions, 29 deletions
diff --git a/user/llvm18/APKBUILD b/user/llvm18/APKBUILD index 694f8245e..bc5bb0c83 100644 --- a/user/llvm18/APKBUILD +++ b/user/llvm18/APKBUILD @@ -6,7 +6,7 @@ _pkgname=llvm pkgver=18.1.8 _majorver=${pkgver%%.*} pkgname=$_pkgname$_majorver -pkgrel=0 +pkgrel=1 pkgdesc="Low Level Virtual Machine compiler system, version $_majorver" url="https://llvm.org/" arch="all" @@ -23,6 +23,7 @@ source="https://github.com/llvm/llvm-project/releases/download/llvmorg-$pkgver/l llvm-fix-build-with-musl-libc.patch disable-FileSystemTest.CreateDir-perms-assert.patch dyld-elf-ppc32.patch + dyld-elf-ppc32-2.patch hexagon.patch i586-json-test.patch m68k-endianness.patch @@ -98,28 +99,6 @@ prepare() { # RISC-V issues are uninvestigated as of yet. #1233 rm -v test/CodeGen/RISCV/rvv/combine-store-extract-crash.ll rm -v test/CodeGen/RISCV/xtheadmempair.ll - - # ExecutionEngine for PPC32 requires R_PPC_REL24 to be - # implemented in RuntimeDyld. - for _bad_orc in global-ctor-with-cast.ll \ - global-variable-alignment.ll \ - trivial-call-to-function.ll \ - trivial-call-to-internal-function.ll \ - trivial-reference-to-global-variable.ll \ - trivial-reference-to-internal-variable-nonzeroinit.ll \ - trivial-reference-to-internal-variable-zeroinit.ll \ - trivial-return-zero.ll \ - weak-comdat.ll; do - rm -v test/ExecutionEngine/Orc/$_bad_orc; - done - for _bad_ee in frem.ll mov64zext32.ll \ - test-interp-vec-arithm_float.ll \ - test-interp-vec-arithm_int.ll \ - test-interp-vec-logical.ll \ - test-interp-vec-setcond-fp.ll \ - test-interp-vec-setcond-int.ll; do - rm -v test/ExecutionEngine/$_bad_ee; - done esac #1053 @@ -337,7 +316,8 @@ _common_subpkg() { sha512sums="25eeee9984c8b4d0fbc240df90f33cbb000d3b0414baff5c8982beafcc5e59e7ef18f6f85d95b3a5f60cb3d4cd4f877c80487b5768bc21bc833f107698ad93db llvm-project-18.1.8.src.tar.xz f84cd65d7042e89826ba6e8d48c4c302bf4980da369d7f19a55f217e51c00ca8ed178d453df3a3cee76598a7cecb94aed0775a6d24fe73266f82749913fc3e71 llvm-fix-build-with-musl-libc.patch d56945bb0476561028616222846257f990d66e68b4458894f8791252411038b269831f9400ed9df3b99f571a82443caaac347a8b38a5516c77c3583469118309 disable-FileSystemTest.CreateDir-perms-assert.patch -9e919d7988b18c7184d9fccd14911d70bbe2acf82d38111bfd41f1ba2976fea07e74527a43c552dad158c982a2cbaaf03f6a1e98c7a1fc02b4e75382cfe6d0b2 dyld-elf-ppc32.patch +94099a2001d38d935ece69943971e7943691e8a5471b31ae2169e1f2f2e60de8a9fe8ba718dfa942c84d22fced7492bc9b87bce84a3e801a46e549c4657f9eb5 dyld-elf-ppc32.patch +23cd4c38899bf001f6e27db9a21dfb9fa1264a81993ef423535ff3132d2a258b4706d201ff15a96624db82540ee09c14810af0392f0786262699dfdbcb47b9ba dyld-elf-ppc32-2.patch 807587a0c897d47a01a846c5c4f7cbf1f2d16437a163b66ee2381a7147e9d04b0141b2c76d022db61903d0d2841ddb267ba98c66c9e41501ca41837659743df8 hexagon.patch 22dedbbdc99ab4df6c64921186803552fc61cfc00a5cd052295a5450809e7205ac21dd07df158b7e99b960084b2ec3d8832480a8cd073fe1c2d613cd21c90b60 i586-json-test.patch b186ce027dca389cfd23dc91b03e023e688c7610745cf62d0b277b6178972bcf55abf0df08453f2a6b85dc61dba929cb565cb30633a2fe0f193a443f54025bf7 m68k-endianness.patch diff --git a/user/llvm18/dyld-elf-ppc32-2.patch b/user/llvm18/dyld-elf-ppc32-2.patch new file mode 100644 index 000000000..d424554e2 --- /dev/null +++ b/user/llvm18/dyld-elf-ppc32-2.patch @@ -0,0 +1,176 @@ +Author: Ash Logan <ash@heyquark.com> + +adds a whole bunch of ppc32 relocation types - probably only REL32 and REL24 are actually needed, or +indeed tested. +mostly copypasted from the ppc64 code with ELFv2 ABI removed. No attempt is made to support GOT/PLT +relocations, since the JIT doesn't seem to generate these. + +makes clang-repl and the ExecutionEngine testsuites pass, and allows llvmpipe to run + +diff -rup llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +--- llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp 2024-06-16 03:21:32.000000000 +1000 ++++ llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp 2025-02-26 00:10:04.114888980 +1100 +@@ -1029,6 +1029,14 @@ uint8_t *RuntimeDyldImpl::createStubFunc + writeBytesUnaligned(JrT9Instr, Addr + 24, 4); + writeBytesUnaligned(NopInstr, Addr + 28, 4); + return Addr; ++ } else if (Arch == Triple::ppc || Arch == Triple::ppcle) { ++ // The ABI docs talk endlessly of PLTs and GOTs which have special relocation types. ++ // For the generic types, just do a generic jump. ++ writeInt32BE(Addr, 0x3D800000); // lis r12, h(addr) ++ writeInt32BE(Addr+4, 0x618C0000); // ori r12, l(addr) ++ writeInt32BE(Addr+8, 0x7D8903A6); // mtctr r12 ++ writeInt32BE(Addr+12, 0x4E800420); // bctr ++ return Addr; + } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { + // Depending on which version of the ELF ABI is in use, we need to + // generate one of two variants of the stub. They both start with +diff -rup llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +--- llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp 2024-06-16 03:21:32.000000000 +1000 ++++ llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp 2025-02-26 00:32:57.021079997 +1100 +@@ -819,7 +819,7 @@ void RuntimeDyldELF::resolvePPC32Relocat + uint8_t *LocalAddress = Section.getAddressWithOffset(Offset); + switch (Type) { + default: +- report_fatal_error("Relocation type not implemented yet!"); ++ report_fatal_error("Relocation type " + Twine(Type) + " not implemented yet!"); + break; + case ELF::R_PPC_ADDR16_LO: + writeInt16BE(LocalAddress, applyPPClo(Value + Addend)); +@@ -835,6 +835,37 @@ void RuntimeDyldELF::resolvePPC32Relocat + int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend); + writeInt32BE(LocalAddress, delta); + } break; ++ case ELF::R_PPC_REL24: { ++ uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); ++ int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend); ++ if (SignExtend64<26>(delta) != delta) ++ llvm_unreachable("Relocation R_PPC_REL24 overflow"); ++ uint32_t Inst = readBytesUnaligned(LocalAddress, 4); ++ writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC)); ++ } break; ++ case ELF::R_PPC_ADDR32: { ++ int64_t delta = static_cast<int64_t>(Value + Addend); ++ writeInt32BE(LocalAddress, delta); ++ } break; ++ case ELF::R_PPC_ADDR30: { ++ uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); ++ int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend); ++ uint32_t Inst = readBytesUnaligned(LocalAddress, 4); ++ writeInt32BE(LocalAddress, (Inst & 0x00000003) | (delta & 0xFFFFFFFC)); ++ } break; ++ case ELF::R_PPC_ADDR24: { ++ int64_t delta = static_cast<int64_t>(Value + Addend); ++ if (SignExtend64<26>(delta) != delta) ++ llvm_unreachable("Relocation R_PPC_ADDR24 overflow"); ++ uint32_t Inst = readBytesUnaligned(LocalAddress, 4); ++ writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC)); ++ } break; ++ case ELF::R_PPC_ADDR16: { ++ int64_t delta = static_cast<int64_t>(Value + Addend); ++ if (SignExtend64<16>(delta) != delta) ++ llvm_unreachable("Relocation R_PPC_ADDR16 overflow"); ++ writeInt16BE(LocalAddress, delta); ++ } break; + } + } + +@@ -1551,6 +1587,76 @@ RuntimeDyldELF::processRelocationRef( + processSimpleRelocation(SectionID, Offset, RelType, Value); + } + ++ } else if (Arch == Triple::ppc || Arch == Triple::ppcle) { ++ if (RelType == ELF::R_PPC_REL24) { ++ // A PPC branch relocation will need a stub function if the target is ++ // an external symbol (either Value.SymbolName is set, or SymType is ++ // Symbol::ST_Unknown) or if the target address is not within the ++ // signed 24-bits branch address. ++ SectionEntry &Section = Sections[SectionID]; ++ uint8_t *Target = Section.getAddressWithOffset(Offset); ++ bool RangeOverflow = false; ++ bool IsExtern = Value.SymbolName || SymType == SymbolRef::ST_Unknown; ++ if (!IsExtern) { ++ uint8_t *RelocTarget = ++ Sections[Value.SectionID].getAddressWithOffset(Value.Addend); ++ int64_t delta = static_cast<int64_t>(Target - RelocTarget); ++ // If it is within 26-bits branch range, just set the branch target ++ if (SignExtend64<26>(delta) != delta) { ++ RangeOverflow = true; ++ } else { ++ RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); ++ addRelocationForSection(RE, Value.SectionID); ++ } ++ } ++ if (IsExtern || RangeOverflow) { ++ // It is an external symbol (either Value.SymbolName is set, or ++ // SymType is SymbolRef::ST_Unknown) or out of range. ++ StubMap::const_iterator i = Stubs.find(Value); ++ if (i != Stubs.end()) { ++ // Symbol function stub already created, just relocate to it ++ resolveRelocation(Section, Offset, ++ reinterpret_cast<uint64_t>( ++ Section.getAddressWithOffset(i->second)), ++ RelType, 0); ++ LLVM_DEBUG(dbgs() << " Stub function found\n"); ++ } else { ++ // Create a new stub function. ++ LLVM_DEBUG(dbgs() << " Create a new stub function\n"); ++ Stubs[Value] = Section.getStubOffset(); ++ uint8_t *StubTargetAddr = createStubFunction( ++ Section.getAddressWithOffset(Section.getStubOffset())); ++ ++ // The PPC32 ELF ABI doesn't really provide any guidance on the no-PLT case so let's do ++ // our best ++ uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress(); ++ if (!IsTargetLittleEndian) ++ StubRelocOffset += 2; ++ ++ RelocationEntry REh(SectionID, StubRelocOffset + 0, ++ ELF::R_PPC_ADDR16_HI, Value.Addend); ++ RelocationEntry REl(SectionID, StubRelocOffset + 4, ++ ELF::R_PPC_ADDR16_LO, Value.Addend); ++ ++ if (Value.SymbolName) { ++ addRelocationForSymbol(REh, Value.SymbolName); ++ addRelocationForSymbol(REl, Value.SymbolName); ++ } else { ++ addRelocationForSection(REh, Value.SectionID); ++ addRelocationForSection(REl, Value.SectionID); ++ } ++ ++ resolveRelocation(Section, Offset, reinterpret_cast<uint64_t>( ++ Section.getAddressWithOffset( ++ Section.getStubOffset())), ++ RelType, 0); ++ Section.advanceStubOffset(getMaxStubSize()); ++ } ++ } ++ } else { ++ // Normal relocations are fine as-is probs ++ processSimpleRelocation(SectionID, Offset, RelType, Value); ++ } + } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { + if (RelType == ELF::R_PPC64_REL24) { + // Determine ABI variant in use for this object. +@@ -2228,6 +2334,8 @@ size_t RuntimeDyldELF::getGOTEntrySize() + case Triple::x86: + case Triple::arm: + case Triple::thumb: ++ case Triple::ppc: ++ case Triple::ppcle: + Result = sizeof(uint32_t); + break; + case Triple::mips: +diff -rup llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +--- llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h 2024-06-16 03:21:32.000000000 +1000 ++++ llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h 2025-02-25 23:51:24.830956991 +1100 +@@ -69,6 +69,8 @@ class RuntimeDyldELF : public RuntimeDyl + return 16; + else if (IsMipsN64ABI) + return 32; ++ else if (Arch == Triple::ppc || Arch == Triple::ppcle) ++ return 16; + else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) + return 44; + else if (Arch == Triple::x86_64) + diff --git a/user/llvm18/dyld-elf-ppc32.patch b/user/llvm18/dyld-elf-ppc32.patch index 7fb744169..77ff8c644 100644 --- a/user/llvm18/dyld-elf-ppc32.patch +++ b/user/llvm18/dyld-elf-ppc32.patch @@ -8,17 +8,15 @@ Needs more tests before submitting upstream, but seems to DTRT. --- llvm-14.0.6.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp.old 2022-06-22 16:46:24.000000000 +0000 +++ llvm-14.0.6.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp 2022-11-28 06:33:12.239921624 +0000 -@@ -830,6 +830,13 @@ +@@ -830,6 +830,11 @@ case ELF::R_PPC_ADDR16_HA: writeInt16BE(LocalAddress, applyPPCha(Value + Addend)); break; -+ case ELF::R_PPC_REL32: ++ case ELF::R_PPC_REL32: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend); -+ if (SignExtend64<32>(delta) != delta) -+ llvm_unreachable("Relocation R_PPC_REL32 overflow"); + writeInt32BE(LocalAddress, delta); -+ break; ++ } break; } } |