From owner-freebsd-current Wed Feb 23 4:30: 2 2000 Delivered-To: freebsd-current@freebsd.org Received: from gidora.zeta.org.au (gidora.zeta.org.au [203.26.10.25]) by hub.freebsd.org (Postfix) with SMTP id 6A31D37B780 for ; Wed, 23 Feb 2000 04:29:52 -0800 (PST) (envelope-from bde@zeta.org.au) Received: (qmail 18529 invoked from network); 23 Feb 2000 12:29:49 -0000 Received: from bde.zeta.org.au (203.2.228.102) by gidora.zeta.org.au with SMTP; 23 Feb 2000 12:29:49 -0000 Date: Wed, 23 Feb 2000 23:29:44 +1100 (EST) From: Bruce Evans X-Sender: bde@alphplex.bde.org To: Martin Cracauer Cc: jdp@FreeBSD.ORG, jkh@FreeBSD.ORG, current@FreeBSD.ORG, dillon@apollo.backplane.com, obrien@FreeBSD.ORG Subject: Re: extern variables in shared libraries broken (ld.so or mmap bug) In-Reply-To: <20000223100036.A4872@cons.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, 23 Feb 2000, Martin Cracauer wrote: > cc -fpic -DPIC -O -pipe -DLIBC_RCS -DSYSLIBC_RCS -I/usr/src/lib/libc/include -D__DBINTERFACE_PRIVATE -DINET6 -DPOSIX_MISTAKE -I/usr/src/lib/libc/../libc/locale -DBROKEN_DES -DYP -I/usr/obj/usr/src/i386/usr/include -c /usr/src/lib/libc/../libc/stdtime/localtime.c -o localtime.So > {standard input}: Assembler messages: > {standard input}:87: Warning: warning: unrecognized characters > `@GOTOFF' in expression > {standard input}:114: Warning: warning: unrecognized characters > `@GOTOFF' in expression > I'm not that familar with gas syntax, but it seems to be that this is > a syntax error generated by the new gcc, that @GOTOFF must be passed > one argument. The syntax seems reasonable, but our version of gas doesn't support it, and it is the result of a pessimisation. I tweaked the source code to avoid the bad code: diff -c2 localtime.c~ localtime.c *** localtime.c~ Fri Jan 28 17:29:18 2000 --- localtime.c Wed Feb 23 22:51:34 2000 *************** *** 220,224 **** settzname P((void)) { ! register struct state * const sp = lclptr; register int i; --- 220,224 ---- settzname P((void)) { ! register struct state * sp = lclptr; register int i; This seems to fix some of your prooblems. It works as follows: when sp is declared as const, gcc decides not to keep in a register in the default !ALL_STATE case (lclptr is &lclmem in this case), since it can "easily" be recovered by computing the address constant &lclmem. However, computing the constant turns out to be not so easy in the -fpic case -- it takes an extra 8 instructions, including a pessimization which gives the bug. (The natural and efficient way to reload lclptr (plus an offset) is: leal offset+lclmem@GOTOFF(%ebx),%reg but for some reason this sometimes gets pessimized to essentially: movl %ebx,%reg addl offset+lclmem@GOTOFF,%reg The last instruction is a syntax error with the current gas.) Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message