head 1.25; access; symbols netbsd-11-0-RC5:1.25 netbsd-11-0-RC4:1.25 netbsd-11-0-RC3:1.25 netbsd-11-0-RC2:1.25 netbsd-11-0-RC1:1.25 perseant-exfatfs-base-20250801:1.25 netbsd-11:1.25.0.2 netbsd-11-base:1.25 netbsd-10-1-RELEASE:1.24 perseant-exfatfs-base-20240630:1.24 perseant-exfatfs:1.24.0.28 perseant-exfatfs-base:1.24 netbsd-8-3-RELEASE:1.24 netbsd-9-4-RELEASE:1.24 netbsd-10-0-RELEASE:1.24 netbsd-10-0-RC6:1.24 netbsd-10-0-RC5:1.24 netbsd-10-0-RC4:1.24 netbsd-10-0-RC3:1.24 netbsd-10-0-RC2:1.24 netbsd-10-0-RC1:1.24 netbsd-10:1.24.0.26 netbsd-10-base:1.24 netbsd-9-3-RELEASE:1.24 cjep_sun2x-base1:1.24 cjep_sun2x:1.24.0.24 cjep_sun2x-base:1.24 cjep_staticlib_x-base1:1.24 netbsd-9-2-RELEASE:1.24 cjep_staticlib_x:1.24.0.22 cjep_staticlib_x-base:1.24 netbsd-9-1-RELEASE:1.24 phil-wifi-20200421:1.24 phil-wifi-20200411:1.24 is-mlppp:1.24.0.20 is-mlppp-base:1.24 phil-wifi-20200406:1.24 netbsd-8-2-RELEASE:1.24 netbsd-9-0-RELEASE:1.24 netbsd-9-0-RC2:1.24 netbsd-9-0-RC1:1.24 phil-wifi-20191119:1.24 netbsd-9:1.24.0.18 netbsd-9-base:1.24 phil-wifi-20190609:1.24 netbsd-8-1-RELEASE:1.24 netbsd-8-1-RC1:1.24 pgoyette-compat-merge-20190127:1.24 pgoyette-compat-20190127:1.24 pgoyette-compat-20190118:1.24 pgoyette-compat-1226:1.24 pgoyette-compat-1126:1.24 pgoyette-compat-1020:1.24 pgoyette-compat-0930:1.24 pgoyette-compat-0906:1.24 netbsd-7-2-RELEASE:1.22.4.1 pgoyette-compat-0728:1.24 netbsd-8-0-RELEASE:1.24 phil-wifi:1.24.0.16 phil-wifi-base:1.24 pgoyette-compat-0625:1.24 netbsd-8-0-RC2:1.24 pgoyette-compat-0521:1.24 pgoyette-compat-0502:1.24 pgoyette-compat-0422:1.24 netbsd-8-0-RC1:1.24 pgoyette-compat-0415:1.24 pgoyette-compat-0407:1.24 pgoyette-compat-0330:1.24 pgoyette-compat-0322:1.24 pgoyette-compat-0315:1.24 netbsd-7-1-2-RELEASE:1.22.4.1 pgoyette-compat:1.24.0.14 pgoyette-compat-base:1.24 netbsd-7-1-1-RELEASE:1.22.4.1 matt-nb8-mediatek:1.24.0.12 matt-nb8-mediatek-base:1.24 perseant-stdc-iso10646:1.24.0.10 perseant-stdc-iso10646-base:1.24 netbsd-8:1.24.0.8 netbsd-8-base:1.24 prg-localcount2-base3:1.24 prg-localcount2-base2:1.24 prg-localcount2-base1:1.24 prg-localcount2:1.24.0.6 prg-localcount2-base:1.24 pgoyette-localcount-20170426:1.24 bouyer-socketcan-base1:1.24 pgoyette-localcount-20170320:1.24 netbsd-7-1:1.22.4.1.0.6 netbsd-7-1-RELEASE:1.22.4.1 netbsd-7-1-RC2:1.22.4.1 netbsd-7-nhusb-base-20170116:1.22.4.1 bouyer-socketcan:1.24.0.4 bouyer-socketcan-base:1.24 pgoyette-localcount-20170107:1.24 netbsd-7-1-RC1:1.22.4.1 pgoyette-localcount-20161104:1.24 netbsd-7-0-2-RELEASE:1.22.4.1 localcount-20160914:1.24 netbsd-7-nhusb:1.22.4.1.0.4 netbsd-7-nhusb-base:1.22.4.1 pgoyette-localcount-20160806:1.24 pgoyette-localcount-20160726:1.24 pgoyette-localcount:1.24.0.2 pgoyette-localcount-base:1.24 netbsd-7-0-1-RELEASE:1.22.4.1 netbsd-7-0:1.22.4.1.0.2 netbsd-7-0-RELEASE:1.22.4.1 netbsd-7-0-RC3:1.22.4.1 netbsd-7-0-RC2:1.22.4.1 netbsd-7-0-RC1:1.22.4.1 netbsd-5-2-3-RELEASE:1.16 netbsd-5-1-5-RELEASE:1.16 netbsd-6-0-6-RELEASE:1.16 netbsd-6-1-5-RELEASE:1.16 netbsd-7:1.22.0.4 netbsd-7-base:1.22 yamt-pagecache-base9:1.22 yamt-pagecache-tag8:1.16 netbsd-6-1-4-RELEASE:1.16 netbsd-6-0-5-RELEASE:1.16 tls-earlyentropy:1.22.0.2 tls-earlyentropy-base:1.22 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.22 riastradh-drm2-base3:1.16 netbsd-6-1-3-RELEASE:1.16 netbsd-6-0-4-RELEASE:1.16 netbsd-5-2-2-RELEASE:1.16 netbsd-5-1-4-RELEASE:1.16 netbsd-6-1-2-RELEASE:1.16 netbsd-6-0-3-RELEASE:1.16 netbsd-5-2-1-RELEASE:1.16 netbsd-5-1-3-RELEASE:1.16 netbsd-6-1-1-RELEASE:1.16 riastradh-drm2-base2:1.16 riastradh-drm2-base1:1.16 riastradh-drm2:1.16.0.66 riastradh-drm2-base:1.16 netbsd-6-1:1.16.0.70 netbsd-6-0-2-RELEASE:1.16 netbsd-6-1-RELEASE:1.16 netbsd-6-1-RC4:1.16 netbsd-6-1-RC3:1.16 agc-symver:1.16.0.68 agc-symver-base:1.16 netbsd-6-1-RC2:1.16 netbsd-6-1-RC1:1.16 yamt-pagecache-base8:1.16 netbsd-5-2:1.16.0.64 netbsd-6-0-1-RELEASE:1.16 yamt-pagecache-base7:1.16 netbsd-5-2-RELEASE:1.16 netbsd-5-2-RC1:1.16 matt-nb6-plus-nbase:1.16 yamt-pagecache-base6:1.16 netbsd-6-0:1.16.0.62 netbsd-6-0-RELEASE:1.16 netbsd-6-0-RC2:1.16 tls-maxphys:1.16.0.60 tls-maxphys-base:1.22 matt-nb6-plus:1.16.0.58 matt-nb6-plus-base:1.16 netbsd-6-0-RC1:1.16 yamt-pagecache-base5:1.16 yamt-pagecache-base4:1.16 netbsd-6:1.16.0.56 netbsd-6-base:1.16 netbsd-5-1-2-RELEASE:1.16 netbsd-5-1-1-RELEASE:1.16 yamt-pagecache-base3:1.16 yamt-pagecache-base2:1.16 yamt-pagecache:1.16.0.54 yamt-pagecache-base:1.16 cherry-xenmp:1.16.0.52 cherry-xenmp-base:1.16 bouyer-quota2-nbase:1.16 bouyer-quota2:1.16.0.50 bouyer-quota2-base:1.16 matt-mips64-premerge-20101231:1.16 matt-nb5-mips64-premerge-20101231:1.16 matt-nb5-pq3:1.16.0.48 matt-nb5-pq3-base:1.16 netbsd-5-1:1.16.0.46 netbsd-5-1-RELEASE:1.16 netbsd-5-1-RC4:1.16 matt-nb5-mips64-k15:1.16 netbsd-5-1-RC3:1.16 netbsd-5-1-RC2:1.16 netbsd-5-1-RC1:1.16 netbsd-5-0-2-RELEASE:1.16 matt-nb5-mips64-premerge-20091211:1.16 matt-premerge-20091211:1.16 matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.16 matt-nb4-mips64-k7-u2a-k9b:1.16 matt-nb5-mips64-u1-k1-k5:1.16 matt-nb5-mips64:1.16.0.44 netbsd-5-0-1-RELEASE:1.16 jym-xensuspend-nbase:1.16 netbsd-5-0:1.16.0.42 netbsd-5-0-RELEASE:1.16 netbsd-5-0-RC4:1.16 netbsd-5-0-RC3:1.16 netbsd-5-0-RC2:1.16 jym-xensuspend:1.16.0.40 jym-xensuspend-base:1.16 netbsd-5-0-RC1:1.16 netbsd-5:1.16.0.38 netbsd-5-base:1.16 matt-mips64-base2:1.16 matt-mips64:1.16.0.36 mjf-devfs2:1.16.0.34 mjf-devfs2-base:1.16 netbsd-4-0-1-RELEASE:1.16 wrstuden-revivesa-base-3:1.16 wrstuden-revivesa-base-2:1.16 wrstuden-fixsa-newbase:1.16 wrstuden-revivesa-base-1:1.16 yamt-pf42-base4:1.16 yamt-pf42-base3:1.16 hpcarm-cleanup-nbase:1.16 yamt-pf42-baseX:1.16 yamt-pf42-base2:1.16 wrstuden-revivesa:1.16.0.32 wrstuden-revivesa-base:1.16 yamt-pf42:1.16.0.30 yamt-pf42-base:1.16 keiichi-mipv6:1.16.0.28 keiichi-mipv6-base:1.16 matt-armv6-nbase:1.16 matt-armv6-prevmlocking:1.16 wrstuden-fixsa-base-1:1.16 netbsd-4-0:1.16.0.26 netbsd-4-0-RELEASE:1.16 cube-autoconf:1.16.0.24 cube-autoconf-base:1.16 netbsd-4-0-RC5:1.16 netbsd-4-0-RC4:1.16 netbsd-4-0-RC3:1.16 netbsd-4-0-RC2:1.16 netbsd-4-0-RC1:1.16 matt-armv6:1.16.0.22 matt-armv6-base:1.16 matt-mips64-base:1.16 hpcarm-cleanup:1.16.0.20 hpcarm-cleanup-base:1.16 netbsd-3-1-1-RELEASE:1.16 netbsd-3-0-3-RELEASE:1.16 wrstuden-fixsa:1.16.0.18 wrstuden-fixsa-base:1.16 abandoned-netbsd-4-base:1.16 abandoned-netbsd-4:1.16.0.12 netbsd-3-1:1.16.0.14 netbsd-3-1-RELEASE:1.16 netbsd-3-0-2-RELEASE:1.16 netbsd-3-1-RC4:1.16 netbsd-3-1-RC3:1.16 netbsd-3-1-RC2:1.16 netbsd-3-1-RC1:1.16 netbsd-4:1.16.0.16 netbsd-4-base:1.16 netbsd-3-0-1-RELEASE:1.16 netbsd-3-0:1.16.0.10 netbsd-3-0-RELEASE:1.16 netbsd-3-0-RC6:1.16 netbsd-3-0-RC5:1.16 netbsd-3-0-RC4:1.16 netbsd-3-0-RC3:1.16 netbsd-3-0-RC2:1.16 netbsd-3-0-RC1:1.16 netbsd-2-0-3-RELEASE:1.16 netbsd-2-1:1.16.0.8 netbsd-2-1-RELEASE:1.16 netbsd-2-1-RC6:1.16 netbsd-2-1-RC5:1.16 netbsd-2-1-RC4:1.16 netbsd-2-1-RC3:1.16 netbsd-2-1-RC2:1.16 netbsd-2-1-RC1:1.16 netbsd-2-0-2-RELEASE:1.16 netbsd-3:1.16.0.6 netbsd-3-base:1.16 netbsd-2-0-1-RELEASE:1.16 netbsd-2:1.16.0.4 netbsd-2-base:1.16 netbsd-2-0-RELEASE:1.16 netbsd-2-0-RC5:1.16 netbsd-2-0-RC4:1.16 netbsd-2-0-RC3:1.16 netbsd-2-0-RC2:1.16 netbsd-2-0-RC1:1.16 netbsd-2-0:1.16.0.2 netbsd-2-0-base:1.16 netbsd-1-6-PATCH002-RELEASE:1.7 netbsd-1-6-PATCH002:1.7 netbsd-1-6-PATCH002-RC4:1.7 netbsd-1-6-PATCH002-RC3:1.7 netbsd-1-6-PATCH002-RC2:1.7 netbsd-1-6-PATCH002-RC1:1.7 netbsd-1-6-PATCH001:1.7 netbsd-1-6-PATCH001-RELEASE:1.7 netbsd-1-6-PATCH001-RC3:1.7 netbsd-1-6-PATCH001-RC2:1.7 netbsd-1-6-PATCH001-RC1:1.7 fvdl_fs64_base:1.15 netbsd-1-6-RELEASE:1.7 netbsd-1-6-RC3:1.7 netbsd-1-6-RC2:1.7 netbsd-1-6-RC1:1.7 netbsd-1-6:1.7.0.2 netbsd-1-6-base:1.7 netbsd-1-5-PATCH003:1.2 netbsd-1-5-PATCH002:1.2 netbsd-1-5-PATCH001:1.2 netbsd-1-5-RELEASE:1.2 netbsd-1-5-BETA2:1.2 netbsd-1-5-BETA:1.2 netbsd-1-5-ALPHA2:1.2 netbsd-1-5:1.2.0.4 netbsd-1-5-base:1.2 minoura-xpg4dl:1.2.0.2 minoura-xpg4dl-base:1.2 wrstuden-devbsize-19991221:1.1 wrstuden-devbsize:1.1.0.4 wrstuden-devbsize-base:1.1 comdex-fall-1999:1.1.0.2 comdex-fall-1999-base:1.1; locks; strict; comment @# @; 1.25 date 2024.08.03.21.59.59; author riastradh; state Exp; branches; next 1.24; commitid R5nq4VHUPO6kqqkF; 1.24 date 2014.08.17.16.57.37; author matt; state Exp; branches 1.24.28.1; next 1.23; commitid lKO0UHLI1mqxIJMx; 1.23 date 2014.08.17.16.14.19; author matt; state Exp; branches; next 1.22; commitid zD9SGDKOFUiQtJMx; 1.22 date 2014.03.22.15.13.10; author matt; state Exp; branches 1.22.4.1; next 1.21; commitid K9jl3DrnRZCRTHtx; 1.21 date 2014.03.21.14.03.30; author matt; state Exp; branches; next 1.20; commitid 4xbezx5Qb0Sbxztx; 1.20 date 2014.03.19.21.52.00; author joerg; state Exp; branches; next 1.19; commitid ZO93QjPmw2pEcmtx; 1.19 date 2014.03.19.15.34.30; author matt; state Exp; branches; next 1.18; commitid dfWKfalamCr47ktx; 1.18 date 2014.03.19.02.39.22; author matt; state Exp; branches; next 1.17; commitid HYXWrPyP06jaPftx; 1.17 date 2014.03.18.23.43.38; author matt; state Exp; branches; next 1.16; commitid 4Y6gmnQvxvaVQetx; 1.16 date 2003.03.02.22.03.40; author mycroft; state Exp; branches 1.16.54.1 1.16.60.1; next 1.15; 1.15 date 2002.10.05.11.59.06; author mycroft; state Exp; branches; next 1.14; 1.14 date 2002.09.27.03.46.12; author mycroft; state Exp; branches; next 1.13; 1.13 date 2002.09.27.03.34.22; author mycroft; state Exp; branches; next 1.12; 1.12 date 2002.09.27.02.46.05; author mycroft; state Exp; branches; next 1.11; 1.11 date 2002.09.27.02.14.38; author mycroft; state Exp; branches; next 1.10; 1.10 date 2002.09.26.23.28.52; author mycroft; state Exp; branches; next 1.9; 1.9 date 2002.09.26.22.26.27; author mycroft; state Exp; branches; next 1.8; 1.8 date 2002.09.12.17.43.30; author mycroft; state Exp; branches; next 1.7; 1.7 date 2002.02.24.01.06.22; author matt; state Exp; branches 1.7.2.1; next 1.6; 1.6 date 2000.08.07.01.47.07; author matt; state Exp; branches; next 1.5; 1.5 date 2000.07.17.02.55.54; author matt; state Exp; branches; next 1.4; 1.4 date 2000.07.14.22.03.03; author matt; state Exp; branches; next 1.3; 1.3 date 2000.07.03.03.31.47; author matt; state Exp; branches; next 1.2; 1.2 date 2000.05.22.19.17.04; author matt; state Exp; branches; next 1.1; 1.1 date 99.08.21.19.26.19; author matt; state Exp; branches; next ; 1.24.28.1 date 2025.08.02.05.55.03; author perseant; state Exp; branches; next ; commitid 23j6GFaDws3O875G; 1.22.4.1 date 2014.08.20.13.49.28; author martin; state Exp; branches; next ; commitid LISysMutZJ4Xz6Nx; 1.16.54.1 date 2014.05.22.11.37.14; author yamt; state Exp; branches; next ; commitid VmckIax9CgOhKwBx; 1.16.60.1 date 2014.08.20.00.02.23; author tls; state Exp; branches; next ; commitid jTnpym9Qu0o4R1Nx; 1.7.2.1 date 2004.05.28.08.31.23; author tron; state Exp; branches; next ; desc @@ 1.25 log @ld.elf_so(1): Nix trailing whitespace. No functional change intended. @ text @/* $NetBSD: rtld_start.S,v 1.24 2014/08/17 16:57:37 matt Exp $ */ /* * Copyright 1996 Matt Thomas * Portions copyright 2002, 2003 Charles M. Hannum * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* R9 contains the address of PS_STRINGS and since its caller saved, * we can just use it. R6 has a backup copy of the stack pointer which * we can use as well. */ ENTRY(_rtld_start, 0) /* Allocate space on the stack for the cleanup and obj_main * entries that _rtld() will provide for us. */ clrl %fp subl2 $8,%sp movab _DYNAMIC,%r0 subl3 _GLOBAL_OFFSET_TABLE_,%r0,%r10 pushl %r10 /* relocbase */ pushl %r0 /* &_DYNAMIC */ calls $2,_rtld_relocate_nonplt_self pushl %r10 /* relocbase */ pushal 4(%sp) /* sp */ calls $2,_rtld /* entry = _rtld(sp, relocbase) */ movq (%sp)+,%r7 /* grab cleanup and obj_main into %r7/%r8 */ jmp 2(%r0) /* jump to entry point + 2 */ END(_rtld_start) /* * Lazy binding entry point, called via PLT via JMP into pltgot[1]. * SP+4: address to relocation offset * SP+0: obj entry points */ ALTENTRY(_rtld_bind_start) pushl %r1 /* need to preserve r1 */ movq -8(%fp),%r0 /* get addresses of plt.got & reloc index */ pushl (%r1) /* push relocation offset */ pushl %r0 /* push address of obj entry */ calls $2,_rtld_bind /* * This code checks to see if we got called via a call{s,g} $n,*pcrel32 * This is by far the most common case (a call indirectly via the PLT). */ subl3 $7,16(%fp),%r1 /* return address */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 20f /* no it isn't */ cmpb $0xff,2(%r1) /* and deferred 32-bit PC displacement? */ jneq 20f /* no it isn't */ /* * This makes sure the longword with the PLT's address has been updated * to point to the routine's address. If it hasn't, then returning * would put us in an infinite loop. Instead we punt and fake up a * callframe. */ movl 3(%r1),%r3 /* get displacement */ addl2 16(%fp),%r3 /* add ending location */ cmpl (%r3),%r0 /* does it contain the routine address? */ #ifdef DEBUG jneq 30f /* no it doesn't, die */ #else jneq 20f /* no it doesn't, go fake a new callframe */ #endif 11: movl %r1,16(%fp) /* backup to the calls/callg */ jbc $29,4(%fp),12f /* skip if this was a callg */ clrl (%ap) /* clear argument count */ 12: movl (%sp)+,%r1 /* restore r1 */ ret /* return and redo the call */ #if 1 20: /* * Since the calling standard says only r6-r11 should be saved, * that simplies things for us. That means we can use r0-r5 as * temporaries without worrying about preserving them. This means * can hold the current fixed callframe in r2-r5 as we build the * callframe without having to worry about overwriting the existing * callframe. */ extzv $0,$12,(%r0),%r1/* get routine's save mask */ bitw $0x3f,%r1 /* does the routine use r0-r5? */ jneq 30f /* yes, that sucks */ jbc $29,4(%fp),27f /* handle callg */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ insv %r1,$16,$12,%r2 /* update save mask */ movl (%sp)+,%fp /* use fp to keep saved r1 */ movl %ap,%sp /* reset stack to top of callframe */ 22: pushr %r1 /* push registers */ movq %r4,-(%sp) /* push callframe saved FP & PC */ movq %r2,-(%sp) /* push callframe status & saved AP */ pushl $0 /* push condition handler */ movl %fp,%r1 /* restore r1 */ movl %sp,%fp /* sp == fp now */ #if 1 jmp 2(%r0) /* jump past entry mask */ #else /* * More correct but IV/DV are never set so ignore doing this for now. */ movpsl -(%sp) /* push PSL */ clrb (%sp) /* clear user flags */ jbc $14,(%r0),24f /* IV need to be set? */ bisb2 $0x20,(%sp) /* yes, set it. */ 24: jbc $15,(%r0),25f /* DV need to be set? */ bisb2 $0x80,(%sp) /* yes, set it. */ 25: pushab 2(%r0) /* push address of first instruction */ rei /* and go to it (updating PSW) */ #endif /* * Count how many registers are being used for callg. */ 27: movl $0x32212110,%r3 /* bit counts */ extzv $6,$3,%r1,%r2 /* extract bits 6-8 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r4 /* extract count */ extzv $9,$3,%r1,%r2 /* extract bits 9-11 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r5 /* extract count */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ insv %r1,$16,$12,%r2 /* update save mask */ addl3 %r4,%r5,%r1 /* add counts and discard them */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ moval 20(%fp)[%r1],%sp/* pop callframe */ extzv $16,$12,%r2,%r1 /* get save mask back */ jbr 22b /* now build the new callframe */ 30: calls $0,_C_LABEL(_rtld_die) #else /* * Check to see if called via call? $n,w^off(reg) */ 20: addl2 $2,%r1 /* 16-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 30f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xc0,%r3 /* 16-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,b^off(reg) */ 30: incl %r1 /* 8-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 40f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xa0,%r3 /* 8-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,(reg) */ 40: incl %r1 /* no displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jeql 41f /* yes it is */ halt /* no, die die die */ 41: bicb3 $0x0f,2(%r1),%r2/* extract addressing mode */ bicb3 $0xf0,2(%r1),%r3/* extract register */ extzv $0,$12,6(%fp),%r4/* extract saved mask */ cmpb $0x60,%r2 /* register deferred? */ jeql 42f /* yes, deal with it */ cmpb $0x90,%r2 /* autoincrement deferred? */ jeql 70f /* yes, deal with it */ halt /* no, die die die */ 42: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 50f /* no, deal with it */ jbc %r3,%r4,43f /* is the register in the saved mask? */ /* * We saved r2-r11, so it's easy to replace the saved register with * the right value by indexing into saved register (offset by 8). */ movl %r0,(20-8)(%fp)[%r3] /* replace address in saved registers */ jbr 11b /* go back and redo call */ /* * Must have been called via r0 or r1 which are saved locally. * So move the routine address in the appropriate slot on the stack. */ 43: movl %r0,(%sp)[%r3] jbr 11b /* go back and redo call */ 50: jbs %r3,%r4,60f /* is the register in the saved mask? */ jbs %r3,$0x3f,43b /* is it r0-r5? */ /* * The register used for the call was not saved so we need to move * the new function address into it so the re-call will use the new * address. */ pushl %r0 /* save function address on the stack */ ashl %r5,$1,%r0 /* create a bitmask for the register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call */ 60: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 61: cmpl %r2,%r3 /* is the register to save? */ jneq 62f /* no, advance to next */ movl %r0,20(%fp)[%r5]/* yes, save return address in saved reg */ jbr 11b /* and return the call */ 62: jbc %r5,%r4,63f /* is this register saved? */ incl %r5 /* yes, account for it */ 63: incl %r2 /* increment register number */ jbr 61b /* and loop */ 70: cmpb %r3,$12 blss 71f halt 71: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 72f /* no, deal with it */ subl2 $4,(20-8)(%fp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 72: jbs %r3,%r4,80f jbs %r3,%3f,74f ashl %r5,$1,%r0 /* create a bitmask for the register */ pushr %r0 /* pop it off the stack. */ subl2 $4,(%sp) /* backup incremented register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call. 73: subl2 %4,(%sp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 80: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 81: cmpl %r2,%r3 /* is the register to save? */ jneq 82f /* no, advance to next */ subl $4,20(%fp)[%r5] /* yes, backup incremented register */ jbr 11b /* and return the call */ 82: jbc %r5,%r4,83f /* is this register saved? */ incl %r5 /* yes, account for it */ 83: incl %r2 /* increment register number */ jbr 81b /* and loop */ #endif END(_rtld_bind_start) @ 1.24 log @Add proper registers for register counts. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.23 2014/08/17 16:14:19 matt Exp $ */ d161 1 a161 1 30: @ 1.24.28.1 log @Sync with HEAD @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.25 2024/08/03 21:59:59 riastradh Exp $ */ d161 1 a161 1 30: @ 1.23 log @add a missing register prefix. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.22 2014/03/22 15:13:10 matt Exp $ */ d155 1 a155 1 addl3 %r3,%r4,%r1 /* add counts and discard them */ @ 1.22 log @Make sure r1 is preserved _rtld_bind_start. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.21 2014/03/21 14:03:30 matt Exp $ */ d155 1 a155 1 addl3 %r3,r4,%r1 /* add counts and discard them */ @ 1.22.4.1 log @Pullup the following to netbsd-7 (requested by matt in ticket #37): external/gpl3/gcc/dist/gcc/config/vax/builtins.md 1.4 external/gpl3/gcc/dist/gcc/config/vax/vax.c 1.10 Rework so that the ctzsi builtin is supported. lib/libc/compiler_rt/Makefile.inc 1.26 VAX does need __clzsi2 libexec/ld.elf_so/arch/vax/rtld_start.S 1.23 libexec/ld.elf_so/arch/vax/rtld_start.S 1.24 add a missing register prefix. Add proper registers for register counts. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.22 2014/03/22 15:13:10 matt Exp $ */ d155 1 a155 1 addl3 %r4,%r5,%r1 /* add counts and discard them */ @ 1.21 log @Simplify. If we got called via a calls $n, *pcrel32, instead of constructing a new stack frame, back up the PC by 7 and return back to the calls so it will be reinvoked. (This is by far the most common way it gets invoked). Otherwise rebuild a new callframe and jump to the routine. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.20 2014/03/19 21:52:00 joerg Exp $ */ d64 1 d99 2 a100 1 12: ret /* return and redo the call */ d119 1 d125 1 @ 1.20 log @Save actual start of function, not address of entry mask on the stack. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.19 2014/03/19 15:34:30 matt Exp $ */ d60 1 a61 4 * SP+4: address to relocation index * * Note: Some functions rely on there not being an additional call frame; * hence the `optimization' to avoid the callg opportunistically. a63 2 movab -64(%sp),%sp /* reserve some space */ pushr $0x3f /* save R0-R5 */ d65 1 a65 1 pushl (%r1) /* push relocation index */ d69 205 a273 84 addl3 $2,%r0,%r3 /* save routine address */ extzv $0,$12,(%r0),%r1 /* get entry mask */ extzv $0,$12,6(%fp),%r2 /* get saved mask */ cmpw %r1,%r2 /* compare them */ bneq 12f /* if they are different, rebuild */ movl %r3,-4(%fp) /* save routine address */ popr $0x3f /* pop registers */ movab 68(%sp),%sp /* restore sp */ rsb /* and jump to it */ /* * We need to rebuild the callframe. Save the current one in case * we might overwrite it. */ 12: movq 4(%fp),-(%sp) /* save PSW and AP */ movq 12(%fp),-(%sp) /* save FP and return address */ /* * Find out where this this call frame ends. */ movl %ap,%r0 /* get past callframe and registers */ bbs $29,4(%fp),22f /* calls is easy, it's where AP is */ /* * Callg not so much */ movab 20(%fp),%r0 /* past fixed callframe */ tstw %r2 /* no saved registers? */ beql 22f /* none, so we are done. */ movl $11,%r4 /* start with register 11 */ 20: bbc %r4,%r2,21f /* save this register? */ addl2 $4,%r0 /* yes, adjust for saved register */ 21: sobgeq %r4,20b /* try next register */ 22: /* * First "push" the caller saved registers (if there any that * need to saved.) */ tstw %r1 /* if there are no registers to save */ beql 1f /* just push the callframe */ cmpw %r1,$63 /* if there are no caller-saved registers */ blequ 5f /* skip them */ bbc $11,%r1,10f /* does it need to be saved? */ movl %r11,-(%r0) 10: bbc $10,%r1,9f /* does it need to be saved? */ movl %r10,-(%r0) 9: bbc $9,%r1,8f /* does it need to be saved? */ movl %r9,-(%r0) 8: bbc $8,%r1,7f /* does it need to be saved? */ movl %r8,-(%r0) 7: bbc $7,%r1,6f /* does it need to be saved? */ movl %r7,-(%r0) 6: bbc $6,%r1,5f /* does it need to be saved? */ movl %r6,-(%r0) 5: /* * r0-r5 are not normally preserved so we should be done. */ cmpw %r1,$63 bgtru 1f /* * For some reason, we have to preserve these. */ movab 16(%sp),%r2 bbc $5,%r1,4f /* does it need to be saved? */ movl 20(%r2),-(%r0) 4: bbc $4,%r1,3f /* does it need to be saved? */ movl 16(%r2),-(%r0) 3: bbc $3,%r1,2f /* does it need to be saved? */ movl 12(%r2),-(%r0) 2: bbc $2,%r1,1f /* does it need to be saved? */ movl 8(%r2),-(%r0) /* * Now we save the fixed part of the callframe. */ 1: clrl %r4 /* clear condition handler slot */ movq (%sp)+,-(%r0) /* move FP and PC into place */ movq (%sp)+,-(%r0) /* move PSW/save-mask/etc + AP into place */ movq %r3,-(%r0) /* move routine address + cond handle slot */ addl3 $4,%r0,%fp /* get start of new callframe */ insv %r1,$0,$12,6(%fp) /* insert new saved mask */ popr $0x3f /* restore R0-R5 (cond flags not modified) */ subl3 $4,%fp,%sp /* sp needs to be equal to fp */ rsb /* and jmp to the routine */ @ 1.19 log @Fix two bugs. (jump past entry mask, fix insv) @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.18 2014/03/19 02:39:22 matt Exp $ */ d79 1 a79 1 movl %r0,-4(%fp) /* save routine address */ @ 1.18 log @Once we know the bound routine, rebuilt a new callframe that can be unwound properly. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.17 2014/03/18 23:43:38 matt Exp $ */ d74 1 a74 1 movl %r0,%r3 /* save routine address */ d154 1 a154 1 insv $0,$12,%r1,6(%fp) /* insert new saved mask */ @ 1.17 log @Add .cfi ops so that one can unwind through this. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.16 2003/03/02 22:03:40 mycroft Exp $ */ d67 1 a67 16 .cfi_startproc .cfi_def_cfa 13, 60 .cfi_offset 16, -56 .cfi_offset 12, -52 .cfi_offset 13, -48 .cfi_offset 15, -44 .cfi_offset 2, -40 .cfi_offset 3, -36 .cfi_offset 4, -32 .cfi_offset 5, -28 .cfi_offset 6, -24 .cfi_offset 7, -20 .cfi_offset 8, -16 .cfi_offset 9, -12 .cfi_offset 10, -8 .cfi_offset 11, -4 d69 1 a69 1 movq 24(%sp),%r0 /* get addresses of plt.got & reloc index */ d73 82 a154 1 movl %r0,28(%sp) /* save return address onto stack */ d156 2 a157 4 addl2 $4,%sp callg (%ap),*(%sp)+ /* return value from _rtld_bind() == actual */ ret .cfi_endproc @ 1.16 log @Shorten rtld_start() slightly -- there's a base-relative _DYNAMIC pointer at the beginning of the GOT, so we don't need an extra one here. Also, remove a bogus comment -- we do in fact have to do fixups, because there are pointers in ld.elf_so's data segment that need to be relocated. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.15 2002/10/05 11:59:06 mycroft Exp $ */ d56 1 d59 3 a61 1 * Lazy binding entry point, called via PLT. d67 16 a88 1 bicw3 6(%fp),(%r0),%r0/* does the entry mask save any additional regs */ d90 1 a90 5 bneq 4f /* yes? do it the hard way */ addl2 $4,%sp /* no? skip past plt.got on stack */ addl2 $2,(%sp) /* skip past the mask */ rsb /* and jump to it */ 4: addl2 $4,%sp d93 2 @ 1.16.60.1 log @Rebase to HEAD as of a few days ago. @ text @d1 1 a1 1 /* $NetBSD$ */ a55 1 END(_rtld_start) d58 4 a61 3 * Lazy binding entry point, called via PLT via JMP into pltgot[1]. * SP+4: address to relocation offset * SP+0: obj entry points d64 3 a66 3 pushl %r1 /* need to preserve r1 */ movq -8(%fp),%r0 /* get addresses of plt.got & reloc index */ pushl (%r1) /* push relocation offset */ d69 10 a78 210 /* * This code checks to see if we got called via a call{s,g} $n,*pcrel32 * This is by far the most common case (a call indirectly via the PLT). */ subl3 $7,16(%fp),%r1 /* return address */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 20f /* no it isn't */ cmpb $0xff,2(%r1) /* and deferred 32-bit PC displacement? */ jneq 20f /* no it isn't */ /* * This makes sure the longword with the PLT's address has been updated * to point to the routine's address. If it hasn't, then returning * would put us in an infinite loop. Instead we punt and fake up a * callframe. */ movl 3(%r1),%r3 /* get displacement */ addl2 16(%fp),%r3 /* add ending location */ cmpl (%r3),%r0 /* does it contain the routine address? */ #ifdef DEBUG jneq 30f /* no it doesn't, die */ #else jneq 20f /* no it doesn't, go fake a new callframe */ #endif 11: movl %r1,16(%fp) /* backup to the calls/callg */ jbc $29,4(%fp),12f /* skip if this was a callg */ clrl (%ap) /* clear argument count */ 12: movl (%sp)+,%r1 /* restore r1 */ ret /* return and redo the call */ #if 1 20: /* * Since the calling standard says only r6-r11 should be saved, * that simplies things for us. That means we can use r0-r5 as * temporaries without worrying about preserving them. This means * can hold the current fixed callframe in r2-r5 as we build the * callframe without having to worry about overwriting the existing * callframe. */ extzv $0,$12,(%r0),%r1/* get routine's save mask */ bitw $0x3f,%r1 /* does the routine use r0-r5? */ jneq 30f /* yes, that sucks */ jbc $29,4(%fp),27f /* handle callg */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ insv %r1,$16,$12,%r2 /* update save mask */ movl (%sp)+,%fp /* use fp to keep saved r1 */ movl %ap,%sp /* reset stack to top of callframe */ 22: pushr %r1 /* push registers */ movq %r4,-(%sp) /* push callframe saved FP & PC */ movq %r2,-(%sp) /* push callframe status & saved AP */ pushl $0 /* push condition handler */ movl %fp,%r1 /* restore r1 */ movl %sp,%fp /* sp == fp now */ #if 1 jmp 2(%r0) /* jump past entry mask */ #else /* * More correct but IV/DV are never set so ignore doing this for now. */ movpsl -(%sp) /* push PSL */ clrb (%sp) /* clear user flags */ jbc $14,(%r0),24f /* IV need to be set? */ bisb2 $0x20,(%sp) /* yes, set it. */ 24: jbc $15,(%r0),25f /* DV need to be set? */ bisb2 $0x80,(%sp) /* yes, set it. */ 25: pushab 2(%r0) /* push address of first instruction */ rei /* and go to it (updating PSW) */ #endif /* * Count how many registers are being used for callg. */ 27: movl $0x32212110,%r3 /* bit counts */ extzv $6,$3,%r1,%r2 /* extract bits 6-8 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r4 /* extract count */ extzv $9,$3,%r1,%r2 /* extract bits 9-11 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r5 /* extract count */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ insv %r1,$16,$12,%r2 /* update save mask */ addl3 %r3,r4,%r1 /* add counts and discard them */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ moval 20(%fp)[%r1],%sp/* pop callframe */ extzv $16,$12,%r2,%r1 /* get save mask back */ jbr 22b /* now build the new callframe */ 30: calls $0,_C_LABEL(_rtld_die) #else /* * Check to see if called via call? $n,w^off(reg) */ 20: addl2 $2,%r1 /* 16-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 30f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xc0,%r3 /* 16-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,b^off(reg) */ 30: incl %r1 /* 8-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 40f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xa0,%r3 /* 8-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,(reg) */ 40: incl %r1 /* no displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jeql 41f /* yes it is */ halt /* no, die die die */ 41: bicb3 $0x0f,2(%r1),%r2/* extract addressing mode */ bicb3 $0xf0,2(%r1),%r3/* extract register */ extzv $0,$12,6(%fp),%r4/* extract saved mask */ cmpb $0x60,%r2 /* register deferred? */ jeql 42f /* yes, deal with it */ cmpb $0x90,%r2 /* autoincrement deferred? */ jeql 70f /* yes, deal with it */ halt /* no, die die die */ 42: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 50f /* no, deal with it */ jbc %r3,%r4,43f /* is the register in the saved mask? */ /* * We saved r2-r11, so it's easy to replace the saved register with * the right value by indexing into saved register (offset by 8). */ movl %r0,(20-8)(%fp)[%r3] /* replace address in saved registers */ jbr 11b /* go back and redo call */ /* * Must have been called via r0 or r1 which are saved locally. * So move the routine address in the appropriate slot on the stack. */ 43: movl %r0,(%sp)[%r3] jbr 11b /* go back and redo call */ 50: jbs %r3,%r4,60f /* is the register in the saved mask? */ jbs %r3,$0x3f,43b /* is it r0-r5? */ /* * The register used for the call was not saved so we need to move * the new function address into it so the re-call will use the new * address. */ pushl %r0 /* save function address on the stack */ ashl %r5,$1,%r0 /* create a bitmask for the register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call */ 60: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 61: cmpl %r2,%r3 /* is the register to save? */ jneq 62f /* no, advance to next */ movl %r0,20(%fp)[%r5]/* yes, save return address in saved reg */ jbr 11b /* and return the call */ 62: jbc %r5,%r4,63f /* is this register saved? */ incl %r5 /* yes, account for it */ 63: incl %r2 /* increment register number */ jbr 61b /* and loop */ 70: cmpb %r3,$12 blss 71f halt 71: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 72f /* no, deal with it */ subl2 $4,(20-8)(%fp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 72: jbs %r3,%r4,80f jbs %r3,%3f,74f ashl %r5,$1,%r0 /* create a bitmask for the register */ pushr %r0 /* pop it off the stack. */ subl2 $4,(%sp) /* backup incremented register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call. 73: subl2 %4,(%sp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 80: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 81: cmpl %r2,%r3 /* is the register to save? */ jneq 82f /* no, advance to next */ subl $4,20(%fp)[%r5] /* yes, backup incremented register */ jbr 11b /* and return the call */ 82: jbc %r5,%r4,83f /* is this register saved? */ incl %r5 /* yes, account for it */ 83: incl %r2 /* increment register number */ jbr 81b /* and loop */ #endif END(_rtld_bind_start) @ 1.16.54.1 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.16 2003/03/02 22:03:40 mycroft Exp $ */ a55 1 END(_rtld_start) d58 4 a61 3 * Lazy binding entry point, called via PLT via JMP into pltgot[1]. * SP+4: address to relocation offset * SP+0: obj entry points d64 3 a66 3 pushl %r1 /* need to preserve r1 */ movq -8(%fp),%r0 /* get addresses of plt.got & reloc index */ pushl (%r1) /* push relocation offset */ d69 10 a78 210 /* * This code checks to see if we got called via a call{s,g} $n,*pcrel32 * This is by far the most common case (a call indirectly via the PLT). */ subl3 $7,16(%fp),%r1 /* return address */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 20f /* no it isn't */ cmpb $0xff,2(%r1) /* and deferred 32-bit PC displacement? */ jneq 20f /* no it isn't */ /* * This makes sure the longword with the PLT's address has been updated * to point to the routine's address. If it hasn't, then returning * would put us in an infinite loop. Instead we punt and fake up a * callframe. */ movl 3(%r1),%r3 /* get displacement */ addl2 16(%fp),%r3 /* add ending location */ cmpl (%r3),%r0 /* does it contain the routine address? */ #ifdef DEBUG jneq 30f /* no it doesn't, die */ #else jneq 20f /* no it doesn't, go fake a new callframe */ #endif 11: movl %r1,16(%fp) /* backup to the calls/callg */ jbc $29,4(%fp),12f /* skip if this was a callg */ clrl (%ap) /* clear argument count */ 12: movl (%sp)+,%r1 /* restore r1 */ ret /* return and redo the call */ #if 1 20: /* * Since the calling standard says only r6-r11 should be saved, * that simplies things for us. That means we can use r0-r5 as * temporaries without worrying about preserving them. This means * can hold the current fixed callframe in r2-r5 as we build the * callframe without having to worry about overwriting the existing * callframe. */ extzv $0,$12,(%r0),%r1/* get routine's save mask */ bitw $0x3f,%r1 /* does the routine use r0-r5? */ jneq 30f /* yes, that sucks */ jbc $29,4(%fp),27f /* handle callg */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ insv %r1,$16,$12,%r2 /* update save mask */ movl (%sp)+,%fp /* use fp to keep saved r1 */ movl %ap,%sp /* reset stack to top of callframe */ 22: pushr %r1 /* push registers */ movq %r4,-(%sp) /* push callframe saved FP & PC */ movq %r2,-(%sp) /* push callframe status & saved AP */ pushl $0 /* push condition handler */ movl %fp,%r1 /* restore r1 */ movl %sp,%fp /* sp == fp now */ #if 1 jmp 2(%r0) /* jump past entry mask */ #else /* * More correct but IV/DV are never set so ignore doing this for now. */ movpsl -(%sp) /* push PSL */ clrb (%sp) /* clear user flags */ jbc $14,(%r0),24f /* IV need to be set? */ bisb2 $0x20,(%sp) /* yes, set it. */ 24: jbc $15,(%r0),25f /* DV need to be set? */ bisb2 $0x80,(%sp) /* yes, set it. */ 25: pushab 2(%r0) /* push address of first instruction */ rei /* and go to it (updating PSW) */ #endif /* * Count how many registers are being used for callg. */ 27: movl $0x32212110,%r3 /* bit counts */ extzv $6,$3,%r1,%r2 /* extract bits 6-8 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r4 /* extract count */ extzv $9,$3,%r1,%r2 /* extract bits 9-11 */ ashl $2,%r2,%r2 /* shift by 2 */ extzv %r2,$4,%r3,%r5 /* extract count */ movq 4(%fp),%r2 /* fetch callframe status & saved AP */ insv %r1,$16,$12,%r2 /* update save mask */ addl3 %r3,r4,%r1 /* add counts and discard them */ movq 12(%fp),%r4 /* fetch callframe saved FP & PC */ moval 20(%fp)[%r1],%sp/* pop callframe */ extzv $16,$12,%r2,%r1 /* get save mask back */ jbr 22b /* now build the new callframe */ 30: calls $0,_C_LABEL(_rtld_die) #else /* * Check to see if called via call? $n,w^off(reg) */ 20: addl2 $2,%r1 /* 16-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 30f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xc0,%r3 /* 16-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,b^off(reg) */ 30: incl %r1 /* 8-bit displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jneq 40f /* no it isn't */ bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */ cmpb $0xa0,%r3 /* 8-bit displacement? */ jeql 11b /* yes, redo the call */ halt /* * Check to see if called via call? $n,(reg) */ 40: incl %r1 /* no displacement */ bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */ cmpb $0xfa,%r2 /* is it calls/callg */ jeql 41f /* yes it is */ halt /* no, die die die */ 41: bicb3 $0x0f,2(%r1),%r2/* extract addressing mode */ bicb3 $0xf0,2(%r1),%r3/* extract register */ extzv $0,$12,6(%fp),%r4/* extract saved mask */ cmpb $0x60,%r2 /* register deferred? */ jeql 42f /* yes, deal with it */ cmpb $0x90,%r2 /* autoincrement deferred? */ jeql 70f /* yes, deal with it */ halt /* no, die die die */ 42: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 50f /* no, deal with it */ jbc %r3,%r4,43f /* is the register in the saved mask? */ /* * We saved r2-r11, so it's easy to replace the saved register with * the right value by indexing into saved register (offset by 8). */ movl %r0,(20-8)(%fp)[%r3] /* replace address in saved registers */ jbr 11b /* go back and redo call */ /* * Must have been called via r0 or r1 which are saved locally. * So move the routine address in the appropriate slot on the stack. */ 43: movl %r0,(%sp)[%r3] jbr 11b /* go back and redo call */ 50: jbs %r3,%r4,60f /* is the register in the saved mask? */ jbs %r3,$0x3f,43b /* is it r0-r5? */ /* * The register used for the call was not saved so we need to move * the new function address into it so the re-call will use the new * address. */ pushl %r0 /* save function address on the stack */ ashl %r5,$1,%r0 /* create a bitmask for the register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call */ 60: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 61: cmpl %r2,%r3 /* is the register to save? */ jneq 62f /* no, advance to next */ movl %r0,20(%fp)[%r5]/* yes, save return address in saved reg */ jbr 11b /* and return the call */ 62: jbc %r5,%r4,63f /* is this register saved? */ incl %r5 /* yes, account for it */ 63: incl %r2 /* increment register number */ jbr 61b /* and loop */ 70: cmpb %r3,$12 blss 71f halt 71: cmpw %r4,$0xffc /* did we save r2-r11? */ jneq 72f /* no, deal with it */ subl2 $4,(20-8)(%fp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 72: jbs %r3,%r4,80f jbs %r3,%3f,74f ashl %r5,$1,%r0 /* create a bitmask for the register */ pushr %r0 /* pop it off the stack. */ subl2 $4,(%sp) /* backup incremented register */ popr %r0 /* pop it off the stack. */ jbr 11b /* and redo the call. 73: subl2 %4,(%sp)[%r3] /* backup incremented register */ jbr 11b /* and redo the call. 80: clrl %r2 /* starting offset into saved registers */ clrl %r5 /* start with register 0 */ 81: cmpl %r2,%r3 /* is the register to save? */ jneq 82f /* no, advance to next */ subl $4,20(%fp)[%r5] /* yes, backup incremented register */ jbr 11b /* and return the call */ 82: jbc %r5,%r4,83f /* is this register saved? */ incl %r5 /* yes, account for it */ 83: incl %r2 /* increment register number */ jbr 81b /* and loop */ #endif END(_rtld_bind_start) @ 1.15 log @Minor cleanup. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.14 2002/09/27 03:46:12 mycroft Exp $ */ d5 1 a5 1 * Portions copyright 2002 Charles M. Hannum a32 3 .data .L1: .long _DYNAMIC d35 1 a35 2 * we can use as well. Since the VAX has perfectly PIC code, we don't * need to relocate anything upon startup. d45 1 a45 1 subl3 .L1,%r0,%r10 @ 1.14 log @We don't need to save r7, either... @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.12 2002/09/27 02:46:05 mycroft Exp $ */ d5 1 a5 1 * Portions copyright 2002 Charles M. Hannum. @ 1.13 log @Put back the short-circuiting code -- Matt claims there are functions that rely on it. OTOH, don't bother saving r6 a second time. @ text @d68 2 a69 2 pushr $0xbf /* save R0-R5,R7 */ movq 28(%sp),%r0 /* get addresses of plt.got & reloc index */ d73 1 a73 1 movl %r0,32(%sp) /* save return address onto stack */ d75 1 a75 1 popr $0xbf /* restore R0-R5,R7 (cond flags not modified) */ @ 1.12 log @1) There is no reason to flush the I$ here, given that we do not modify any instructions. Function calls use GOT indirection, and we only patch the GOT. 2) The mask-comparison optimization always fails, because the saved mask always has 0x2000 set, and the PLT stub mask never does. So, remove it. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.9 2002/09/26 22:26:27 mycroft Exp $ */ d63 3 d68 2 a69 2 pushr $0xff /* save R0-R7 */ movq 32(%sp),%r0 /* get addresses of plt.got & reloc index */ d73 8 a80 3 movl %r0,36(%sp) /* save return address onto stack */ popr $0xff /* restore R0-R7 (cond flags not modified) */ addl2 $4,%sp @ 1.11 log @Save one more instruction. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.10 2002/09/26 23:28:52 mycroft Exp $ */ d70 1 a70 5 movpsl -(%sp) /* flush the instruction cache */ pushab 1f /* by issuing an */ rei /* rei. */ 1: movl %r0,36(%sp) /* save return address onto stack */ 2: bicw3 6(%fp),(%r0),%r0 /* does the entry mask save any additional regs */ d72 1 a72 5 bneq 4f /* yes? do it the hard way */ 3: addl2 $4,%sp /* no? skip past plt.got on stack */ addl2 $2,(%sp) /* skip past the mask */ rsb /* and jump to it */ 4: addl2 $4,%sp @ 1.10 log @Save relocbase in %r10, not %r1. Also, save one instruction. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.9 2002/09/26 22:26:27 mycroft Exp $ */ a53 1 movl %sp,%r0 d55 1 a55 1 pushl %r0 /* sp */ @ 1.9 log @Implement a self-relocate function for the VAX. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.8 2002/09/12 17:43:30 mycroft Exp $ */ d34 1 a34 1 .L1: .long _GLOBAL_OFFSET_TABLE_ d49 2 a50 3 movab _GLOBAL_OFFSET_TABLE_,%r1 subl2 .L1,%r1 pushl %r1 /* relocbase */ d55 1 a55 1 pushl %r1 /* relocbase */ @ 1.8 log @Figure out the relocation offset and pass it to _rtld(). @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.7 2002/02/24 01:06:22 matt Exp $ */ d5 1 d48 10 a57 5 movab _GLOBAL_OFFSET_TABLE_,%r0 subl2 .L1,%r0 movl %sp,%r1 pushl %r0 /* relocbase */ pushl %r1 /* sp */ @ 1.7 log @Change to use a register prefix. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.6 2000/08/07 01:47:07 matt Exp $ */ d32 3 a40 1 a45 1 pushl %sp d47 6 a52 1 calls $1,_rtld @ 1.7.2.1 log @Apply patch (request by skrll in ticket #1702): Bring "ld.elf_so" (mostly) in sync with NetBSD-current: - MI and MD (e.g. under NetBSD-alpha) performance improvements - RTLD_SELF, RTLD_NEXT, RTLD_DEFAULT support - much better structured code - closes PR bin/25464 @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.16 2003/03/02 22:03:40 mycroft Exp $ */ a4 1 * Portions copyright 2002, 2003 Charles M. Hannum d34 2 a35 1 * we can use as well. d38 1 d44 1 d46 1 a46 9 movab _DYNAMIC,%r0 subl3 _GLOBAL_OFFSET_TABLE_,%r0,%r10 pushl %r10 /* relocbase */ pushl %r0 /* &_DYNAMIC */ calls $2,_rtld_relocate_nonplt_self pushl %r10 /* relocbase */ pushal 4(%sp) /* sp */ calls $2,_rtld /* entry = _rtld(sp, relocbase) */ a52 3 * * Note: Some functions rely on there not being an additional call frame; * hence the `optimization' to avoid the callg opportunistically. d55 2 a56 2 pushr $0x3f /* save R0-R5 */ movq 24(%sp),%r0 /* get addresses of plt.got & reloc index */ d60 6 a65 3 movl %r0,28(%sp) /* save return address onto stack */ bicw3 6(%fp),(%r0),%r0/* does the entry mask save any additional regs */ popr $0x3f /* restore R0-R5 (cond flags not modified) */ d67 1 a67 1 addl2 $4,%sp /* no? skip past plt.got on stack */ @ 1.6 log @Simplify some stuff. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.5 2000/07/17 02:55:54 matt Exp $ */ d42 3 a44 3 clrl fp subl2 $8,sp pushl sp d48 2 a49 2 movq (sp)+,r7 /* grab cleanup and obj_main into r7/r8 */ jmp 2(r0) /* jump to entry point + 2 */ d56 3 a58 3 movq 32(sp),r0 /* get addresses of plt.got & reloc index */ pushl (r1) /* push relocation index */ pushl r0 /* push address of obj entry */ d60 1 a60 1 movpsl -(sp) /* flush the instruction cache */ d63 2 a64 2 1: movl r0,36(sp) /* save return address onto stack */ 2: bicw3 6(fp),(r0),r0 /* does the entry mask save any additional regs */ d67 2 a68 2 3: addl2 $4,sp /* no? skip past plt.got on stack */ addl2 $2,(sp) /* skip past the mask */ d70 2 a71 2 4: addl2 $4,sp callg (ap),*(sp)+ /* return value from _rtld_bind() == actual */ @ 1.5 log @More VAX ELF changes. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.4 2000/07/14 22:03:03 matt Exp $ */ d58 1 a58 1 pushl 12(r0) /* push address of obj entry */ @ 1.4 log @No need for RELOCATE_SELF since the VAX does real PIC. Rewrite the bind routine to deal with JMP .vs. CALLx differences. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.3 2000/07/03 03:31:47 matt Exp $ */ a56 3 divl3 $12,(r1),r2 /* get reloc index */ moval 16(r0)[r2],r6 /* get location in .plt.got */ bicl3 $0xfffffffc,(r6),r7 /* get low 2 bits (addend) */ a63 5 tstl r7 /* was this a call (0) or jmp (!0)? */ beql 2f /* branch if call */ addl2 r7,(r6) /* preserve addend */ popr $0xff /* restore R0-R7 */ jbr 3f /* jmp directly since this was a jsb/jmp */ @ 1.3 log @Update to current @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.2 2000/05/22 19:17:04 matt Exp $ */ d42 2 a43 1 subl2 $8, sp a44 1 calls $1, _rtld d46 3 a48 1 movq (sp)+, r7 /* grab cleanup and obj_main into r7/r8 */ d55 5 a59 2 pushr $0x3f /* save R0-R5 */ movq 24(sp),r0 /* get addresses of plt.got & reloc index */ d61 1 a61 1 pushl r0 /* push address of obj entry */ d66 10 a75 5 1: movl r0, 28(sp) /* save return address onto stack */ bicw3 6(fp),(r0),r0 /* does the entry mask save any additional regs */ popr $0x3f /* restore r0 to r5 (cond flags aren't modified) */ bneq 2f /* yes? do it the hard way */ addl2 $4,sp /* no? skip past plt.got on stack */ d78 2 a79 1 2: callg (ap),*(sp)+ /* return value from _rtld_bind() == actual */ @ 1.2 log @minor fix now that i've defined the plt0 entry. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.1 1999/08/21 19:26:19 matt Exp $ */ d37 1 a37 2 ENTRY(_rtld_start) .word 0x0101 /* nops to be safe */ d52 1 a52 1 ENTRY(_rtld_bind_start): d65 1 a65 1 addl4 $4,sp /* no? skip past plt.got on stack */ @ 1.1 log @Initial VAX ELF32 support (mostly untested). It's checked primarily for testing and archival for now. I don't expect anyone to work with it since the binutils and gas changes are still pending. But you got to crawl before you walk. @ text @d1 1 a1 1 /* $NetBSD: rtld_start.S,v 1.3 1999/04/19 00:05:00 thorpej Exp $ */ d57 1 a57 1 pushl 4(r0) /* push address of obj entry */ @