Module Name: src Committed By: riastradh Date: Mon Jul 22 23:18:50 UTC 2024
Modified Files: src/libexec/ld.elf_so/arch/aarch64: rtld_start.S Log Message: ld.elf_so aarch64/rtld_start.S: Sprinkle comments. No functional change intended. Prompted by PR lib/58154. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/libexec/ld.elf_so/arch/aarch64/rtld_start.S Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/ld.elf_so/arch/aarch64/rtld_start.S diff -u src/libexec/ld.elf_so/arch/aarch64/rtld_start.S:1.5 src/libexec/ld.elf_so/arch/aarch64/rtld_start.S:1.6 --- src/libexec/ld.elf_so/arch/aarch64/rtld_start.S:1.5 Thu Mar 24 12:12:00 2022 +++ src/libexec/ld.elf_so/arch/aarch64/rtld_start.S Mon Jul 22 23:18:50 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld_start.S,v 1.5 2022/03/24 12:12:00 andvar Exp $ */ +/* $NetBSD: rtld_start.S,v 1.6 2024/07/22 23:18:50 riastradh Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -60,7 +60,7 @@ #include <machine/asm.h> -RCSID("$NetBSD: rtld_start.S,v 1.5 2022/03/24 12:12:00 andvar Exp $") +RCSID("$NetBSD: rtld_start.S,v 1.6 2024/07/22 23:18:50 riastradh Exp $") /* * void _rtld_start(void (*cleanup)(void), const Obj_Entry *obj, @@ -146,87 +146,122 @@ ENTRY_NP(_rtld_bind_start) END(_rtld_bind_start) /* - * struct rel_tlsdesc { - * uint64_t resolver_fnc; - * uint64_t resolver_arg; + * Entry points used by _rtld_tlsdesc_fill. They will be passed in x0 + * a pointer to: * + * struct rel_tlsdesc { + * uint64_t resolver_fnc; + * uint64_t resolver_arg; + * }; * - * uint64_t _rtld_tlsdesc_static(struct rel_tlsdesc *); + * They are called with nonstandard calling convention and must + * preserve all registers except x0. + */ + +/* + * uint64_t@x0 + * _rtld_tlsdesc_static(struct rel_tlsdesc *rel_tlsdesc@x0); + * + * Resolver function for TLS symbols resolved at load time. * - * Resolver function for TLS symbols resolved at load time + * rel_tlsdesc->resolver_arg is the offset of the static + * thread-local storage region, relative to the start of the TCB. + * + * Nonstandard calling convention: Must preserve all registers + * except x0. */ ENTRY(_rtld_tlsdesc_static) .cfi_startproc - ldr x0, [x0, #8] - ret + ldr x0, [x0, #8] /* x0 := tcboffset */ + ret /* return x0 = tcboffset */ .cfi_endproc END(_rtld_tlsdesc_static) /* - * uint64_t _rtld_tlsdesc_undef(void); + * uint64_t@x0 + * _rtld_tlsdesc_undef(struct rel_tlsdesc *rel_tlsdesc@x0); + * + * Resolver function for weak and undefined TLS symbols. * - * Resolver function for weak and undefined TLS symbols + * rel_tlsdesc->resolver_arg is the Elf_Rela rela->r_addend. + * + * Nonstandard calling convention: Must preserve all registers + * except x0. */ ENTRY(_rtld_tlsdesc_undef) .cfi_startproc - str x1, [sp, #-16]! + str x1, [sp, #-16]! /* save x1 on stack */ .cfi_adjust_cfa_offset 16 - mrs x1, tpidr_el0 - ldr x0, [x0, #8] - sub x0, x0, x1 + mrs x1, tpidr_el0 /* x1 := current thread tcb */ + ldr x0, [x0, #8] /* x0 := rela->r_addend */ + sub x0, x0, x1 /* x0 := rela->r_addend - tcb */ - ldr x1, [sp], #16 - .cfi_adjust_cfa_offset -16 + ldr x1, [sp], #16 /* restore x1 from stack */ + .cfi_adjust_cfa_offset -16 .cfi_endproc - ret + ret /* return x0 = rela->r_addend - tcb */ END(_rtld_tlsdesc_undef) /* - * uint64_t _rtld_tlsdesc_dynamic(struct rel_tlsdesc *); + * uint64_t@x0 + * _rtld_tlsdesc_dynamic(struct rel_tlsdesc *tlsdesc@x0); + * + * Resolver function for TLS symbols from dlopen(). * - * Resolver function for TLS symbols from dlopen() + * rel_tlsdesc->resolver_arg is a pointer to a struct tls_data + * object allocated during relocation. + * + * Nonstandard calling convention: Must preserve all registers + * except x0. */ ENTRY(_rtld_tlsdesc_dynamic) .cfi_startproc /* Save registers used in fast path */ - stp x1, x2, [sp, #(-2 * 16)]! - stp x3, x4, [sp, #(1 * 16)] + stp x1, x2, [sp, #(-2 * 16)]! + stp x3, x4, [sp, #(1 * 16)] .cfi_adjust_cfa_offset 2 * 16 .cfi_rel_offset x1, 0 .cfi_rel_offset x2, 8 .cfi_rel_offset x3, 16 .cfi_rel_offset x4, 24 - /* Test fastpath - inlined version of __tls_get_addr. */ + /* Try for the fast path -- inlined version of __tls_get_addr. */ - ldr x1, [x0, #8] /* tlsdesc ptr */ - mrs x4, tpidr_el0 - ldr x0, [x4] /* DTV pointer (tcb->tcb_dtv) */ + ldr x1, [x0, #8] /* x1 := tlsdesc (struct tls_data *) */ + mrs x4, tpidr_el0 /* x4 := tcb */ + ldr x0, [x4] /* x0 := dtv = tcb->tcb_dtv */ - ldr x3, [x0, #-8] /* DTV_MAX_INDEX(dtv) */ - ldr x2, [x1, #0] /* tlsdesc->td_tlsindex */ + ldr x3, [x0, #-8] /* x3 := max = DTV_MAX_INDEX(dtv) */ + ldr x2, [x1, #0] /* x2 := idx = tlsdesc->td_tlsindex */ cmp x2, x3 - b.lt 1f /* Slow path */ + b.lt 1f /* Slow path if idx < max */ + /* XXX PR lib/58154 */ + + ldr x3, [x0, x2, lsl #3] /* x3 := dtv[idx] */ + cbz x3, 1f /* Slow path if dtv[idx] is null */ - ldr x3, [x0, x2, lsl #3] /* dtv[tlsdesc->td_tlsindex] */ - cbz x3, 1f + /* + * Fast path + * + * return (dtv[tlsdesc->td_tlsindex] + tlsdesc->td_tlsoffs - tcb) + */ + ldr x2, [x1, #8] /* x2 := offs = tlsdesc->td_tlsoffs */ + add x2, x2, x3 /* x2 := addr = dtv[idx] + offs */ + sub x0, x2, x4 /* x0 := addr - tcb - /* Return (dtv[tlsdesc->td_tlsindex] + tlsdesc->td_tlsoffs - tp) */ - ldr x2, [x1, #8] /* tlsdesc->td_tlsoffs */ - add x2, x2, x3 - sub x0, x2, x4 - - /* Restore registers and return */ - ldp x3, x4, [sp, #(1 * 16)] - ldp x1, x2, [sp], #(2 * 16) - .cfi_adjust_cfa_offset -2 * 16 - ret + /* Restore fast path registers and return */ + ldp x3, x4, [sp, #(1 * 16)] + ldp x1, x2, [sp], #(2 * 16) + .cfi_adjust_cfa_offset -2 * 16 + ret /* return x0 = addr - tcb */ /* * Slow path - * return _rtld_tls_get_addr(tp, tlsdesc->td_tlsindex, tlsdesc->td_tlsoffs); + * + * return _rtld_tls_get_addr(tp, tlsdesc->td_tlsindex, + * tlsdesc->td_tlsoffs); * */ 1: @@ -236,18 +271,18 @@ ENTRY(_rtld_tlsdesc_dynamic) .cfi_rel_offset x29, 0 .cfi_rel_offset x30, 8 - stp x5, x6, [sp, #(1 * 16)] - stp x7, x8, [sp, #(2 * 16)] - stp x9, x10, [sp, #(3 * 16)] + stp x5, x6, [sp, #(1 * 16)] + stp x7, x8, [sp, #(2 * 16)] + stp x9, x10, [sp, #(3 * 16)] stp x11, x12, [sp, #(4 * 16)] stp x13, x14, [sp, #(5 * 16)] stp x15, x16, [sp, #(6 * 16)] stp x17, x18, [sp, #(7 * 16)] - .cfi_rel_offset x5, 16 - .cfi_rel_offset x6, 24 - .cfi_rel_offset x7, 32 - .cfi_rel_offset x8, 40 - .cfi_rel_offset x9, 48 + .cfi_rel_offset x5, 16 + .cfi_rel_offset x6, 24 + .cfi_rel_offset x7, 32 + .cfi_rel_offset x8, 40 + .cfi_rel_offset x9, 48 .cfi_rel_offset x10, 56 .cfi_rel_offset x11, 64 .cfi_rel_offset x12, 72 @@ -259,31 +294,32 @@ ENTRY(_rtld_tlsdesc_dynamic) .cfi_rel_offset x18, 120 /* Find the tls offset */ - mov x0, x4 /* tp */ - mov x3, x1 /* tlsdesc ptr */ - ldr x1, [x3, #0] /* tlsdesc->td_tlsindex */ - ldr x2, [x3, #8] /* tlsdesc->td_tlsoffs */ - bl _rtld_tls_get_addr - mrs x1, tpidr_el0 - sub x0, x0, x1 + mov x0, x4 /* x0 := tcb */ + mov x3, x1 /* x3 := tlsdesc */ + ldr x1, [x3, #0] /* x1 := idx = tlsdesc->td_tlsindex */ + ldr x2, [x3, #8] /* x2 := offs = tlsdesc->td_tlsoffs */ + bl _rtld_tls_get_addr /* x0 := addr = _rtld_tls_get_addr(tcb, + * idx, offs) */ + mrs x1, tpidr_el0 /* x1 := tcb */ + sub x0, x0, x1 /* x0 := addr - tcb */ /* Restore slow path registers */ ldp x17, x18, [sp, #(7 * 16)] ldp x15, x16, [sp, #(6 * 16)] ldp x13, x14, [sp, #(5 * 16)] ldp x11, x12, [sp, #(4 * 16)] - ldp x9, x10, [sp, #(3 * 16)] - ldp x7, x8, [sp, #(2 * 16)] - ldp x5, x6, [sp, #(1 * 16)] + ldp x9, x10, [sp, #(3 * 16)] + ldp x7, x8, [sp, #(2 * 16)] + ldp x5, x6, [sp, #(1 * 16)] ldp x29, x30, [sp], #(8 * 16) - .cfi_adjust_cfa_offset -8 * 16 + .cfi_adjust_cfa_offset -8 * 16 .cfi_restore x29 .cfi_restore x30 /* Restore fast path registers and return */ - ldp x3, x4, [sp, #16] - ldp x1, x2, [sp], #(2 * 16) + ldp x3, x4, [sp, #16] + ldp x1, x2, [sp], #(2 * 16) .cfi_adjust_cfa_offset -2 * 16 .cfi_endproc - ret + ret /* return x0 = addr - tcb */ END(_rtld_tlsdesc_dynamic)