From 73fb033b28c8892f1df06fc87a7a4da4082bc9cd Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 14 Jul 2026 19:06:52 +0000 Subject: [PATCH] ppc: make AltiVec asm PIC-safe, fixing illegal text-relocation at link Every label-address load in these three hand-written AltiVec .S files used absolute addressing (lis rX, ha16(LABEL) / la rY, lo16(LABEL)(rX)), which requires the linker to emit an absolute relocation into .text. That's rejected outright when building a -fPIC dynamiclib ("illegal text-relocation ... for architecture ppc"), since __TEXT pages must stay shareable/read-only across processes. Replace each site with the standard Darwin PPC PIC idiom (confirmed against Apple's own Mach-O Programming Topics doc and the XNU kernel's asm_help.h PICIFY macro): capture the current PC via a linked branch to the next instruction (bcl 20,31,1f / 1: mflr rX), preserving the caller's original LR around it (mflr r0 before, mtlr r0 after, since these are leaf functions whose final blr depends on it), then compute the label's address as PC + (label - here) via addis/la on the now PC-relative ha16/lo16 deltas. Each site reuses whatever register the original lis already targeted, which the surrounding code always treats as fully dead going in, so no additional register pressure or spilling is introduced. _chromaSelectors' .data contents (loopfilter_filters_altivec.S) are left untouched -- the "illegal text-relocation" restriction is specific to __TEXT; ordinary pointer fixups in __DATA are normal and dyld-supported in any PIC dylib. Only the .text instructions that load that table's own address needed the same fix as every other label reference. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01DLC53yuiz8taQDNndUp4rs --- vp8/common/ppc/filter_altivec.S | 216 +++++++++++++++----- vp8/common/ppc/filter_bilinear_altivec.S | 180 ++++++++++++---- vp8/common/ppc/loopfilter_filters_altivec.S | 36 +++- 3 files changed, 336 insertions(+), 96 deletions(-) diff --git a/vp8/common/ppc/filter_altivec.S b/vp8/common/ppc/filter_altivec.S index ee2b4b15d..b7f6f88e6 100644 --- a/vp8/common/ppc/filter_altivec.S +++ b/vp8/common/ppc/filter_altivec.S @@ -67,8 +67,13 @@ _sixtap_predict_ppc: beq- vertical_only_4x4 ;# load up horizontal filter - lis r9, ha16(HFilter) - la r10, lo16(HFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(HFilter - 1b) + la r10, lo16(HFilter - 1b)(r9) lvx v13, r5, r10 addi r5, r5, 16 @@ -80,14 +85,29 @@ _sixtap_predict_ppc: vslw v15, v16, v15 ;# 0x00000040000000400000004000000040 ;# Load up permutation constants - lis r9, ha16(B_0123) - la r10, lo16(B_0123)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_0123 - 1b) + la r10, lo16(B_0123 - 1b)(r9) lvx v16, 0, r10 - lis r9, ha16(B_4567) - la r10, lo16(B_4567)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_4567 - 1b) + la r10, lo16(B_4567 - 1b)(r9) lvx v17, 0, r10 - lis r9, ha16(B_89AB) - la r10, lo16(B_89AB)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_89AB - 1b) + la r10, lo16(B_89AB - 1b)(r9) lvx v18, 0, r10 ;# Back off input buffer by 2 bytes. Need 2 before and 3 after @@ -483,11 +503,21 @@ vertical_only_4x4: slwi r6, r6, 4 ;# index into vertical filter array second_pass_4x4: - lis r9, ha16(b_hilo_4x4) - la r10, lo16(b_hilo_4x4)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo_4x4 - 1b) + la r10, lo16(b_hilo_4x4 - 1b)(r9) lvx v20, 0, r10 - lis r9, ha16(b_hilo) - la r10, lo16(b_hilo)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo - 1b) + la r10, lo16(b_hilo - 1b)(r9) lvx v21, 0, r10 ;# reposition input so that it can go through the @@ -506,8 +536,13 @@ second_pass_4x4: vsldoi v5, v4, v8, 4 - lis r9, ha16(VFilter) - la r10, lo16(VFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(VFilter - 1b) + la r10, lo16(VFilter - 1b)(r9) lvx v13, r6, r10 vspltish v15, 8 @@ -630,8 +665,13 @@ _sixtap_predict8x4_ppc: ;# just skip to the second pass. beq- second_pass_pre_copy_8x4 - lis r9, ha16(HFilter) - la r10, lo16(HFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(HFilter - 1b) + la r10, lo16(HFilter - 1b)(r9) lvx v13, r5, r10 addi r5, r5, 16 @@ -643,14 +683,29 @@ _sixtap_predict8x4_ppc: vslw v15, v16, v15 ;# 0x00000040000000400000004000000040 ;# Load up permutation constants - lis r9, ha16(B_0123) - la r10, lo16(B_0123)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_0123 - 1b) + la r10, lo16(B_0123 - 1b)(r9) lvx v16, 0, r10 - lis r9, ha16(B_4567) - la r10, lo16(B_4567)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_4567 - 1b) + la r10, lo16(B_4567 - 1b)(r9) lvx v17, 0, r10 - lis r9, ha16(B_89AB) - la r10, lo16(B_89AB)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_89AB - 1b) + la r10, lo16(B_89AB - 1b)(r9) lvx v18, 0, r10 ;# Back off input buffer by 2 bytes. Need 2 before and 3 after @@ -1047,8 +1102,13 @@ second_pass_pre_copy_8x4: slwi r6, r6, 4 ;# index into vertical filter array second_pass_8x4: - lis r9, ha16(VFilter) - la r10, lo16(VFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(VFilter - 1b) + la r10, lo16(VFilter - 1b)(r9) lvx v13, r6, r10 vspltish v15, 8 @@ -1235,8 +1295,13 @@ second_pass_8x4: store_aligned_8x4: - lis r9, ha16(b_hilo) - la r10, lo16(b_hilo)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo - 1b) + la r10, lo16(b_hilo - 1b)(r9) lvx v10, 0, r10 vperm v0, v0, v1, v10 @@ -1280,8 +1345,13 @@ store_8x4: b exit_8x4 store_aligned2_8x4: - lis r9, ha16(b_hilo) - la r10, lo16(b_hilo)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo - 1b) + la r10, lo16(b_hilo - 1b)(r9) lvx v10, 0, r10 vperm v2, v2, v3, v10 @@ -1326,8 +1396,13 @@ _sixtap_predict8x8_ppc: ;# just skip to the second pass. beq- second_pass_pre_copy_8x8 - lis r9, ha16(HFilter) - la r10, lo16(HFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(HFilter - 1b) + la r10, lo16(HFilter - 1b)(r9) lvx v13, r5, r10 addi r5, r5, 16 @@ -1339,14 +1414,29 @@ _sixtap_predict8x8_ppc: vslw v15, v16, v15 ;# 0x00000040000000400000004000000040 ;# Load up permutation constants - lis r9, ha16(B_0123) - la r10, lo16(B_0123)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_0123 - 1b) + la r10, lo16(B_0123 - 1b)(r9) lvx v16, 0, r10 - lis r9, ha16(B_4567) - la r10, lo16(B_4567)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_4567 - 1b) + la r10, lo16(B_4567 - 1b)(r9) lvx v17, 0, r10 - lis r9, ha16(B_89AB) - la r10, lo16(B_89AB)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(B_89AB - 1b) + la r10, lo16(B_89AB - 1b)(r9) lvx v18, 0, r10 ;# Back off input buffer by 2 bytes. Need 2 before and 3 after @@ -1902,8 +1992,13 @@ second_pass_pre_copy_8x8: slwi r6, r6, 4 ;# index into vertical filter array second_pass_8x8: - lis r9, ha16(VFilter) - la r10, lo16(VFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(VFilter - 1b) + la r10, lo16(VFilter - 1b)(r9) lvx v13, r6, r10 vspltish v15, 8 @@ -2254,8 +2349,13 @@ second_pass_8x8: store_aligned_8x8: - lis r9, ha16(b_hilo) - la r10, lo16(b_hilo)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo - 1b) + la r10, lo16(b_hilo - 1b)(r9) lvx v10, 0, r10 vperm v0, v0, v1, v10 @@ -2329,8 +2429,13 @@ store_8x8: b exit_8x8 store_aligned2_8x8: - lis r9, ha16(b_hilo) - la r10, lo16(b_hilo)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo - 1b) + la r10, lo16(b_hilo - 1b)(r9) lvx v10, 0, r10 vperm v2, v2, v3, v10 @@ -2387,8 +2492,13 @@ _sixtap_predict16x16_ppc: ;# load up horizontal filter slwi. r5, r5, 5 ;# index into horizontal filter array - lis r9, ha16(HFilter) - la r10, lo16(HFilter)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(HFilter - 1b) + la r10, lo16(HFilter - 1b)(r9) lvx v4, r5, r10 addi r5, r5, 16 @@ -2403,8 +2513,13 @@ _sixtap_predict16x16_ppc: ;# setup constants ;# v14 permutation value for alignment - lis r9, ha16(b_hperm) - la r10, lo16(b_hperm)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hperm - 1b) + la r10, lo16(b_hperm - 1b)(r9) lvx v14, 0, r10 ;# These statements are guessing that there won't be a second pass, @@ -2549,8 +2664,13 @@ second_pass_16x16: ;# downshift by 7 ( divide by 128 ) at the end vspltish v7, 7 - lis r3, ha16(VFilter) - la r10, lo16(VFilter)(r3) + mflr r0 + bcl 20,31,1f +1: + mflr r3 + mtlr r0 + addis r3, r3, ha16(VFilter - 1b) + la r10, lo16(VFilter - 1b)(r3) lvx v0, r6, r10 vspltish v5, 8 diff --git a/vp8/common/ppc/filter_bilinear_altivec.S b/vp8/common/ppc/filter_bilinear_altivec.S index 83b3319ab..07903e791 100644 --- a/vp8/common/ppc/filter_bilinear_altivec.S +++ b/vp8/common/ppc/filter_bilinear_altivec.S @@ -78,14 +78,24 @@ _bilinear_predict4x4_ppc: ;# just skip to the second pass. beq second_pass_4x4_pre_copy_b - lis r9, ha16(hfilter_b) - la r0, lo16(hfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(hfilter_b - 1b) + la r0, lo16(hfilter_b - 1b)(r9) lvx v20, r5, r0 ;# setup constants ;# v14 permutation value for alignment - lis r9, ha16(b_hperm_b) - la r0, lo16(b_hperm_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hperm_b - 1b) + la r0, lo16(b_hperm_b - 1b)(r9) lvx v28, 0, r0 ;# rounding added in on the multiply @@ -96,11 +106,21 @@ _bilinear_predict4x4_ppc: slwi. r6, r6, 5 ;# index into vertical filter array ;# Load up permutation constants - lis r9, ha16(b_0123_b) - la r12, lo16(b_0123_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_0123_b - 1b) + la r12, lo16(b_0123_b - 1b)(r9) lvx v10, 0, r12 - lis r9, ha16(b_4567_b) - la r12, lo16(b_4567_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_4567_b - 1b) + la r12, lo16(b_4567_b - 1b)(r9) lvx v11, 0, r12 lvsl v17, 0, r3 ;# permutate value for alignment @@ -271,8 +291,13 @@ second_pass_4x4_b: vspltish v18, 3 vslh v18, v20, v18 ;# 0x0040 0040 0040 0040 0040 0040 0040 0040 - lis r9, ha16(vfilter_b) - la r10, lo16(vfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(vfilter_b - 1b) + la r10, lo16(vfilter_b - 1b)(r9) lvx v20, r6, r10 addi r6, r6, 16 @@ -396,14 +421,24 @@ _bilinear_predict8x4_ppc: ;# just skip to the second pass. beq second_pass_8x4_pre_copy_b - lis r9, ha16(hfilter_b) - la r0, lo16(hfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(hfilter_b - 1b) + la r0, lo16(hfilter_b - 1b)(r9) lvx v20, r5, r0 ;# setup constants ;# v14 permutation value for alignment - lis r9, ha16(b_hperm_b) - la r0, lo16(b_hperm_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hperm_b - 1b) + la r0, lo16(b_hperm_b - 1b)(r9) lvx v28, 0, r0 ;# rounding added in on the multiply @@ -414,11 +449,21 @@ _bilinear_predict8x4_ppc: slwi. r6, r6, 5 ;# index into vertical filter array ;# Load up permutation constants - lis r9, ha16(b_0123_b) - la r12, lo16(b_0123_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_0123_b - 1b) + la r12, lo16(b_0123_b - 1b)(r9) lvx v10, 0, r12 - lis r9, ha16(b_4567_b) - la r12, lo16(b_4567_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_4567_b - 1b) + la r12, lo16(b_4567_b - 1b)(r9) lvx v11, 0, r12 lvsl v17, 0, r3 ;# permutate value for alignment @@ -589,8 +634,13 @@ second_pass_8x4_b: vspltish v18, 3 vslh v18, v20, v18 ;# 0x0040 0040 0040 0040 0040 0040 0040 0040 - lis r9, ha16(vfilter_b) - la r10, lo16(vfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(vfilter_b - 1b) + la r10, lo16(vfilter_b - 1b)(r9) lvx v20, r6, r10 addi r6, r6, 16 @@ -690,8 +740,13 @@ store_out_8x4_b: b exit_8x4 store_aligned_8x4_b: - lis r9, ha16(b_hilo_b) - la r10, lo16(b_hilo_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo_b - 1b) + la r10, lo16(b_hilo_b - 1b)(r9) lvx v10, 0, r10 vperm v0, v0, v1, v10 @@ -737,14 +792,24 @@ _bilinear_predict8x8_ppc: ;# just skip to the second pass. beq second_pass_8x8_pre_copy_b - lis r9, ha16(hfilter_b) - la r0, lo16(hfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(hfilter_b - 1b) + la r0, lo16(hfilter_b - 1b)(r9) lvx v20, r5, r0 ;# setup constants ;# v14 permutation value for alignment - lis r9, ha16(b_hperm_b) - la r0, lo16(b_hperm_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hperm_b - 1b) + la r0, lo16(b_hperm_b - 1b)(r9) lvx v28, 0, r0 ;# rounding added in on the multiply @@ -755,11 +820,21 @@ _bilinear_predict8x8_ppc: slwi. r6, r6, 5 ;# index into vertical filter array ;# Load up permutation constants - lis r9, ha16(b_0123_b) - la r12, lo16(b_0123_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_0123_b - 1b) + la r12, lo16(b_0123_b - 1b)(r9) lvx v10, 0, r12 - lis r9, ha16(b_4567_b) - la r12, lo16(b_4567_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_4567_b - 1b) + la r12, lo16(b_4567_b - 1b)(r9) lvx v11, 0, r12 lvsl v17, 0, r3 ;# permutate value for alignment @@ -1049,8 +1124,13 @@ second_pass_8x8_b: vspltish v18, 3 vslh v18, v20, v18 ;# 0x0040 0040 0040 0040 0040 0040 0040 0040 - lis r9, ha16(vfilter_b) - la r10, lo16(vfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(vfilter_b - 1b) + la r10, lo16(vfilter_b - 1b)(r9) lvx v20, r6, r10 addi r6, r6, 16 @@ -1234,8 +1314,13 @@ store_out_8x8_b: b exit_8x8 store_aligned_8x8_b: - lis r9, ha16(b_hilo_b) - la r10, lo16(b_hilo_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hilo_b - 1b) + la r10, lo16(b_hilo_b - 1b)(r9) lvx v10, 0, r10 vperm v0, v0, v1, v10 @@ -1307,14 +1392,24 @@ _bilinear_predict16x16_ppc: ;# just skip to the second pass. beq second_pass_16x16_pre_copy_b - lis r9, ha16(hfilter_b) - la r0, lo16(hfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(hfilter_b - 1b) + la r0, lo16(hfilter_b - 1b)(r9) lvx v20, r5, r0 ;# setup constants ;# v14 permutation value for alignment - lis r9, ha16(b_hperm_b) - la r0, lo16(b_hperm_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(b_hperm_b - 1b) + la r0, lo16(b_hperm_b - 1b)(r9) lvx v28, 0, r0 ;# rounding added in on the multiply @@ -2123,8 +2218,13 @@ second_pass_16x16_b: vspltish v18, 3 vslh v18, v20, v18 ;# 0x0040 0040 0040 0040 0040 0040 0040 0040 - lis r9, ha16(vfilter_b) - la r10, lo16(vfilter_b)(r9) + mflr r0 + bcl 20,31,1f +1: + mflr r9 + mtlr r0 + addis r9, r9, ha16(vfilter_b - 1b) + la r10, lo16(vfilter_b - 1b)(r9) lvx v20, r6, r10 addi r6, r6, 16 diff --git a/vp8/common/ppc/loopfilter_filters_altivec.S b/vp8/common/ppc/loopfilter_filters_altivec.S index 9a811ff4f..09edcd6eb 100644 --- a/vp8/common/ppc/loopfilter_filters_altivec.S +++ b/vp8/common/ppc/loopfilter_filters_altivec.S @@ -1412,8 +1412,13 @@ _mbloop_filter_horizontal_edge_uv_ppc: andi. r7, r3, 8 ;# row origin modulo 16 add r7, r7, r7 ;# selects selectors - lis r12, ha16(_chromaSelectors) - la r0, lo16(_chromaSelectors)(r12) + mflr r0 + bcl 20,31,1f +1: + mflr r12 + mtlr r0 + addis r12, r12, ha16(_chromaSelectors - 1b) + la r0, lo16(_chromaSelectors - 1b)(r12) lwzux r0, r7, r0 ;# leave selector addr in r7 lvx v12, 0, r0 ;# mask to concatenate active U,V pels @@ -1658,8 +1663,13 @@ _loop_filter_horizontal_edge_uv_ppc: andi. r7, r3, 8 ;# row origin modulo 16 add r7, r7, r7 ;# selects selectors - lis r12, ha16(_chromaSelectors) - la r0, lo16(_chromaSelectors)(r12) + mflr r0 + bcl 20,31,1f +1: + mflr r12 + mtlr r0 + addis r12, r12, ha16(_chromaSelectors - 1b) + la r0, lo16(_chromaSelectors - 1b)(r12) lwzux r0, r7, r0 ;# leave selector addr in r7 lvx v12, 0, r0 ;# mask to concatenate active U,V pels @@ -2666,12 +2676,22 @@ _loop_filter_simple_vertical_edge_ppc: lvx v2, 0, r7 lvx v3, r8, r7 - lis r12, ha16(_B_hihi) - la r0, lo16(_B_hihi)(r12) + mflr r0 + bcl 20,31,1f +1: + mflr r12 + mtlr r0 + addis r12, r12, ha16(_B_hihi - 1b) + la r0, lo16(_B_hihi - 1b)(r12) lvx v16, 0, r0 - lis r12, ha16(_B_lolo) - la r0, lo16(_B_lolo)(r12) + mflr r0 + bcl 20,31,1f +1: + mflr r12 + mtlr r0 + addis r12, r12, ha16(_B_lolo - 1b) + la r0, lo16(_B_lolo - 1b)(r12) lvx v17, 0, r0 -- 2.43.0