diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d543db86e..4a05bf796 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -733,7 +733,7 @@ jobs: run: cargo install cargo-fuzz --version=^0.11.2 - name: Test Foundation - run: cargo test $ARGS --features=$INTERESTING_FEATURES,catch-all,Foundation + run: cargo test $ARGS --features=$INTERESTING_FEATURES,catch-all,Foundation_all - name: Test all frameworks if: ${{ env.FULL }} @@ -742,7 +742,7 @@ jobs: - name: Test in release mode # Disabled on GNUStep 2.1 for now if: ${{ env.FULL && matrix.runtime != 'gnustep-2-1' }} - run: cargo test $ARGS --features=Foundation --release + run: cargo test $ARGS --features=Foundation_all --release - name: Run fuzzing if: ${{ matrix.fuzz }} @@ -770,7 +770,7 @@ jobs: - name: Test with unstable features if: ${{ env.FULL && matrix.nightly }} - run: cargo test $ARGS --features=$INTERESTING_FEATURES,catch-all,Foundation,$UNSTABLE_FEATURES + run: cargo test $ARGS --features=$INTERESTING_FEATURES,catch-all,Foundation_all,$UNSTABLE_FEATURES test-compiler-rt: name: Test Compiler-RT diff --git a/Cargo.lock b/Cargo.lock index 1816cfe93..c4b56a51e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -479,6 +479,13 @@ dependencies = [ "trybuild", ] +[[package]] +name = "test_autorelease_return" +version = "0.1.0" +dependencies = [ + "objc2", +] + [[package]] name = "test_extern_protocol" version = "0.1.0" diff --git a/crates/icrate/tests/mutable_array.rs b/crates/icrate/tests/mutable_array.rs index 5577b5c29..4a326807d 100644 --- a/crates/icrate/tests/mutable_array.rs +++ b/crates/icrate/tests/mutable_array.rs @@ -1,6 +1,6 @@ #![cfg(feature = "Foundation_NSMutableArray")] -use objc2::msg_send; use objc2::rc::{__RcTestObject, __ThreadTestData, autoreleasepool}; +use objc2::{msg_send, ClassType}; #[cfg(feature = "Foundation_NSNumber")] use icrate::Foundation::NSNumber; @@ -57,6 +57,26 @@ fn test_replace() { #[test] #[cfg(feature = "Foundation_NSMutableString")] +#[cfg_attr( + feature = "gnustep-1-7", + ignore = "thread safety issues regarding initialization" +)] +fn test_containing_mutable_objects() { + use Foundation::NSMutableString; + + let mut array = NSMutableArray::from_vec(vec![NSMutableString::new()]); + let _: &mut NSMutableString = &mut array[0]; + let _: &mut NSMutableString = array.get_mut(0).unwrap(); + let _: &mut NSMutableString = array.first_mut().unwrap(); + let _: &mut NSMutableString = array.last_mut().unwrap(); +} + +#[test] +#[cfg(feature = "Foundation_NSMutableString")] +#[cfg_attr( + feature = "gnustep-1-7", + ignore = "thread safety issues regarding initialization" +)] fn test_allowed_mutation_while_iterating() { use Foundation::{NSMutableString, NSString}; @@ -77,6 +97,10 @@ fn test_allowed_mutation_while_iterating() { not(debug_assertions), ignore = "enumeration mutation only detected with debug assertions on" )] +#[cfg_attr( + all(debug_assertions, feature = "gnustep-1-7"), + ignore = "thread safety issues regarding initialization" +)] fn test_iter_mutation_detection() { let array = NSMutableArray::from_id_slice(&[NSObject::new(), NSObject::new()]); @@ -86,6 +110,24 @@ fn test_iter_mutation_detection() { } } +#[test] +#[cfg_attr( + feature = "gnustep-1-7", + ignore = "thread safety issues regarding initialization" +)] +fn test_threaded() { + std::thread::scope(|s| { + s.spawn(|| { + let _ = NSMutableArray::from_vec(vec![NSObject::new(), NSObject::new()]); + }); + + s.spawn(|| { + let array = >::alloc(); + assert!(array.is_some()); + }); + }); +} + #[test] fn test_remove() { let mut array = NSMutableArray::new(); diff --git a/crates/objc2/src/rc/test_object.rs b/crates/objc2/src/rc/test_object.rs index ac726a991..a125c4668 100644 --- a/crates/objc2/src/rc/test_object.rs +++ b/crates/objc2/src/rc/test_object.rs @@ -41,7 +41,13 @@ impl __ThreadTestData { // GNUStep doesn't call `autorelease` if it's overridden expected.autorelease = 0; } - assert_eq!(current, expected); + if current != expected { + panic!( + "got differing amounts of calls: + current: `{current:?}`, + expected: `{expected:?}`" + ) + } } } @@ -385,6 +391,10 @@ mod tests { } else if cfg!(all(target_arch = "arm", panic = "unwind")) { // 32-bit ARM unwinding interferes with the optimization 2 + } else if cfg!(target_arch = "x86") { + // x86 autorelease_return is not currently tail-called, so the + // optimization doesn't work on declare_class! functions. + 2 } else if cfg!(any(debug_assertions, feature = "exception")) { 2 } else { diff --git a/crates/test-assembly/crates/test_autorelease_return/Cargo.toml b/crates/test-assembly/crates/test_autorelease_return/Cargo.toml new file mode 100644 index 000000000..839455a45 --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "test_autorelease_return" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +path = "lib.rs" + +[dependencies] +objc2 = { path = "../../../objc2", default-features = false } + +[features] +default = ["apple", "std"] +std = ["objc2/std"] +# Runtime +apple = ["objc2/apple"] +gnustep-1-7 = ["objc2/gnustep-1-7"] +gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8"] +gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9"] +gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0"] +gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1"] + +# Hack +assembly-features = [] diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/apple-aarch64.s b/crates/test-assembly/crates/test_autorelease_return/expected/apple-aarch64.s new file mode 100644 index 000000000..e6e48e2bf --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/apple-aarch64.s @@ -0,0 +1,16 @@ + .section __TEXT,__text,regular,pure_instructions + .globl _simple + .p2align 2 +_simple: + b _objc_autoreleaseReturnValue + + .globl _with_body + .p2align 2 +_with_body: + stp x29, x30, [sp, #-16]! + mov x29, sp + bl _objc_msgSend + ldp x29, x30, [sp], #16 + b _objc_autoreleaseReturnValue + +.subsections_via_symbols diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7.s b/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7.s new file mode 100644 index 000000000..871359113 --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7.s @@ -0,0 +1,19 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .globl _simple + .p2align 2 + .code 32 +_simple: + b _objc_autoreleaseReturnValue + + .globl _with_body + .p2align 2 + .code 32 +_with_body: + push {r7, lr} + mov r7, sp + bl _objc_msgSend + pop {r7, lr} + b _objc_autoreleaseReturnValue + +.subsections_via_symbols diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7s.s b/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7s.s new file mode 100644 index 000000000..5eb906fb8 --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/apple-armv7s.s @@ -0,0 +1,22 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .globl _simple + .p2align 2 + .code 32 +_simple: + push {r7, lr} + mov r7, sp + bl _objc_autoreleaseReturnValue + pop {r7, pc} + + .globl _with_body + .p2align 2 + .code 32 +_with_body: + push {r7, lr} + mov r7, sp + bl _objc_msgSend + bl _objc_autoreleaseReturnValue + pop {r7, pc} + +.subsections_via_symbols diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86.s b/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86.s new file mode 100644 index 000000000..2fb76c89d --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86.s @@ -0,0 +1,28 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .globl _simple + .p2align 4, 0x90 +_simple: + push ebp + mov ebp, esp + pop ebp + jmp _objc_autoreleaseReturnValue + + .globl _with_body + .p2align 4, 0x90 +_with_body: + push ebp + mov ebp, esp + sub esp, 8 + mov eax, dword ptr [ebp + 8] + mov ecx, dword ptr [ebp + 12] + mov dword ptr [esp + 4], ecx + mov dword ptr [esp], eax + call _objc_msgSend + mov dword ptr [esp], eax + call _objc_autoreleaseReturnValue + add esp, 8 + pop ebp + ret + +.subsections_via_symbols diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86_64.s b/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86_64.s new file mode 100644 index 000000000..f91040ede --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/apple-x86_64.s @@ -0,0 +1,21 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .globl _simple + .p2align 4, 0x90 +_simple: + push rbp + mov rbp, rsp + pop rbp + jmp _objc_autoreleaseReturnValue + + .globl _with_body + .p2align 4, 0x90 +_with_body: + push rbp + mov rbp, rsp + call _objc_msgSend + mov rdi, rax + pop rbp + jmp _objc_autoreleaseReturnValue + +.subsections_via_symbols diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86.s b/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86.s new file mode 100644 index 000000000..11b62021c --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86.s @@ -0,0 +1,56 @@ + .text + .intel_syntax noprefix + .section .text.simple,"ax",@progbits + .globl simple + .p2align 4, 0x90 + .type simple,@function +simple: + push ebx + sub esp, 8 + mov eax, dword ptr [esp + 16] + call .L0$pb +.L0$pb: + pop ebx +.Ltmp0: + add ebx, offset _GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb) + mov dword ptr [esp], eax + call objc_autoreleaseReturnValue@PLT + add esp, 8 + pop ebx + ret +.Lfunc_end0: + .size simple, .Lfunc_end0-simple + + .section .text.with_body,"ax",@progbits + .globl with_body + .p2align 4, 0x90 + .type with_body,@function +with_body: + push ebx + push edi + push esi + sub esp, 16 + mov esi, dword ptr [esp + 32] + mov edi, dword ptr [esp + 36] + call .L1$pb +.L1$pb: + pop ebx +.Ltmp1: + add ebx, offset _GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb) + mov dword ptr [esp + 4], edi + mov dword ptr [esp], esi + call objc_msg_lookup@PLT + mov dword ptr [esp + 4], edi + mov dword ptr [esp], esi + call eax + mov dword ptr [esp], eax + call objc_autoreleaseReturnValue@PLT + add esp, 16 + pop esi + pop edi + pop ebx + ret +.Lfunc_end1: + .size with_body, .Lfunc_end1-with_body + + .section ".note.GNU-stack","",@progbits diff --git a/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86_64.s b/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86_64.s new file mode 100644 index 000000000..cb0231d87 --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/expected/gnustep-x86_64.s @@ -0,0 +1,34 @@ + .text + .intel_syntax noprefix + .section .text.simple,"ax",@progbits + .globl simple + .p2align 4, 0x90 + .type simple,@function +simple: + jmp qword ptr [rip + objc_autoreleaseReturnValue@GOTPCREL] +.Lfunc_end0: + .size simple, .Lfunc_end0-simple + + .section .text.with_body,"ax",@progbits + .globl with_body + .p2align 4, 0x90 + .type with_body,@function +with_body: + push r14 + push rbx + push rax + mov rbx, rsi + mov r14, rdi + call qword ptr [rip + objc_msg_lookup@GOTPCREL] + mov rdi, r14 + mov rsi, rbx + call rax + mov rdi, rax + add rsp, 8 + pop rbx + pop r14 + jmp qword ptr [rip + objc_autoreleaseReturnValue@GOTPCREL] +.Lfunc_end1: + .size with_body, .Lfunc_end1-with_body + + .section ".note.GNU-stack","",@progbits diff --git a/crates/test-assembly/crates/test_autorelease_return/lib.rs b/crates/test-assembly/crates/test_autorelease_return/lib.rs new file mode 100644 index 000000000..ca38e3871 --- /dev/null +++ b/crates/test-assembly/crates/test_autorelease_return/lib.rs @@ -0,0 +1,16 @@ +//! Test that `Id::autorelease_return` is tail-called properly. + +use objc2::__macro_helpers::{MsgSendId, New}; +use objc2::rc::Id; +use objc2::runtime::{Class, Object, Sel}; + +#[no_mangle] +fn simple(obj: Id) -> *mut Object { + Id::autorelease_return(obj) +} + +#[no_mangle] +unsafe fn with_body(cls: &Class, sel: Sel) -> *mut Object { + let obj: Option> = New::send_message_id(cls, sel, ()); + Id::autorelease_return(obj.unwrap_unchecked()) +} diff --git a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7.s b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7.s index 5d5dcde7b..dc5a4638e 100644 --- a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7.s +++ b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7.s @@ -35,8 +35,8 @@ _iter_once: cmp r0, r1 blo LBB1_4 ldr r6, [r4] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC1_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC1_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC1_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC1_0+8)) add r8, r4, #4 LPC1_0: ldr r10, [pc, r10] @@ -115,8 +115,8 @@ _iter: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC3_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC3_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC3_1+8)) movt r8, :upper16:(l_anon.[ID].0-(LPC3_1+8)) LPC3_0: @@ -189,8 +189,8 @@ _iter_noop: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC4_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC4_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC4_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC4_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC4_1+8)) movt r8, :upper16:(l_anon.[ID].0-(LPC4_1+8)) LPC4_0: @@ -258,8 +258,8 @@ _iter_retained: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC5_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr-(LPC5_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC5_1+8)) movt r8, :upper16:(l_anon.[ID].0-(LPC5_1+8)) LPC5_0: @@ -312,7 +312,7 @@ l_anon.[ID].0: .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers .p2align 2, 0x0 -L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h37ea10daa3c347f7E$non_lazy_ptr: +LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr: .indirect_symbol SYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0) .long 0 diff --git a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7s.s b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7s.s index 4b56642a1..7542f916a 100644 --- a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7s.s +++ b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-armv7s.s @@ -35,8 +35,8 @@ _iter_once: cmp r0, r1 blo LBB1_4 ldr r6, [r4] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC1_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC1_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC1_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC1_0+8)) add r8, r4, #4 LPC1_0: ldr r10, [pc, r10] @@ -115,8 +115,8 @@ _iter: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC3_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC3_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC3_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC3_1+8)) LPC3_0: ldr r10, [pc, r10] @@ -189,8 +189,8 @@ _iter_noop: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC4_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC4_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC4_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC4_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC4_1+8)) LPC4_0: ldr r10, [pc, r10] @@ -258,8 +258,8 @@ _iter_retained: str r0, [sp, #84] str r0, [sp, #80] str r6, [sp, #8] - movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC5_0+8)) - movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr-(LPC5_0+8)) + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) movw r8, :lower16:(l_anon.[ID].0-(LPC5_1+8)) LPC5_0: ldr r10, [pc, r10] @@ -312,7 +312,7 @@ l_anon.[ID].0: .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers .p2align 2, 0x0 -L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h6140e5efd2948e03E$non_lazy_ptr: +LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr: .indirect_symbol SYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0) .long 0 diff --git a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-x86.s b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-x86.s index 7c7c5e5f3..d615c9ff8 100644 --- a/crates/test-assembly/crates/test_fast_enumeration/expected/apple-x86.s +++ b/crates/test-assembly/crates/test_fast_enumeration/expected/apple-x86.s @@ -57,7 +57,7 @@ L1$pb: mov dword ptr [ebp - 20], eax mov edx, dword ptr [esi] lea edi, [esi + 68] - mov ebx, dword ptr [ecx + L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h230d5b6091d37064E$non_lazy_ptr-L1$pb] + mov ebx, dword ptr [ecx + LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-L1$pb] mov eax, dword ptr [ebx] test eax, eax jne LBB1_4 @@ -153,7 +153,7 @@ L3$pb: mov dword ptr [ebp - 52], 0 mov dword ptr [ebp - 28], 0 mov dword ptr [ebp - 24], 0 - mov esi, dword ptr [eax + L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h230d5b6091d37064E$non_lazy_ptr-L3$pb] + mov esi, dword ptr [eax + LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-L3$pb] lea eax, [eax + l_anon.[ID].0-L3$pb] mov dword ptr [ebp - 16], eax xor eax, eax @@ -246,7 +246,7 @@ L4$pb: mov dword ptr [ebp - 52], 0 mov dword ptr [ebp - 28], 0 mov dword ptr [ebp - 24], 0 - mov esi, dword ptr [eax + L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h230d5b6091d37064E$non_lazy_ptr-L4$pb] + mov esi, dword ptr [eax + LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-L4$pb] lea eax, [eax + l_anon.[ID].0-L4$pb] mov dword ptr [ebp - 16], eax xor eax, eax @@ -332,7 +332,7 @@ L5$pb: mov dword ptr [ebp - 52], 0 mov dword ptr [ebp - 28], 0 mov dword ptr [ebp - 24], 0 - mov edi, dword ptr [eax + L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h230d5b6091d37064E$non_lazy_ptr-L5$pb] + mov edi, dword ptr [eax + LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-L5$pb] lea eax, [eax + l_anon.[ID].0-L5$pb] mov dword ptr [ebp - 16], eax xor eax, eax @@ -390,7 +390,7 @@ l_anon.[ID].0: .asciz "countByEnumeratingWithState:objects:count:" .section __IMPORT,__pointers,non_lazy_symbol_pointers -L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h230d5b6091d37064E$non_lazy_ptr: +LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr: .indirect_symbol SYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0) .long 0 diff --git a/crates/test-assembly/src/lib.rs b/crates/test-assembly/src/lib.rs index a74b2fa6d..84252bee1 100644 --- a/crates/test-assembly/src/lib.rs +++ b/crates/test-assembly/src/lib.rs @@ -157,7 +157,16 @@ fn demangle_assembly(assembly: &str) -> String { // Find all identifiers, and attempt to demangle them let assembly = RE_SYMBOL.replace_all(assembly, |caps: &Captures| { - let symbol = caps.get(0).unwrap().as_str(); + let mut symbol = caps.get(0).unwrap().as_str(); + let (mut prefix, mut suffix) = ("", ""); + if symbol.starts_with("L__") { + prefix = "L"; + symbol = symbol.strip_prefix('L').unwrap(); + if let Some(stripped) = symbol.strip_suffix("$non_lazy_ptr") { + suffix = "$non_lazy_ptr"; + symbol = stripped; + } + } match rustc_demangle::try_demangle(symbol) { Ok(s) => { let s = s.to_string(); @@ -174,9 +183,9 @@ fn demangle_assembly(assembly: &str) -> String { list_for_this_symbol.len() - 1 }); - format!("SYM({s}, {unique_identifier})") + format!("{prefix}SYM({s}, {unique_identifier}){suffix}") } - Err(_) => symbol.to_string(), + Err(_) => format!("{prefix}{symbol}{suffix}"), } }); // Replace anonymous section names @@ -189,6 +198,29 @@ mod tests { fn test_demangle() { use super::*; + let before = r#" + movw r10, :lower16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h32db0c71005d38edE$non_lazy_ptr-(LPC5_0+8)) + movt r10, :upper16:(L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h32db0c71005d38edE$non_lazy_ptr-(LPC5_0+8)) + + .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers + .p2align 2, 0x0 +L__ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h32db0c71005d38edE$non_lazy_ptr: + .indirect_symbol __ZN6icrate10Foundation9generated14__NSEnumerator17NSFastEnumeration41countByEnumeratingWithState_objects_count10CACHED_SEL17h86a0ced45445d2c5E + .long 0 + "#; + let after = r#" + movw r10, :lower16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) + movt r10, :upper16:(LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr-(LPC5_0+8)) + + .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers + .p2align 2, 0x0 +LSYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 0)$non_lazy_ptr: + .indirect_symbol SYM(icrate::Foundation::generated::__NSEnumerator::NSFastEnumeration::countByEnumeratingWithState_objects_count::CACHED_SEL::GENERATED_ID, 1) + .long 0 + "#; + let output = demangle_assembly(before); + assert_eq!(output, after, "Got {output}"); + let before = r#" .section __TEXT,__text,regular,pure_instructions .intel_syntax noprefix